I have numerous number input fields that have min and max attribute values that depend on logic elsewhere in my AngularJS app, but when using data bindings within these attr
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
.
i have face the same problem. got success by using this directive :
angular.module('tech').directive('maximum', ['$parse',
function($parse) {
return {
restrict: 'A',
require: '?ngModel',
link: function(scope, element, attrs, ctrl) {
if (!ctrl) return;
attrs.maximum = true;
var checkMax = function(n) {
if (!n) return;
var actualValue = ctrl.$viewValue;
var maxValue = attrs.maximum;
if (parseInt(actualValue) > parseInt(maxValue)) {
ctrl.$setValidity('maximum', false);
} else {
ctrl.$setValidity('maximum', true);
}
};
scope.$watch(attrs.ngModel, checkMax);
//attrs.$observe('ngModel', remind);
attrs.$observe('maximum', checkMax);
}
}
}
]);
i got this solution from this website. for entire code you can go for this website
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.
I also wrote a custom directive for it:
.directive('validateRange', ['$parse', function($parse) {
function link($scope, $element, $attrs, ngModel) {
var attrRange, range = [];
function validate(value) {
var validMin = true, validMax = true;
if (typeof range[0] === 'number') {
ngModel.$setValidity('min', value >= range[0]);
validMin = value >= range[0];
}
if (typeof range[1] === 'number') {
ngModel.$setValidity('max', value <= range[1]);
validMax = value <= range[1];
}
return validMin && validMax ? value : undefined;
}
attrRange = $attrs.validateRange.split(/,/);
range[0] = $parse(attrRange[0] || '')($scope);
range[1] = $parse(attrRange[1] || '')($scope);
$scope.$watchCollection('[' + $attrs.validateRange + ']', function(values) {
range = values;
validate(ngModel.$viewValue);
});
ngModel.$parsers.unshift(validate);
ngModel.$formatters.unshift(validate);
}
return {
link: link,
require: 'ngModel'
};
}]);
Example use:
<form name="myform" ng-init="minvalue=0;value=1;maxvalue=2">
Min Value:
<input type="number" name="minvalue" required
data-validate-range="0,value"
ng-model="minvalue">
Value:
<input type="number" name="value" required
data-validate-range="minvalue,maxvalue"
ng-model="value">
Max Value:
<input type="number" name="maxvalue" required
data-validate-range="value,false"
ng-model="maxvalue">
<pre>
myform.minvalue.$error {{ myform.minvalue.$error }}
myform.value.$error {{ myform.value.$error }}
myform.maxvalue.$error {{ myform.maxvalue.$error }}
</pre>
</form>
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']);