Reputation: 4563
I have a simple form with a directive:
<form name="testform">
<input name="testfield" type="text" ng-model="test.name" ng-minlength="3" my-validate>
</form>
Since Angular validates the field itself when entering less than 3 characters, it sets testform.testfield.$invalid
.
What I want to achieve is to add some custom validation functionality in a directive and react to this angular validation/set the validation result e.g. with the help of watchers or events like so:
angular.module('myApp.directives').directive('myValidate', [function() {
return {
link: function(scope, elem, attrs) {
elem.on('keyup', function() {
// do some custom validation
// if valid, set elem to $valid
// else set $error
// something like elem.set('$valid');
}
}
};
}]);
How can I achieve the combination of HTML5, Angular and custom form validation while using Angulars testform.testfield.$invalid
, testform.testfield.$valid
, testform.testfield.$error
etc. logic?
Upvotes: 1
Views: 2385
Reputation: 316
You can do custom validation and combine it with Angular's built in validation, you just need to require ngModel, pass ctrl as the 4th value to your link function, and use ctrl.$setValidity to indicate if your custom validation passes or fails.
The example below will be invalid if the length < 3 OR if the value is the string 'invalid':
var app = angular.module('app', []);
app.controller('controller', ['$scope',
function(scope) {
scope.test = {
name: ''
};
}
]);
app.directive('myValidate', [
function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
ctrl.$parsers.unshift(function(value) {
var valid = true;
if (value === 'invalid') {
valid = false;
}
ctrl.$setValidity(attrs.name, valid);
return valid ? value : undefined;
});
}
};
}
]);
Markup:
<body ng-app="app">
<div ng-controller="controller">
<form name="testform">
<input name="testform" type="text" ng-model="test.name" ng-minlength="3" my-validate /><br/>
</form>
<span style="color:green" ng-show="testform.testform.$valid">** valid **</span>
<span style="color:red" ng-show="testform.testform.$invalid">** invalid **</span>
</div>
<script src="script.js"></script>
</body>
Here is a plunker with this code: http://plnkr.co/edit/6XIKYvGwMSh1zpLRbbEm
The Angular documentation talks about this, though it wasn't totally obvious: https://docs.angularjs.org/api/ng/type/ngModel.NgModelController
This blog helped me get a hold on this: http://www.benlesh.com/2012/12/angular-js-custom-validation-via.html
Upvotes: 1
Reputation: 407
By default Angular provides some directives for input validation (like required, pattern, min, max etc.). If these directives doesn't suffice, custom validation is available. To be able to do that, the directive requires the model used for validation, then it can set the validity of the element like below:
.directive('myValidate', [ function() {
return {
require: 'ngModel',
link: function(scope, elem, attrs, ctrl) {
ctrl.$setValidity('myValidate', false);
}
};
}]);
A Plunker with such a directive which will become invalid when you enter '0' is HERE.
You can read more about custom validation on Angular forms documentation.
Upvotes: 2