0

我目前工作的一个角度引导UI日期选择器弹出验证,事情是,我可以设置一个最大最小日期和验证(仅当用户设定的日期点击日历),但是当用户通过手写日期的确认是没有用的,我做了一个指令,但只验证,并设置错误一次,这是我的标记

<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

这里有几件事。

首先,Moment的isBetween()中给出的日期是排他性的,而datePickerminDatemaxDate是包含日期。所以你要传递额外的参数,包括这些最小和最大范围内的日期:

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

其次,如果你正在寻找即时反馈的日期是否在该范围内,那么你就需要在scope.$apply函数内包装$setValidity

没有看日期选择器弹出窗口的JavaScript我不能确切地说明为什么需要,但从实验中我可以看到,它只适用于ng-invalid-validbound属性时弹出关闭(而ng-valid-validbound是应用尽快有效性设置为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,我改变了它的爬虫,并没有工作,当你用手输入日期 – flaalf

+0

我不是确定你的意思?我已将更新为1.6.1,对于我输入日期“2017年2月15日”显示为绿色(范围内),输入“2017年2月25日”显示为红色(超出范围)。我使用Firefox,但我不希望它是依赖于浏览器的使用Firefox的 –

+0

也,如果我输入“12/12/2018”输入变成红色,如果我删除最后一个字符它变成正常,那是预期的我要搜索的行为,但如果在此之后我再次输入“12/12/2016”(范围内)输入将变为红色 – flaalf

0

在链接功能 - 创建一个验证功能与您的自定义的验证,你可以添加$观看ngModel $ viewValue

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

而不是'Keyup',我认为'模糊'会更好。

+0

OK,这就是一种选择,但我仍然没有得到为什么后确认丢失第一次验证 – flaalf