I\'ve created a validation directive for my form. It basically validates a fields value based on data from another field.
It works perfect :-)
My problem is
Maybe a simpler solution would be with a watcher or even an expression inside the ng-show direcive of your error span.
Using an expression inside the ng-show directive would be like this:
<span ng-show="int1 > int2" style="color: red; display:none">
Otherwise you could watch for changes in the models int1 and int2 and compare their values:
$scope.$watch('int1+int2', function () {
if($scope.int1 > $scope.int2) {
$scope.error = true;
}else {
$scope.error = false;
}
})
<span ng-show="error" style="color: red; display:none">
Here is a fiddle
It is a really bad idea to refer explicitly to some fields in your directive. As you can see, this has a lot of drawbacks : unportability, code repetition, brittleness, …
Just make something like that :
<input type="text" ng-model="int2" validate-greater-integer="int1" />
And :
myApp.directive('validateGreaterInteger', function() {
return {
require: 'ngModel',
scope: {
otherInteger : '=validateGreaterInteger',
}
link: function(scope, elm, attrs, ctrl) {
ctrl.$parsers.unshift(function(viewValue) {
if (viewValue > scope.otherInteger) {
ctrl.$setValidity('higher', true);
return viewValue;
} else {
ctrl.$setValidity('higher', false);
return undefined;
}
}
});
You can then simply do the typical state control (see the section "Binding to form and control state" for an exemple).
Please notice that, in this case, you can also more simply use input[number] and its min
parameter.
Edit after the discussion in comments :
Well, the functions in NgModelController.$parsers
are obviously called only when the content of the model changes. What you want to do is to make validation whenever int1
or int2
change. So just do it :-) :
link: function(scope, elm, attrs, ctrl) {
scope.$watch('data', function (data) {
if (data.int2 > data.int1) {
ctrl.$setValidity('higher', true);
return data.int2;
} else {
ctrl.$setValidity('higher', false);
return undefined;
}
}, true);
Use your own validation variable (int2valid
in your Fiddle) is also very strange. Please use the typical state control, with something like form.int2.$error.higher
.