implementing a directive to exclude a hidden input element from validation ($addControl issue)

angularjs, forms, validation

Solution

If the control is removed angular updates the validity (from the sources):

  form.$removeControl = function(control) {
    if (control.$name && form[control.$name] === control) {
      delete form[control.$name];
    }
    forEach(errors, function(queue, validationToken) {
      form.$setValidity(validationToken, true, control);
    });

    arrayRemove(controls, control);
  };

If you add the control angular did not update the validity (from the sources):

  form.$addControl = function(control) {
    // Breaking change - before, inputs whose name was "hasOwnProperty" were quietly ignored
    // and not added to the scope.  Now we throw an error.
    assertNotHasOwnProperty(control.$name, 'input');
    controls.push(control);

    if (control.$name) {
      form[control.$name] = control;
    }
  };

so we have to do this manually. I guess this way:

if (value == true){
    form.$addControl(control); 
    angular.forEach(control.$error, function(validity, validationToken) {
       form.$setValidity(validationToken, !validity, control);
    });
   }else{
    form.$removeControl(control);
   }
}

Problem

I'm creating a directive to exclude a hidden input element from validation: http://plnkr.co/edit/Vnwvq2AT7JpgTnoQwGh9?p=preview ``` app.directive('shownValidation', function() { return { require: '^form', restrict: 'A', link: function(scope, element, attrs,form) { var control; scope.$watch(attrs.ngShow,function(value){ if (!control){ control = form[element.attr("name")]; } if (value == true){ form.$addControl(control); }else{ form.$removeControl(control); } }); } }; }); ``` The idea here is if the element is hidden, I will remove the control from the Form so that it will not affect the other input validity. It works fine when I call `form.$removeControl(control);`, you can test that in the demo by removing the firstname and clicking on the button to hide the field. But when I click the button again, the form validity is still true even though the firstname is invalid (empty) I also tried adding `form.$setValidity(form.$valid && control.$valid)` => the validity state is updated as expected but when I type into the firstname, the validity is still false. My question is how to solve this problem? Thanks for any replies. Update: Thanks to @Michael's answer. Here is the working solution: ``` app.directive('shownValidation', function() { return { require: '^form', restrict: 'A', link: function(scope, element, attrs, form) { var control; scope.$watch(attrs.ngShow, function(value) { if (!control) { control = form[element.attr("name")]; } if (value == true) { form.$addControl(control); //Add a forEach to manually update form validity.Thanks to @Michael's answer angular.forEach(control.$error, function(validity, validationToken) { form.$setValidity(validationToken, !validity, control); }); } else { form.$removeControl(control); } }); } }; }); ``` Working plunk

Original source