diff --git a/src/ng/directive/input.js b/src/ng/directive/input.js index 40b29b236900..f672e571c098 100644 --- a/src/ng/directive/input.js +++ b/src/ng/directive/input.js @@ -82,8 +82,8 @@ var inputType = { * * @param {string} ngModel Assignable angular expression to data-bind to. * @param {string=} name Property name of the form under which the control is published. - * @param {string=} min Sets the `min` validation error key if the value entered is less then `min`. - * @param {string=} max Sets the `max` validation error key if the value entered is greater then `min`. + * @param {expression} min Sets the `min` validation error key if the value entered is less then `min`. + * @param {expression} max Sets the `max` validation error key if the value entered is greater then `max`. * @param {string=} required Sets `required` validation error key if the value is not entered. * @param {number=} ngMinlength Sets `minlength` validation error key if the value is shorter than * minlength. @@ -498,38 +498,31 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) { return isEmpty(value) ? '' : '' + value; }); - if (attr.min) { - var min = parseFloat(attr.min); - var minValidator = function(value) { - if (!isEmpty(value) && value < min) { - ctrl.$setValidity('min', false); - return undefined; - } else { - ctrl.$setValidity('min', true); - return value; - } - }; - - ctrl.$parsers.push(minValidator); - ctrl.$formatters.push(minValidator); - } + function applyMinMax(minOrMax, notInRange) { + if (attr.hasOwnProperty(minOrMax)) { + var validator = function(value) { + var parsedValue = parseFloat(attr[minOrMax]); + if (!isEmpty(value) && notInRange(value, parsedValue)) { + ctrl.$setValidity(minOrMax, false); + return undefined; + } else { + ctrl.$setValidity(minOrMax, true); + return value; + } + }; - if (attr.max) { - var max = parseFloat(attr.max); - var maxValidator = function(value) { - if (!isEmpty(value) && value > max) { - ctrl.$setValidity('max', false); - return undefined; - } else { - ctrl.$setValidity('max', true); - return value; - } - }; + ctrl.$parsers.push(validator); + ctrl.$formatters.push(validator); - ctrl.$parsers.push(maxValidator); - ctrl.$formatters.push(maxValidator); + attr.$observe(minOrMax, function() { + // triggering validation + ctrl.$setViewValue(ctrl.$viewValue); + }); + } } - + applyMinMax('min', function notInRange(value, min) {return value < min}); + applyMinMax('max', function notInRange(value, max) {return value > max}); + ctrl.$formatters.push(function(value) { if (isEmpty(value) || isNumber(value)) { diff --git a/test/ng/directive/inputSpec.js b/test/ng/directive/inputSpec.js index 3b511011d1a6..41a9c1980b9e 100644 --- a/test/ng/directive/inputSpec.js +++ b/test/ng/directive/inputSpec.js @@ -592,7 +592,10 @@ describe('input', function() { describe('min', function() { it('should validate', function() { - compileInput(''); + scope.$apply(function() { + scope.min = 10; + }); + compileInput(''); scope.$digest(); changeInputValueTo('1'); @@ -604,6 +607,15 @@ describe('input', function() { expect(inputElm).toBeValid(); expect(scope.value).toBe(100); expect(scope.form.alias.$error.min).toBeFalsy(); + + scope.$apply(function() { + scope.min = 200; + }); + expect(inputElm.val()).toBe('100'); + expect(inputElm).toBeInvalid(); + expect(scope.value).toBeFalsy(); + expect(scope.form.alias.$error.min).toBeTruthy(); + }); }); @@ -611,7 +623,8 @@ describe('input', function() { describe('max', function() { it('should validate', function() { - compileInput(''); + scope.max = 10; + compileInput(''); scope.$digest(); changeInputValueTo('20');