Multiple validation directives not working-Collection of common programming errors
I’m trying to write my own set of directives. I have written following two directives:
- eaValidateEmail (Validates the format of the email address)
- eaValidateUnique (Will validate the uniqueness by a call to a rest service once complete)
What I want to achieve:
- First the eaValidateEmail directive is executed which returns false until the format of the email is correct
- Then and only then the eaValidateUnique directive should execute and check if the email address is taken already over a rest service. If the value is not found it will return true, else it will return false.
What’s happening
When I only add the eaValidateEmail directive, everything is working and the format of the email is validated.
But as soon I add the eaValidateUnique directive then the eaValidateEmail directive is left out and the ctrl.$valid method of the eaValidateUnique directive is always passing even though ctrl.$valid is false in console.log.
I have read through the AngularJS documentation, bought two books but the examples are always very basic. Currently I can’t figure out where the problem could be located. It looks like there is a clash with ngModelController but I can’t figure out the right way to solve this issue.
I’m currently testing with the ValidateCtrlNew form. So the field in the “New” section of the html form.
Questions:
- Does anybody know how to write the directives so that they are executed in serial order as I add them as attributes to the input element?
- How can I prevent such clashes with directives? Isolated scope is also no option for multiple directives.
Here is the jsfiddle: http://jsfiddle.net/charms/6j3U8/230/
New
Invalid:
Please enter your email.
This is not a valid email.
Checking email....
This email is already taken.
.directive('eaValidateUnique', ['$http', function($http) {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
ctrl.$parsers.push(function(viewValue) {
console.log(ctrl);
//ctrl.$setValidity('eaValidateUnique', true);
if(ctrl.$valid) {
ctrl.$setValidity('eaValidateUnique', false);
console.log("valid was true");
}
});
}
};
}])
.directive('eaValidateEmail', [function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
var EMAIL_REGEXP = /^([\w-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|(([\w-]+\.)+))([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$/;
ctrl.$parsers.push(function(viewValue) {
// set validity to true to clear out if previous validators fail
ctrl.$setValidity('eaValidateEmail', true);
if(ctrl.$valid) {
// set validity to false as we need to check the value here
ctrl.$setValidity('eaValidateEmail', false);
if(viewValue !== undefined && viewValue !== "" && EMAIL_REGEXP.test(viewValue)) {
// if the format of the email is valid then we set validity to true
ctrl.$setValidity('eaValidateEmail', true);
ctrl.$setValidity('eaValidateEmailCheck', true);
console.log("TRUE");
} else {
// if the format of the email is invalid we set validity to false
ctrl.$setValidity('eaValidateEmail', false);
ctrl.$setValidity('eaValidateEmailCheck', true);
console.log("FALSE");
}
}
return viewValue;
});
}
};
}]);