Reputation: 23
I'm trying to build a directive for input fields which validates using a custom function passed from the outer scope, for example:
HTML:
<input type="text" custom-validator="checkValidity"/>
Controller:
$scope.checkValidity = function(value){
return $scope.invalidWords.indexOf(value) === -1;
}
I've created a detailed plunker for this: http://plnkr.co/edit/H5A5O3?p=preview
Validation works, but it seems to broke things up with the default directives, in this case ng-disabled doesn't work and I can't access the variable used in ng-model!
This is my directive:
app.directive('customValidator', function() {
return {
require: "ngModel"
, scope: { customValidator: '='}
, link: function postLink(scope, elm, attrs, ctrl) {
var validator = function(value) {
if(scope.customValidator && scope.customValidator(value)) {
ctrl.$setValidity('custom-validator', true);
return value;
}
ctrl.$setValidity('custom-validator', false);
return undefined;
}
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
}
});
I can't figure out what's going wrong, I really need help!
I should stay on Angular 1.0.7
Upvotes: 2
Views: 2413
Reputation: 364687
ng-model and isolate scopes don't mix well, so follow @Codezilla's advice and don't create a new scope.
However, I suggest using $parse, which allows us to clearly specify in the HTML that we are passing a function with a single (named) argument to the directive:
<input type="text" ... custom-validator="checkValidity(val)">
app.directive('customValidator', function($parse) {
return {
require: "ngModel",
//scope: false,
link: function postLink(scope, elm, attrs, ctrl) {
var validationFn = $parse(attrs.customValidator);
var validator = function(value) {
if(validationFn(scope, {val: value})) {
ctrl.$setValidity('custom-validator', true);
return value;
}
ctrl.$setValidity('custom-validator', false);
return undefined;
}
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
}
});
Upvotes: 3
Reputation: 43947
The reason ng-disabled
in not working on inputB
is that you are creating a new scope through your directive:
scope: { customValidator: '=' }
To keep your model inputB
in the same scope as inputA
you can do something like this:
app.directive('customValidator', function() {
return {
require: "ngModel",
scope: false,
link: function postLink(scope, elm, attrs, ctrl) {
var validator = function(value) {
customValidator = scope[attrs["customValidator"]];
if(customValidator(value)) {
ctrl.$setValidity('custom-validator', true);
return value;
}
ctrl.$setValidity('custom-validator', false);
return undefined;
}
ctrl.$parsers.unshift(validator);
ctrl.$formatters.unshift(validator);
}
}
});
Upvotes: 4