Reputation: 136
Now, in my validation directive I set validation state 'manually', like this:
$element.on('focus', function() {
$scope.$apply(function() {
ngModelCtrl.$setValidity('length', true);
});
});
$element.on('blur', function() {
$scope.$apply(function() {
if (ngModelCtrl.$modelValue && ngModelCtrl.$modelValue.length === +$attrs.maxlength) {
ngModelCtrl.$setValidity('length', true);
}
else if (ngModelCtrl.$modelValue.length < +$attrs.maxlength && ngModelCtrl.$modelValue.length > 0) {
ngModelCtrl.$setValidity('length', false);
}
}
});
But I want to set validation states with $validators
with saving validation behaviour (on blur/focus events).
I can't use ng-model-options
with updateOn: 'blur'
.
Is other options to do this?
Upvotes: 1
Views: 352
Reputation: 3726
So to use a custom validator you will need to structure your directive a little differently. The major difference is you need to require ngModel
.
Directive
return {
require: 'ngModel',
link: function(scope, element, attrs, ngModel) {
// Run validator for maxLenth
ngModel.$validators.customMaxLength = function(value) {
var status = false;
if(value.length <= attrs.maxLengthValidator) {
console.log(attrs.maxLengthValidator);
status = true;
}
return status;
};
}
}
Something important to note. If you are using an attribute to do your validate against and the value can change you need to watch the value and run your validator function against in manually. Because the model does not change the validator would not fire automatically.
Add the following to the directive
scope.$watch(function() {
return attrs.maxLengthValidator;
},function() {
ngModel.$validate();
});
If you validator returns false you form will automatically have $valid
set to false
HTML
In the example below I use angular-messages to display the valid output. This is an optional module that needs included.
<form name="myForm">
<div class="form-group" ng-class="{'has-error':myForm.testField.$invalid}">
<label class="control-label" for="testInput">Test Field</label>
<input class="form-control" type="text" name="testField"
max-length-validator="3" required ng-model="testField"/>
</div>
</form>
<div ng-messages ng-messages-multiple class="bg-danger" for="myForm.testField.$error">
<div ng-message when="required">Please enter value</div>
<div ng-message when="customMaxLength">To Long</div>
</div>
You don't really want to update the ngModel if the model value is invalid.
What I would recommend is using styles and a focus attribute with the field to toggle the display based on the focus of the field.
Add something like the following to your input field
ng-focus="myForm.testField.focus=true" ng-blur="myForm.testField.focus=false"
Then use checks with ng-class
, ng-show
or ng-hide
to update your display.
This has been added to the plnkr
Upvotes: 1