Skip to content

Commit 03bb888

Browse files
committed
fix(ngModel): revalidate the model when min/max expression values change
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
1 parent b474c36 commit 03bb888

File tree

2 files changed

+49
-14
lines changed

2 files changed

+49
-14
lines changed

src/ng/directive/input.js

+17-2
Original file line numberDiff line numberDiff line change
@@ -1129,15 +1129,30 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
11291129
});
11301130

11311131
if (attr.min) {
1132+
var minVal;
11321133
ctrl.$validators.min = function(value) {
1133-
return ctrl.$isEmpty(value) || isUndefined(attr.min) || value >= parseFloat(attr.min);
1134+
return ctrl.$isEmpty(value) || isUndefined(minVal) || value >= minVal;
11341135
};
1136+
1137+
val = isDefined(val) && parseFloat(val, 10);
1138+
minVal = isNaN(val) ? undefined : val;
1139+
// TODO(matsko): implement validateLater to reduce number of validations
1140+
ctrl.$validate();
1141+
});
11351142
}
11361143

11371144
if (attr.max) {
1145+
var maxVal;
11381146
ctrl.$validators.max = function(value) {
1139-
return ctrl.$isEmpty(value) || isUndefined(attr.max) || value <= parseFloat(attr.max);
1147+
return ctrl.$isEmpty(value) || isUndefined(maxVal) || value <= maxVal;
11401148
};
1149+
1150+
attr.$observe('max', function(val) {
1151+
val = isDefined(val) && parseFloat(val, 10);
1152+
maxVal = isNaN(val) ? undefined : val;
1153+
// TODO(matsko): implement validateLater to reduce number of validations
1154+
ctrl.$validate();
1155+
});
11411156
}
11421157
}
11431158

test/ng/directive/inputSpec.js

+32-12
Original file line numberDiff line numberDiff line change
@@ -2894,18 +2894,28 @@ describe('input', function() {
28942894
expect(scope.form.alias.$error.min).toBeFalsy();
28952895
});
28962896

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

2901-
changeInputValueTo('5');
2901+
changeInputValueTo('15');
2902+
expect(inputElm).toBeValid();
2903+
2904+
scope.min = 20;
2905+
scope.$digest();
29022906
expect(inputElm).toBeInvalid();
29032907

2904-
scope.min = 0;
2905-
scope.$digest(function () {
2906-
expect(inputElm).toBeValid();
2907-
done();
2908-
});
2908+
scope.min = null;
2909+
scope.$digest();
2910+
expect(inputElm).toBeValid();
2911+
2912+
scope.min = '20';
2913+
scope.$digest();
2914+
expect(inputElm).toBeInvalid();
2915+
2916+
scope.min = 'abc';
2917+
scope.$digest();
2918+
expect(inputElm).toBeValid();
29092919
});
29102920
});
29112921

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

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

29332943
changeInputValueTo('5');
29342944
expect(inputElm).toBeValid();
29352945

29362946
scope.max = 0;
2937-
scope.$digest(function () {
2938-
expect(inputElm).toBeInvalid();
2939-
done();
2940-
});
2947+
scope.$digest();
2948+
expect(inputElm).toBeInvalid();
2949+
2950+
scope.max = null;
2951+
scope.$digest();
2952+
expect(inputElm).toBeValid();
2953+
2954+
scope.max = '4';
2955+
scope.$digest();
2956+
expect(inputElm).toBeInvalid();
2957+
2958+
scope.max = 'abc';
2959+
scope.$digest();
2960+
expect(inputElm).toBeValid();
29412961
});
29422962
});
29432963

0 commit comments

Comments
 (0)