Last week, I was playing a bit with the popular angularjs framework and discover
how to handle with custom form validation.
I had a form with multiple selects to select countries but each country selected has to be unique.
Here the simply html of the current form (without the Add/Remove all buttons) :
Let's now deal with the custom form validator [1] and create a angular directive
called unique. This validator will check if an existing country already exists in
scope.prices.
Note: ngModel.$parsers.unshift is called on value changed and BEFORE the value is selected (so
the number of same element must be 0 to be invalid).
While ngModel.$formatters.unshift is called during page load
(number of found elements must be > 1 to be invalid).
This directive is using "ngModel.$setValidity" to change the validity of the model.
To use it, just add "unique" in the html element
Playing with ng-show, we can easily display an error message
However, with the current implementation, our unique directive is not reusable :
Scope need to have a 'prices' element (which is an object).
Let's change that by setting the unique element directly in the attribute and use
the 'name' attribute if the unique element is an object.
Now our directive is completely reusable, let style it a bit.
Angular automatically add classes to (in)valid form element (ng-valid/ng-invalid).
To finish, we can play with ng-disabled [3] on the submit button to prevent
the user to send the form if it is invalid.
Note: myForm is invalid because we changed the element validity in the directive using
ngModel.$setValidity.