@@ -1037,19 +1037,13 @@ var inputType = {
1037
1037
* The model for the range input must always be a `Number`.
1038
1038
*
1039
1039
* IE9 and other browsers that do not support the `range` type fall back
1040
- * to a text input without any default values for `min`, `max` and `step`. Model binding,
1041
- * validation and number parsing are nevertheless supported.
1040
+ * to a text input. Model binding, validation and number parsing are nevertheless supported.
1042
1041
*
1043
1042
* Browsers that support range (latest Chrome, Safari, Firefox, Edge) treat `input[range]`
1044
1043
* in a way that never allows the input to hold an invalid value. That means:
1045
1044
* - any non-numerical value is set to `(max + min) / 2`.
1046
1045
* - any numerical value that is less than the current min val, or greater than the current max val
1047
1046
* is set to the min / max val respectively.
1048
- * - additionally, the current `step` is respected, so the nearest value that satisfies a step
1049
- * is used.
1050
- *
1051
- * See the [HTML Spec on input[type=range]](https://www.w3.org/TR/html5/forms.html#range-state-(type=range))
1052
- * for more info.
1053
1047
*
1054
1048
* This has the following consequences for Angular:
1055
1049
*
@@ -1062,30 +1056,23 @@ var inputType = {
1062
1056
* That means the model for range will immediately be set to `50` after `ngModel` has been
1063
1057
* initialized. It also means a range input can never have the required error.
1064
1058
*
1065
- * This does not only affect changes to the model value, but also to the values of the `min`,
1066
- * `max`, and `step` attributes. When these change in a way that will cause the browser to modify
1067
- * the input value, Angular will also update the model value.
1059
+ * This does not only affect changes to the model value, but also to the values of the `min` and
1060
+ * `max` attributes. When these change in a way that will cause the browser to modify the input value,
1061
+ * Angular will also update the model value.
1068
1062
*
1069
1063
* Automatic value adjustment also means that a range input element can never have the `required`,
1070
1064
* `min`, or `max` errors.
1071
1065
*
1072
- * However, `step` is currently only fully implemented by Firefox. Other browsers have problems
1073
- * when the step value changes dynamically - they do not adjust the element value correctly, but
1074
- * instead may set the `stepMismatch` error. If that's the case, the Angular will set the `step`
1075
- * error on the input, and set the model to `undefined`.
1076
- *
1077
- * Note that `input[range]` is not compatible with`ngMax`, `ngMin`, and `ngStep`, because they do
1078
- * not set the `min` and `max` attributes, which means that the browser won't automatically adjust
1079
- * the input value based on their values, and will always assume min = 0, max = 100, and step = 1.
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.
1080
1069
*
1081
1070
* @param {string } ngModel Assignable angular expression to data-bind to.
1082
1071
* @param {string= } name Property name of the form under which the control is published.
1083
1072
* @param {string= } min Sets the `min` validation to ensure that the value entered is greater
1084
1073
* than `min`. Can be interpolated.
1085
1074
* @param {string= } max Sets the `max` validation to ensure that the value entered is less than `max`.
1086
1075
* Can be interpolated.
1087
- * @param {string= } step Sets the `step` validation to ensure that the value entered matches the `step`
1088
- * Can be interpolated.
1089
1076
* @param {string= } ngChange Angular expression to be executed when the ngModel value changes due
1090
1077
* to user interaction with the input element.
1091
1078
*
@@ -1512,13 +1499,6 @@ function numberFormatterParser(ctrl) {
1512
1499
} ) ;
1513
1500
}
1514
1501
1515
- function parseNumberAttrVal ( val ) {
1516
- if ( isDefined ( val ) && ! isNumber ( val ) ) {
1517
- val = parseFloat ( val ) ;
1518
- }
1519
- return ! isNumberNaN ( val ) ? val : undefined ;
1520
- }
1521
-
1522
1502
function numberInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
1523
1503
badInputChecker ( scope , element , attr , ctrl ) ;
1524
1504
numberFormatterParser ( ctrl ) ;
@@ -1531,7 +1511,10 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1531
1511
} ;
1532
1512
1533
1513
attr . $observe ( 'min' , function ( val ) {
1534
- minVal = parseNumberAttrVal ( val ) ;
1514
+ if ( isDefined ( val ) && ! isNumber ( val ) ) {
1515
+ val = parseFloat ( val ) ;
1516
+ }
1517
+ minVal = isNumber ( val ) && ! isNaN ( val ) ? val : undefined ;
1535
1518
// TODO(matsko): implement validateLater to reduce number of validations
1536
1519
ctrl . $validate ( ) ;
1537
1520
} ) ;
@@ -1544,7 +1527,10 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1544
1527
} ;
1545
1528
1546
1529
attr . $observe ( 'max' , function ( val ) {
1547
- maxVal = parseNumberAttrVal ( val ) ;
1530
+ if ( isDefined ( val ) && ! isNumber ( val ) ) {
1531
+ val = parseFloat ( val ) ;
1532
+ }
1533
+ maxVal = isNumber ( val ) && ! isNaN ( val ) ? val : undefined ;
1548
1534
// TODO(matsko): implement validateLater to reduce number of validations
1549
1535
ctrl . $validate ( ) ;
1550
1536
} ) ;
@@ -1559,11 +1545,9 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1559
1545
var supportsRange = ctrl . $$hasNativeValidators && element [ 0 ] . type === 'range' ,
1560
1546
minVal = supportsRange ? 0 : undefined ,
1561
1547
maxVal = supportsRange ? 100 : undefined ,
1562
- stepVal = supportsRange ? 1 : undefined ,
1563
1548
validity = element [ 0 ] . validity ,
1564
1549
hasMinAttr = isDefined ( attr . min ) ,
1565
- hasMaxAttr = isDefined ( attr . max ) ,
1566
- hasStepAttr = isDefined ( attr . step ) ;
1550
+ hasMaxAttr = isDefined ( attr . max ) ;
1567
1551
1568
1552
var originalRender = ctrl . $render ;
1569
1553
@@ -1580,7 +1564,7 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1580
1564
ctrl . $validators . min = supportsRange ?
1581
1565
// Since all browsers set the input to a valid value, we don't need to check validity
1582
1566
function noopMinValidator ( ) { return true ; } :
1583
- // non-support browsers validate the min val
1567
+ // non-support browsers validate the range
1584
1568
function minValidator ( modelValue , viewValue ) {
1585
1569
return ctrl . $isEmpty ( viewValue ) || isUndefined ( minVal ) || viewValue >= minVal ;
1586
1570
} ;
@@ -1592,40 +1576,28 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1592
1576
ctrl . $validators . max = supportsRange ?
1593
1577
// Since all browsers set the input to a valid value, we don't need to check validity
1594
1578
function noopMaxValidator ( ) { return true ; } :
1595
- // non-support browsers validate the max val
1579
+ // ngMax doesn't set the max attr, so the browser doesn't adjust the input value as setting max would
1596
1580
function maxValidator ( modelValue , viewValue ) {
1597
1581
return ctrl . $isEmpty ( viewValue ) || isUndefined ( maxVal ) || viewValue <= maxVal ;
1598
1582
} ;
1599
1583
1600
1584
setInitialValueAndObserver ( 'max' , maxChange ) ;
1601
1585
}
1602
1586
1603
- if ( hasStepAttr ) {
1604
- ctrl . $validators . step = supportsRange ?
1605
- function nativeStepValidator ( ) {
1606
- // Currently, only FF implements the spec on step change correctly (i.e. adjusting the
1607
- // input element value to a valid value). It's possible that other browsers set the stepMismatch
1608
- // validity error instead, so we can at least report an error in that case.
1609
- return ! validity . stepMismatch ;
1610
- } :
1611
- // ngStep doesn't set the setp attr, so the browser doesn't adjust the input value as setting step would
1612
- function stepValidator ( modelValue , viewValue ) {
1613
- return ctrl . $isEmpty ( viewValue ) || isUndefined ( stepVal ) || viewValue % stepVal === 0 ;
1614
- } ;
1615
-
1616
- setInitialValueAndObserver ( 'step' , stepChange ) ;
1617
- }
1618
-
1619
1587
function setInitialValueAndObserver ( htmlAttrName , changeFn ) {
1620
1588
// interpolated attributes set the attribute value only after a digest, but we need the
1621
1589
// attribute value when the input is first rendered, so that the browser can adjust the
1622
1590
// input value based on the min/max value
1623
1591
element . attr ( htmlAttrName , attr [ htmlAttrName ] ) ;
1592
+
1624
1593
attr . $observe ( htmlAttrName , changeFn ) ;
1625
1594
}
1626
1595
1627
1596
function minChange ( val ) {
1628
- minVal = parseNumberAttrVal ( val ) ;
1597
+ if ( isDefined ( val ) && ! isNumber ( val ) ) {
1598
+ val = parseFloat ( val ) ;
1599
+ }
1600
+ minVal = isNumber ( val ) && ! isNaN ( val ) ? val : undefined ;
1629
1601
// ignore changes before model is initialized
1630
1602
if ( isNumberNaN ( ctrl . $modelValue ) ) {
1631
1603
return ;
@@ -1646,7 +1618,10 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1646
1618
}
1647
1619
1648
1620
function maxChange ( val ) {
1649
- maxVal = parseNumberAttrVal ( val ) ;
1621
+ if ( isDefined ( val ) && ! isNumber ( val ) ) {
1622
+ val = parseFloat ( val ) ;
1623
+ }
1624
+ maxVal = isNumber ( val ) && ! isNaN ( val ) ? val : undefined ;
1650
1625
// ignore changes before model is initialized
1651
1626
if ( isNumberNaN ( ctrl . $modelValue ) ) {
1652
1627
return ;
@@ -1667,21 +1642,6 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
1667
1642
}
1668
1643
}
1669
1644
1670
- function stepChange ( val ) {
1671
- stepVal = parseNumberAttrVal ( val ) ;
1672
- // ignore changes before model is initialized
1673
- if ( isNumberNaN ( ctrl . $modelValue ) ) {
1674
- return ;
1675
- }
1676
-
1677
- // Some browsers don't adjust the input value correctly, but set the stepMismatch error
1678
- if ( supportsRange && ctrl . $viewValue !== element . val ( ) ) {
1679
- ctrl . $setViewValue ( element . val ( ) ) ;
1680
- } else {
1681
- // TODO(matsko): implement validateLater to reduce number of validations
1682
- ctrl . $validate ( ) ;
1683
- }
1684
- }
1685
1645
}
1686
1646
1687
1647
function urlInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
0 commit comments