Skip to content
This repository was archived by the owner on Apr 12, 2024. It is now read-only.

Commit 0dbe342

Browse files
committed
fix IE10+11 bugs, mark tests for unsupported range
1 parent 9d30cea commit 0dbe342

File tree

2 files changed

+71
-47
lines changed

2 files changed

+71
-47
lines changed

src/ng/directive/input.js

+14-5
Original file line numberDiff line numberDiff line change
@@ -1530,6 +1530,11 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15301530

15311531
// TODO(matsko): implement validateLater to reduce number of validations
15321532
if (minAttrType === 'min') {
1533+
var elVal = element.val();
1534+
// IE11 doesn't set the el val correctly if the maxVal is less than the element value
1535+
if (minVal > elVal) {
1536+
element.val(minVal);
1537+
}
15331538
ctrl.$setViewValue(element.val());
15341539
} else {
15351540
ctrl.$validate();
@@ -1540,7 +1545,7 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15401545
if (minAttrType) {
15411546
ctrl.$validators.min = isDefined(attr.min) && supportsRange && isDefined(validity.rangeUnderflow) ?
15421547
function nativeMinValidator(value) {
1543-
return !element[0].validity.rangeOverflow;
1548+
return !element[0].validity.rangeUnderflow;
15441549
} :
15451550
function minValidator(modelValue, viewValue) {
15461551
return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;
@@ -1563,24 +1568,28 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15631568
}
15641569

15651570
if (maxAttrType === 'max') {
1571+
var elVal = element.val();
1572+
// IE11 doesn't set the el val correctly if the maxVal is less than the element value
1573+
if (maxVal < elVal) {
1574+
element.val(maxVal);
1575+
}
15661576
ctrl.$setViewValue(element.val());
15671577
} else {
15681578
ctrl.$validate();
15691579
}
15701580
}
1571-
15721581
var maxAttrType = isDefined(attr.max) ? 'max' : attr.ngMax ? 'ngMax' : false;
15731582
if (maxAttrType) {
15741583
// Since ngMax doesn't set the max attr, the browser doesn't adjust the input value as setting max would
15751584
ctrl.$validators.max = isDefined(attr.max) && supportsRange && isDefined(validity.rangeOverflow) ?
1576-
function nativeMaxValidator(value) {
1577-
return !element[0].validity.rangeOverflow;
1585+
function nativeMaxValidator() {
1586+
// IE10+11 incorrectly set the rangeOverflow error when max < min
1587+
return (msie > 9 && maxVal < minVal) ? true : !element[0].validity.rangeOverflow;
15781588
} :
15791589
function maxValidator(modelValue, viewValue) {
15801590
return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;
15811591
};
15821592

1583-
console.log('max initial', attr.max);
15841593
// Assign maxVal when the directive is linked. This won't $validate as the model isn't ready yet
15851594
maxChange(attr.max);
15861595
attr.$observe('max', maxChange);

test/ng/directive/inputSpec.js

+57-42
Original file line numberDiff line numberDiff line change
@@ -2830,50 +2830,31 @@ describe('input', function() {
28302830
var rangeTestEl = angular.element('<input type="range">');
28312831
var supportsRange = rangeTestEl[0].type === 'range';
28322832

2833-
it('should reset the model if view is invalid', function() {
2834-
var inputElm = helper.compileInput('<input type="range" ng-model="age"/>');
2835-
2836-
scope.$apply('age = 100');
2837-
expect(inputElm.val()).toBe('100');
2838-
2839-
try {
2840-
// to allow non-number values, we have to change type so that
2841-
// the browser which have number validation will not interfere with
2842-
// this test. IE8 won't allow it hence the catch.
2843-
inputElm[0].setAttribute('type', 'text');
2844-
} catch (e) {}
2845-
2846-
helper.changeInputValueTo('100X');
2847-
expect(inputElm.val()).toBe('100X');
2848-
expect(scope.age).toBeUndefined();
2849-
expect(inputElm).toBeInvalid();
2850-
});
2851-
2833+
if (supportsRange) {
2834+
// This behavior only applies to browsers that implement the range input, which do not
2835+
// allow to set a non-number value and will set the value of the input to 50 even when you
2836+
// change it directly on the element.
2837+
// Other browsers fall back to text inputs, where setting a model value of 50 does not make
2838+
// sense if the input value is a string. These browser will mark the input as invalid instead.
28522839

2853-
it('should render as 50 if null', function() {
2854-
var inputElm = helper.compileInput('<input type="range" ng-model="age" />');
2840+
it('should render as 50 if null', function() {
2841+
var inputElm = helper.compileInput('<input type="range" ng-model="age" />');
28552842

2856-
scope.$apply('age = null');
2843+
scope.$apply('age = null');
28572844

2858-
expect(inputElm.val()).toEqual('50');
2859-
});
2845+
expect(inputElm.val()).toEqual('50');
2846+
});
28602847

2861-
it('should set model to 50 when no value specified', function() {
2862-
var inputElm = helper.compileInput('<input type="range" ng-model="age" />');
2848+
it('should set model to 50 when no value specified', function() {
2849+
var inputElm = helper.compileInput('<input type="range" ng-model="age" />');
28632850

2864-
expect(inputElm.val()).toBe('50');
2851+
expect(inputElm.val()).toBe('50');
28652852

2866-
scope.$apply('age = null');
2853+
scope.$apply('age = null');
28672854

2868-
expect(scope.age).toBe(50);
2869-
});
2855+
expect(scope.age).toBe(50);
2856+
});
28702857

2871-
if (supportsRange) {
2872-
// This behavior only applies to browsers that implement the range input, which do not
2873-
// allow to set a non-number value and will set the value of the input to 50 even when you
2874-
// change it directly on the element.
2875-
// Other browsers fall back to text inputs, where setting a model value of 50 does not make
2876-
// sense if the input value is a string. These browser will mark the input as invalid instead.
28772858
it('should parse non-number values to 50', function() {
28782859
var inputElm = helper.compileInput('<input type="range" ng-model="age" />');
28792860

@@ -2884,6 +2865,20 @@ describe('input', function() {
28842865
expect(scope.age).toBe(50);
28852866
expect(inputElm).toBeValid();
28862867
});
2868+
2869+
} else {
2870+
2871+
it('should reset the model if view is invalid', function() {
2872+
var inputElm = helper.compileInput('<input type="range" ng-model="age"/>');
2873+
2874+
scope.$apply('age = 100');
2875+
expect(inputElm.val()).toBe('100');
2876+
2877+
helper.changeInputValueTo('100X');
2878+
expect(inputElm.val()).toBe('100X');
2879+
expect(scope.age).toBeUndefined();
2880+
expect(inputElm).toBeInvalid();
2881+
});
28872882
}
28882883

28892884
it('should only invalidate the model if suffering from bad input when the data is parsed', function() {
@@ -3183,14 +3178,34 @@ describe('input', function() {
31833178
});
31843179

31853180
if (supportsRange) {
3186-
it('should keep the initial default value when min and max are specified', function() {
3187-
scope.max = 80;
3188-
scope.min = 40;
3189-
var inputElm = helper.compileInput('<input type="range" ng-model="value" name="alias" max="{{max}}" min="{{min}}" />');
31903181

3191-
expect(inputElm.val()).toBe('50');
3192-
expect(scope.value).toBe(50);
3182+
describe('min and max', function() {
3183+
3184+
it('should keep the initial default value when min and max are specified', function() {
3185+
scope.max = 80;
3186+
scope.min = 40;
3187+
var inputElm = helper.compileInput('<input type="range" ng-model="value" name="alias" max="{{max}}" min="{{min}}" />');
3188+
3189+
expect(inputElm.val()).toBe('50');
3190+
expect(scope.value).toBe(50);
3191+
});
3192+
3193+
3194+
it('should set element and model value to min if max is less than min', function() {
3195+
scope.min = 40;
3196+
var inputElm = helper.compileInput('<input type="range" ng-model="value" name="alias" max="{{max}}" min="{{min}}" />');
3197+
3198+
expect(inputElm.val()).toBe('50');
3199+
expect(scope.value).toBe(50);
3200+
3201+
scope.max = 20;
3202+
scope.$digest();
3203+
3204+
expect(inputElm.val()).toBe('40');
3205+
expect(scope.value).toBe(40);
3206+
});
31933207
});
3208+
31943209
}
31953210

31963211
});

0 commit comments

Comments
 (0)