Validation not triggered when data binding a number input's min / max attributes
I wrote directives to fill the gap, ng-min and ng-max:
http://jsfiddle.net/g/s5gKC/
var app = angular.module('app', []);
function isEmpty(value) {
return angular.isUndefined(value) || value === '' || value === null || value !== value;
}
app.directive('ngMin', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
scope.$watch(attr.ngMin, function(){
ctrl.$setViewValue(ctrl.$viewValue);
});
var minValidator = function(value) {
var min = scope.$eval(attr.ngMin) || 0;
if (!isEmpty(value) && value < min) {
ctrl.$setValidity('ngMin', false);
return undefined;
} else {
ctrl.$setValidity('ngMin', true);
return value;
}
};
ctrl.$parsers.push(minValidator);
ctrl.$formatters.push(minValidator);
}
};
});
app.directive('ngMax', function() {
return {
restrict: 'A',
require: 'ngModel',
link: function(scope, elem, attr, ctrl) {
scope.$watch(attr.ngMax, function(){
ctrl.$setViewValue(ctrl.$viewValue);
});
var maxValidator = function(value) {
var max = scope.$eval(attr.ngMax) || Infinity;
if (!isEmpty(value) && value > max) {
ctrl.$setValidity('ngMax', false);
return undefined;
} else {
ctrl.$setValidity('ngMax', true);
return value;
}
};
ctrl.$parsers.push(maxValidator);
ctrl.$formatters.push(maxValidator);
}
};
});
angular.bootstrap(document.body, ['app']);
Apparently we can't use {{}}s (i.e., interpolation) for the min
and max
fields. I looked at the source code and I found the following:
if (attr.min) {
var min = parseFloat(attr.min);
$interpolate
is not called, just parseFloat
, so you'll need to specify a string that looks like a number for min
and max
.
Angular appears to now support ng-min
and ng-max
out of the box without the necessity of writing your own directives. See this Fiddle that is using Angular 1.4.2.