If you’re converting a legacy app or simply have a complicated validation scheme already implemented on the server that you aren’t ready to replicate on the client then whole form validation may be for you.
The goal is to take an entire form model and validate the whole object on the server and return back a collection of errors. This will give the user instant feedback that they have entered some data that is invalid.
Directive
Creating a custom directive contact-validator
and applying it to the ng-form
directive I am able to setup the asyncValidator
on the entire model.
app.directive('contactValidator', function($q, $http) { return { restrict: 'A', require: 'ngModel', link: function(scope, element, attrs, ngModel) { ngModel.$asyncValidators.contact = function(model) { ... } } } });
In order to catch all the model updates a $watch
is applied with the deep checking enabled.
scope.$watch(attrs.ngModel, function(model) { if (model != null) { ngModel.$validate(); } }, true);
You may want to review the ngModel directive documentation and the advanced features it contains.
Model Options
Model options are important because without them then the entire model will be cleared if validation fails.
ng-model-options="{allowInvalid: true}"
Things to consider
When using this method consider changing the validation event on each input field to on blur instead of on keypress to reduce the chattyness of the validations events.
ng-model-options="{updateOn:'blur'}"
In low latency environments where the web server and you are in the same office this can provide a quick way to extend the server side validation directly to the browser.
Remember it will be more performant to have your client side code do as much of the validation as possible. But when you need it this method is available.