I've written a custom validator for a password field, in order to verify the following scenarios:
Problem is, I have noticed the validator is run only when the user interacts with the field (unlike required
which is run on any input apparently). This makes the form appear valid even if password empty for a new user. Once I interact with the password input, everything seems fine.
I have solved the business logic requirement through the poorly documented ngRequired
directive, but I would really like to understand the issue regarding the custom validator in case I run into it again.
After giving up on this, I ran into the problem again and I could not find a workaround. Fortunatel, I found a solution:
When you make a custom validator you need to bind it to the model field, not the form field. This makes it validate correctly all the time (one can assume due to differences between $modelValue and $viewValue properties that are on the form field which fudges up things). Please see code below for reference:
<input type="password" class="form-control" id="confirmpass" name="confirmpass" placeholder="Repeat Password"
ng-model="controller.selectedUser.passwordRepeat"
compare-to="controller.selectedUser.password"/>
And custom validator:
angular.module("compareTo", []).directive("compareTo", function() {
return {
require: "ngModel",
scope: {
otherModelValue: "=compareTo"
},
link: function(scope, element, attributes, ngModel) {
ngModel.$validators.compareTo = function(modelValue) {
return modelValue == scope.otherModelValue;
};
scope.$watch("otherModelValue", function() {
ngModel.$validate();
});
}
};
);