Reputation: 1580
I want to apply "ng-pattern" to the form input fields using a directive. Let's say I want to check if the value provided is an integer or not.
form-markup
<form class="form" name="frm" novalidate>
<div class="form-group">
<label class="control-label">Age</label>
<input int
type="text"
name="age"
class="form-control"
ng-model="fd.age">
<span class="help-block" ng-show="frm.age.$error.pattern">
age is just a number.
</span>
</div>
</form>
and the directive code is like this
app.directive("int", function($compile){
return {
restrict: "A",
scope: true,
replace: true,
link: function(scope, elem, attrs) {
elem.attr("ng-pattern", "/[0-9]+/");
}
}
});
In the markup I can see that it is applied properly but still it doesn't work. The pattern is correct because when I use it explicitly in the markup without using the directive it works nicely.
I have two questions.
Why this doesn't work?
Since I have to write a lot of such domain specific directives, is my approach correct to solve this problem pattern.
Upvotes: 0
Views: 1077
Reputation: 1169
Instead of trying to incapsulate an existing validator in your custom directive, you should try implementing a custom validation rule as explained in this article
I've modified your example using this technique.
Code:
<form class="form" name="frm" novalidate>
<div class="form-group">
<label class="control-label">Age</label>
<input int
type="text"
name="age"
class="form-control"
ng-model="fd.age">
<span class="help-block" ng-show="frm.age.$error.numberValidator">
age is just a number.
</span>
</div>
</form>
JS:
app.directive("int", function() {
return {
restrict: "A",
scope: true,
replace: true,
require: 'ngModel',
link: function(scope, elem, attrs,ctrl) {
function customValidator(ngModelValue) {
if (/^[0-9]+$/.test(ngModelValue)) {
ctrl.$setValidity('numberValidator', true);
} else {
ctrl.$setValidity('numberValidator', false);
}
return ngModelValue;
}
ctrl.$parsers.push(customValidator);
}
}
});
For your specific case - there is a standard validation rule $error.number
described in this documentation
To answer your first question - for the ng-pattern
directive to be functional you need to re-run the compile cycle via $compile
service for the given element and bind it to the scope
.
Like this:
myApp.directive("int2", function($compile) {
return {
restrict: "A",
scope: true,
replace: true,
require: 'ngModel',
link: function(scope, elem, attrs) {
elem.attr("ng-pattern", "/^[0-9]+$/");
elem.removeAttr("int2");
$compile(elem)(scope);
}
}
});
Here is an updated Fiddle to illustrate the behavior.
Upvotes: 1