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