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