While writing applications using Angular JS, sometimes we need to define our own validators. Custom validations in Angular JS are created as directives with a dependency on the ng-model directive. At times, key part of the validation depends on controller of the ng-model directive.
The ng-model directive provides two arrays of functions to which the custom validation logic can be hooked: $parsers and $formatters. Usage of both of these arrays looks similar, but they are invoked under different conditions.
$parsers:
In most of the cases, $parsers is the right option to handle the logic of custom validation. Functions added to $parsers are called as soon as the value in the form input is modified by the user. As an example, consider the following directive:
This is a simple directive that checks if the number entered in the textbox is even. If we apply validation on a textbox, the validator works as long as the value is modified in the textbox.
$formatters:
Formatters are invoked when the model is modified in the code. They are not invoked if the value is modified in the textbox. $formatters are useful when there is a possibility of the value getting modified from the code. $formatters can be applied in the above directive using a simple statement:
Now, the validation on the textbox containing the evenNumber is fired when the value is directly modified or even when the value is modified in the code.
A demo of the directive is available on plnkr.
Happy coding!
The ng-model directive provides two arrays of functions to which the custom validation logic can be hooked: $parsers and $formatters. Usage of both of these arrays looks similar, but they are invoked under different conditions.
$parsers:
In most of the cases, $parsers is the right option to handle the logic of custom validation. Functions added to $parsers are called as soon as the value in the form input is modified by the user. As an example, consider the following directive:
app.directive('evenNumber', function(){ return{ require:'ngModel', link: function(scope, elem, attrs, ctrl){ ctrl.$parsers.unshift(checkForEven); function checkForEven(viewValue){ if (parseInt(viewValue)%2 === 0) { ctrl.$setValidity('evenNumber',true); } else{ ctrl.$setValidity('evenNumber', false); } return viewValue; } } }; });
This is a simple directive that checks if the number entered in the textbox is even. If we apply validation on a textbox, the validator works as long as the value is modified in the textbox.
$formatters:
Formatters are invoked when the model is modified in the code. They are not invoked if the value is modified in the textbox. $formatters are useful when there is a possibility of the value getting modified from the code. $formatters can be applied in the above directive using a simple statement:
ctrl.$formatters.unshift(checkForEven);
Now, the validation on the textbox containing the evenNumber is fired when the value is directly modified or even when the value is modified in the code.
A demo of the directive is available on plnkr.
Happy coding!
Hi Ravi, for some weird reason my $parsers do nothing and also i have another problem, my ctrl.$pristine is always true,
ReplyDeletelink: function(scope, elem, attrs, ctrl){
ctrl.$parsers.unshift(validate);
//ctrl.$formatters.unshift(validate);
function validate(viewValue){
console.log(viewValue); // this is never triggered
console.log(ctrl.$pristine); //this is always true but only works with formatters
}
}
if i uncomment the formatters line, everything works well, any ideas? hope you can help me this is driving me crazy, i cant figure it out why $parsers didnt work