In AngularJS, how to force the re-validation of a field in a form when another value in the same form is changed?

All we need is an easy explanation of the problem, so here it is.

I have a form with few fields, however a select and an input field are coupled: the validation on the input depends on which value the user chooses in the select field.

I’ll try to clarify with an example. Let’s say that the select contains names of planets:

<select id="planet" class="form-control" name="planet" ng-model="planet" ng-options="c.val as c.label for c in planets"></select>

in the input I apply custom validation via a custom directive named “input-validation”:

<input id="city" input-validation iv-allow-if="planet==='earth'" class="form-control" name="city" ng-model="city" required>

where this is the directive:

.directive('inputValidation', [function() {
  return {
    require: 'ngModel',
    restrict: 'A',
    scope: {
      ivAllowIf: '='
    },
    link: function(scope, elm, attrs, ctrl) {
      ctrl.$parsers.unshift(function(viewValue) {

        //input is allowed if the attribute is not present or the expression evaluates to true
        var inputAllowed = attrs.ivAllowIf === undefined || scope.$parent.$eval(attrs.ivAllowIf);

        if (inputAllowed) {
          ctrl.$setValidity('iv', true);
          return viewValue;
        } else {
          ctrl.$setValidity('iv', false);
          return undefined;
        }

      });
    }
  };
}]) 

The full example can be examined in Plnkr: http://plnkr.co/edit/t2xMPy1ehVFA5KNEDfrf?p=preview

Whenever the select is modified, I need the input to be verified again. This is not happening in my code. What am I doing wrong?

How to solve :

I know you bored from this bug, So we are here to help you! Take a deep breath and look at the explanation of your problem. We have many solutions to this problem, But we recommend you to use the first method because it is tested & true method that will 100% work for you.

Method 1

I have done the same thing for validation of start-date on change of end-date. In the directive of start-date add watch for change of end-date and then call ngModel.$validate() in case end-date new value is defined.

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

The important part to take is call to ngModel.$validate() inside the directive.

Note
you should use $validators for custom validations above to work. read here, $parsers is the old way – from angularjs 1.3 use $validators

FIXED PLUNKER LINK

Note: Use and implement method 1 because this method fully tested our system.
Thank you 🙂

All methods was sourced from stackoverflow.com or stackexchange.com, is licensed under cc by-sa 2.5, cc by-sa 3.0 and cc by-sa 4.0

Leave a Reply