0

В настоящее время я работаю над угловым бутстрапом ui datepicker, поэтому я могу установить максимальную дату и подтвердить это (только когда пользователь установил дату, нажав календарь), но когда пользователь пишет дату вручную эти проверки бесполезны, я сделал директиву для этого, но только проверяю и устанавливаю ошибку один раз, вот моя разметка

<div class="form-group clearfix"> 
    <div class="col-md-3 m-t-b-20"> 
    <label>Date validation</label> 
    <p class="input-group col-md-12"> 

     <input id="validationDate" 
      type="text" 
      name="validationDate" 
      class="form-control" 
      uib-datepicker-popup="{{ Ctrl.format }}" 
      data-ng-model="Ctrl.formObj.validationDate" 
      is-open="Ctrl.validationDate.opened" 
      datepicker-options="Ctrl.dateOptions" 
      ng-required="true" 
      close-text="Close" 
      placeholder="Fecha de radicacion" 
      ng-click="Ctrl.openDatePicker('validationDate')" 
      required 
      date-validate/> 

     <span class="input-group-btn"> 
     <button type="button" 
       class="btn btn-default" 
       ng-click="Ctrl.openDatePicker('validationDate')" 
       data-ng-disabled="Ctrl.blockFields"> 
      <i class="glyphicon glyphicon-calendar"></i> 
     </button> 
     </span> 

    </p> 

    <!-- THE ERROR TO SHOW --> 
    <p data-ng-show="stepOne.validationDate.$error.validbound" 
     class="text-red"> 
     the selected date exeeds the max and min date boundaries 
    </p> 
    </div> 

и это моя директива

var dateValidate = function() { 
    return { 
     require: 'ngModel', 
     link: function (scope, elem, attr, ngModel) { 

     elem.bind('keyup', function(value) { 

      var atrvls = scope.$eval(attr.datepickerOptions), 
       maxDate = moment(atrvls.maxDate, 'DD/MM/YYYY'), 
       minDate = moment(atrvls.minDate, 'DD/MM/YYYY'), 
       cDate = moment(elem.val(), 'DD/MM/YYYY', true); 

      ngModel.$setValidity('validbound', true); 

      if (!cDate.isValid()) { 
       return false; 
      } 

      if (!cDate.isBetween(minDate, maxDate)) { 
       ngModel.$setValidity('validbound', false); 
      } 

     }); 

    } 
}; 

};

я хотел бы знать, почему проверка производится только в первый раз, и tafter, что директива не делает ничего

ответ

0

Здесь есть пара вещей.

Во-первых, сроки, указанные в Минутное isBetween() являются исключительными, в то время как datePicker «s minDate и maxDate включают даты. Так что вы хотите передать дополнительные параметры для включения в эти мин и макс даты в диапазоне:

cDate.isBetween(minDate, maxDate, null, '[]') 

Во-вторых, если вы ищете для немедленной обратной связи для того, является ли дата в пределах диапазона, то вам необходимо обернуть $setValidity внутри функции scope.$apply.

Не глядя на javascript для всплывающего окна Datepicker, я не могу точно сказать, зачем это нужно, но из экспериментов я вижу, что он применяется только к атрибуту ng-invalid-validbound, когда всплывающее окно закрывается (тогда как ng-valid-validbound применяется, как только для validity установлено значение true). Я предполагаю, что это так для производительности, поскольку вы не можете выбрать дату вне диапазона, используя всплывающее окно, в любом случае вы можете перейти только в другую сторону - от недопустимой даты до выбора допустимой даты с помощью всплывающего окна.

Это более или менее, как бы я это сделать:

var dateValidate = function() { 
    return { 
    require: 'ngModel', 
    link: function(scope, elem, attr, ngModel) { 
     elem.bind('keyup', function(value) { 

     var atrvls = scope.$eval(attr.datepickerOptions), 
      maxDate = moment(atrvls.maxDate, 'DD/MM/YYYY'), 
      minDate = moment(atrvls.minDate, 'DD/MM/YYYY'), 
      cDate = moment(elem.val(), 'DD/MM/YYYY', true); 

     if (!cDate.isValid()) { 
      scope.$apply(ngModel.$setValidity('validbound', null)); 
      return false; 
     } 

     if (!cDate.isBetween(minDate, maxDate, null, '[]')) { 
      scope.$apply(ngModel.$setValidity('validbound', false)); 
     } else { 
      scope.$apply(ngModel.$setValidity('validbound', true)); 
     } 

     }); 
    } 
    }; 
}; 

Вот plunker: http://plnkr.co/edit/toXpEWNa99o7Gfs69KfZ?p=preview

+0

nop, ну ... да ... но я забыл упомянуть, что сделано с угловым 1.6.1, я меняю его на plnker и не работал, когда вы вводите дату вручную – flaalf

+0

Я не конечно, что вы имеете в виду? Я обновил плунжер до 1.6.1, и для меня ввод даты «15/02/2017» отображается зеленым (в диапазоне), а ввод «25/02/2017» показывает красный (вне диапазона). Я использую Firefox, хотя я бы не ожидал, что он будет зависимым от браузера –

+0

, используя firefox, если я наберу «12/12/2018», вход станет красным, если я удалю последний символ, он станет нормальным, вот и ожидаемый поведение, которое я ищу, но если после этого я снова набираю «12/12/2016» (в диапазоне), вход становится красным. – flaalf

0

В функции связи - создать функцию Validate с пользовательской проверкой, и вы можете добавить $ смотреть на ngModel. $ viewValue

scope.$watch(function() { 
      return ngModel.$viewValue; 
     }, validate); 

Вместо 'KeyUp' я думаю 'размытости' было бы лучше.

+0

нормально, тот вариант, но я все еще не получаю, почему проверка теряет после первая проверка – flaalf

Смежные вопросы