简体   繁体   中英

Use $validators on blur/focus events

Now, in my validation directive I set validation state 'manually', like this:

$element.on('focus', function() {
    $scope.$apply(function() {
       ngModelCtrl.$setValidity('length', true);
    });
 });

 $element.on('blur', function() {
    $scope.$apply(function() {
        if (ngModelCtrl.$modelValue && ngModelCtrl.$modelValue.length === +$attrs.maxlength) {
            ngModelCtrl.$setValidity('length', true);
        }      
        else if (ngModelCtrl.$modelValue.length < +$attrs.maxlength && ngModelCtrl.$modelValue.length > 0) {
            ngModelCtrl.$setValidity('length', false);
        }
     }
 });

But I want to set validation states with $validators with saving validation behaviour (on blur/focus events).

I can't use ng-model-options with updateOn: 'blur' .

Is other options to do this?

So to use a custom validator you will need to structure your directive a little differently. The major difference is you need to require ngModel .

Directive

return {
     require: 'ngModel',
     link: function(scope, element, attrs, ngModel) {
        // Run validator for maxLenth
        ngModel.$validators.customMaxLength = function(value) { 
          var status = false;
            if(value.length <= attrs.maxLengthValidator) {
              console.log(attrs.maxLengthValidator);
            status = true;
          }
              return status;
        };
    }
  }

Something important to note. If you are using an attribute to do your validate against and the value can change you need to watch the value and run your validator function against in manually. Because the model does not change the validator would not fire automatically.

Add the following to the directive

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

If you validator returns false you form will automatically have $valid set to false

HTML

In the example below I use angular-messages to display the valid output. This is an optional module that needs included.

<form name="myForm">
    <div class="form-group" ng-class="{'has-error':myForm.testField.$invalid}">
      <label class="control-label" for="testInput">Test Field</label>
      <input class="form-control" type="text" name="testField"  
        max-length-validator="3" required ng-model="testField"/>
    </div>
</form>

    <div ng-messages ng-messages-multiple class="bg-danger" for="myForm.testField.$error">
                <div ng-message when="required">Please enter value</div>
                <div ng-message when="customMaxLength">To Long</div>
    </div>

Custom Validator Example


In regards to your question about firing the validator on blur

You don't really want to update the ngModel if the model value is invalid.

What I would recommend is using styles and a focus attribute with the field to toggle the display based on the focus of the field.

Add something like the following to your input field

ng-focus="myForm.testField.focus=true" ng-blur="myForm.testField.focus=false"

Then use checks with ng-class , ng-show or ng-hide to update your display.

This has been added to the plnkr

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM