Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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?

like image 407
Giordano Avatar asked Aug 16 '15 16:08

Giordano


1 Answers

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

like image 83
harishr Avatar answered Oct 07 '22 02:10

harishr