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

Commit aa60491

Browse files
revert: fix(input[range]): correctly handle min/max; remove ngMin/ngMax support
This reverts commit b78539b
1 parent 5b633d8 commit aa60491

File tree

3 files changed

+149
-165
lines changed

3 files changed

+149
-165
lines changed

src/ng/directive/input.js

+51-49
Original file line numberDiff line numberDiff line change
@@ -1061,18 +1061,23 @@ var inputType = {
10611061
* Angular will also update the model value.
10621062
*
10631063
* Automatic value adjustment also means that a range input element can never have the `required`,
1064-
* `min`, or `max` errors.
1065-
*
1066-
* Note that `input[range]` is not compatible with`ngMax` and `ngMin`, because they do not set the
1067-
* `min` and `max` attributes, which means that the browser won't automatically adjust the input
1068-
* value based on their values, and will always assume min = 0 and max = 100.
1064+
* `min`, or `max` errors, except when using `ngMax` and `ngMin`, which are not affected by automatic
1065+
* value adjustment, because they do not set the `min` and `max` attributes.
10691066
*
10701067
* @param {string} ngModel Assignable angular expression to data-bind to.
10711068
* @param {string=} name Property name of the form under which the control is published.
10721069
* @param {string=} min Sets the `min` validation to ensure that the value entered is greater
10731070
* than `min`. Can be interpolated.
10741071
* @param {string=} max Sets the `max` validation to ensure that the value entered is less than `max`.
10751072
* Can be interpolated.
1073+
* @param {string=} ngMin Takes an expression. Sets the `min` validation to ensure that the value
1074+
* entered is greater than `min`. Does not set the `min` attribute and therefore
1075+
* adds no native HTML5 validation. It also means the browser won't adjust the
1076+
* element value in case `min` is greater than the current value.
1077+
* @param {string=} ngMax Takes an expression. Sets the `max` validation to ensure that the value
1078+
* entered is less than `max`. Does not set the `max` attribute and therefore
1079+
* adds no native HTML5 validation. It also means the browser won't adjust the
1080+
* element value in case `max` is less than the current value.
10761081
* @param {string=} ngChange Angular expression to be executed when the ngModel value changes due
10771082
* to user interaction with the input element.
10781083
*
@@ -1542,12 +1547,10 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15421547
numberFormatterParser(ctrl);
15431548
baseInputType(scope, element, attr, ctrl, $sniffer, $browser);
15441549

1545-
var supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',
1546-
minVal = supportsRange ? 0 : undefined,
1547-
maxVal = supportsRange ? 100 : undefined,
1548-
validity = element[0].validity,
1549-
hasMinAttr = isDefined(attr.min),
1550-
hasMaxAttr = isDefined(attr.max);
1550+
var minVal = 0,
1551+
maxVal = 100,
1552+
supportsRange = ctrl.$$hasNativeValidators && element[0].type === 'range',
1553+
validity = element[0].validity;
15511554

15521555
var originalRender = ctrl.$render;
15531556

@@ -1560,39 +1563,6 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
15601563
} :
15611564
originalRender;
15621565

1563-
if (hasMinAttr) {
1564-
ctrl.$validators.min = supportsRange ?
1565-
// Since all browsers set the input to a valid value, we don't need to check validity
1566-
function noopMinValidator() { return true; } :
1567-
// non-support browsers validate the range
1568-
function minValidator(modelValue, viewValue) {
1569-
return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;
1570-
};
1571-
1572-
setInitialValueAndObserver('min', minChange);
1573-
}
1574-
1575-
if (hasMaxAttr) {
1576-
ctrl.$validators.max = supportsRange ?
1577-
// Since all browsers set the input to a valid value, we don't need to check validity
1578-
function noopMaxValidator() { return true; } :
1579-
// ngMax doesn't set the max attr, so the browser doesn't adjust the input value as setting max would
1580-
function maxValidator(modelValue, viewValue) {
1581-
return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;
1582-
};
1583-
1584-
setInitialValueAndObserver('max', maxChange);
1585-
}
1586-
1587-
function setInitialValueAndObserver(htmlAttrName, changeFn) {
1588-
// interpolated attributes set the attribute value only after a digest, but we need the
1589-
// attribute value when the input is first rendered, so that the browser can adjust the
1590-
// input value based on the min/max value
1591-
element.attr(htmlAttrName, attr[htmlAttrName]);
1592-
1593-
attr.$observe(htmlAttrName, changeFn);
1594-
}
1595-
15961566
function minChange(val) {
15971567
if (isDefined(val) && !isNumber(val)) {
15981568
val = parseFloat(val);
@@ -1603,12 +1573,12 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16031573
return;
16041574
}
16051575

1606-
if (supportsRange) {
1576+
if (supportsRange && minAttrType === 'min') {
16071577
var elVal = element.val();
16081578
// IE11 doesn't set the el val correctly if the minVal is greater than the element value
16091579
if (minVal > elVal) {
1580+
element.val(minVal);
16101581
elVal = minVal;
1611-
element.val(elVal);
16121582
}
16131583
ctrl.$setViewValue(elVal);
16141584
} else {
@@ -1617,6 +1587,23 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16171587
}
16181588
}
16191589

1590+
var minAttrType = isDefined(attr.ngMin) ? 'ngMin' : isDefined(attr.min) ? 'min' : false;
1591+
if (minAttrType) {
1592+
ctrl.$validators.min = isDefined(attr.min) && supportsRange ?
1593+
function noopMinValidator(value) {
1594+
// Since all browsers set the input to a valid value, we don't need to check validity
1595+
return true;
1596+
} :
1597+
// ngMin doesn't set the min attr, so the browser doesn't adjust the input value as setting min would
1598+
function minValidator(modelValue, viewValue) {
1599+
return ctrl.$isEmpty(viewValue) || isUndefined(minVal) || viewValue >= minVal;
1600+
};
1601+
1602+
// Assign minVal when the directive is linked. This won't run the validators as the model isn't ready yet
1603+
minChange(attr.min);
1604+
attr.$observe('min', minChange);
1605+
}
1606+
16201607
function maxChange(val) {
16211608
if (isDefined(val) && !isNumber(val)) {
16221609
val = parseFloat(val);
@@ -1627,20 +1614,35 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
16271614
return;
16281615
}
16291616

1630-
if (supportsRange) {
1617+
if (supportsRange && maxAttrType === 'max') {
16311618
var elVal = element.val();
16321619
// IE11 doesn't set the el val correctly if the maxVal is less than the element value
16331620
if (maxVal < elVal) {
16341621
element.val(maxVal);
1635-
// IE11 and Chrome don't set the value to the minVal when max < min
1636-
elVal = maxVal < minVal ? minVal : maxVal;
1622+
elVal = minVal;
16371623
}
16381624
ctrl.$setViewValue(elVal);
16391625
} else {
16401626
// TODO(matsko): implement validateLater to reduce number of validations
16411627
ctrl.$validate();
16421628
}
16431629
}
1630+
var maxAttrType = isDefined(attr.max) ? 'max' : attr.ngMax ? 'ngMax' : false;
1631+
if (maxAttrType) {
1632+
ctrl.$validators.max = isDefined(attr.max) && supportsRange ?
1633+
function noopMaxValidator() {
1634+
// Since all browsers set the input to a valid value, we don't need to check validity
1635+
return true;
1636+
} :
1637+
// ngMax doesn't set the max attr, so the browser doesn't adjust the input value as setting max would
1638+
function maxValidator(modelValue, viewValue) {
1639+
return ctrl.$isEmpty(viewValue) || isUndefined(maxVal) || viewValue <= maxVal;
1640+
};
1641+
1642+
// Assign maxVal when the directive is linked. This won't run the validators as the model isn't ready yet
1643+
maxChange(attr.max);
1644+
attr.$observe('max', maxChange);
1645+
}
16441646

16451647
}
16461648

0 commit comments

Comments
 (0)