Skip to content

Commit

Permalink
fix(ngModel): revalidate the model when min/max expression values cha…
Browse files Browse the repository at this point in the history
…nge for number inputs

As of this fix if the max or min value is changed via scope or by another ngModel
then it will trigger the model containing the min/max attributes to revalidate itself.

Closes angular#2404
  • Loading branch information
matsko committed Sep 4, 2014
1 parent 3952408 commit 3f3f60c
Show file tree
Hide file tree
Showing 2 changed files with 54 additions and 14 deletions.
24 changes: 22 additions & 2 deletions src/ng/directive/input.js
Original file line number Diff line number Diff line change
Expand Up @@ -1129,15 +1129,35 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
});

if (attr.min) {
var minVal;
ctrl.$validators.min = function(value) {
return ctrl.$isEmpty(value) || isUndefined(attr.min) || value >= parseFloat(attr.min);
return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
};

attr.$observe('min', function(val) {
if (isDefined(val) && !isNumber(val)) {
val = parseFloat(val, 10);
}
minVal = isNumber(val) && !isNaN(val) ? val : undefined;
// TODO(matsko): implement validateLater to reduce number of validations
ctrl.$validate();
});
}

if (attr.max) {
var maxVal;
ctrl.$validators.max = function(value) {
return ctrl.$isEmpty(value) || isUndefined(attr.max) || value <= parseFloat(attr.max);
return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
};

attr.$observe('max', function(val) {
if (isDefined(val) && !isNumber(val)) {
val = parseFloat(val, 10);
}
maxVal = isNumber(val) && !isNaN(val) ? val : undefined;
// TODO(matsko): implement validateLater to reduce number of validations
ctrl.$validate();
});
}
}

Expand Down
44 changes: 32 additions & 12 deletions test/ng/directive/inputSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -2894,18 +2894,28 @@ describe('input', function() {
expect(scope.form.alias.$error.min).toBeFalsy();
});

it('should validate even if min value changes on-the-fly', function(done) {
it('should validate even if min value changes on-the-fly', function() {
scope.min = 10;
compileInput('<input type="number" ng-model="value" name="alias" min="{{min}}" />');

changeInputValueTo('5');
changeInputValueTo('15');
expect(inputElm).toBeValid();

scope.min = 20;
scope.$digest();
expect(inputElm).toBeInvalid();

scope.min = 0;
scope.$digest(function () {
expect(inputElm).toBeValid();
done();
});
scope.min = null;
scope.$digest();
expect(inputElm).toBeValid();

scope.min = '20';
scope.$digest();
expect(inputElm).toBeInvalid();

scope.min = 'abc';
scope.$digest();
expect(inputElm).toBeValid();
});
});

Expand All @@ -2926,18 +2936,28 @@ describe('input', function() {
expect(scope.form.alias.$error.max).toBeFalsy();
});

it('should validate even if max value changes on-the-fly', function(done) {
it('should validate even if max value changes on-the-fly', function() {
scope.max = 10;
compileInput('<input type="number" ng-model="value" name="alias" max="{{max}}" />');

changeInputValueTo('5');
expect(inputElm).toBeValid();

scope.max = 0;
scope.$digest(function () {
expect(inputElm).toBeInvalid();
done();
});
scope.$digest();
expect(inputElm).toBeInvalid();

scope.max = null;
scope.$digest();
expect(inputElm).toBeValid();

scope.max = '4';
scope.$digest();
expect(inputElm).toBeInvalid();

scope.max = 'abc';
scope.$digest();
expect(inputElm).toBeValid();
});
});

Expand Down

0 comments on commit 3f3f60c

Please sign in to comment.