@@ -1497,7 +1497,7 @@ function createDateParser(regexp, mapping) {
14971497}
14981498
14991499function createDateInputType ( type , regexp , parseDate , format ) {
1500- return function dynamicDateInputType ( scope , element , attr , ctrl , $sniffer , $browser , $filter ) {
1500+ return function dynamicDateInputType ( scope , element , attr , ctrl , $sniffer , $browser , $filter , $parse ) {
15011501 badInputChecker ( scope , element , attr , ctrl , type ) ;
15021502 baseInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
15031503
@@ -1540,24 +1540,34 @@ function createDateInputType(type, regexp, parseDate, format) {
15401540 } ) ;
15411541
15421542 if ( isDefined ( attr . min ) || attr . ngMin ) {
1543- var minVal ;
1543+ var minVal = attr . min || $parse ( attr . ngMin ) ( scope ) ;
1544+ var parsedMinVal = parseObservedDateValue ( minVal ) ;
1545+
15441546 ctrl . $validators . min = function ( value ) {
1545- return ! isValidDate ( value ) || isUndefined ( minVal ) || parseDate ( value ) >= minVal ;
1547+ return ! isValidDate ( value ) || isUndefined ( parsedMinVal ) || parseDate ( value ) >= parsedMinVal ;
15461548 } ;
15471549 attr . $observe ( 'min' , function ( val ) {
1548- minVal = parseObservedDateValue ( val ) ;
1549- ctrl . $validate ( ) ;
1550+ if ( val !== minVal ) {
1551+ parsedMinVal = parseObservedDateValue ( val ) ;
1552+ minVal = val ;
1553+ ctrl . $validate ( ) ;
1554+ }
15501555 } ) ;
15511556 }
15521557
15531558 if ( isDefined ( attr . max ) || attr . ngMax ) {
1554- var maxVal ;
1559+ var maxVal = attr . max || $parse ( attr . ngMax ) ( scope ) ;
1560+ var parsedMaxVal = parseObservedDateValue ( maxVal ) ;
1561+
15551562 ctrl . $validators . max = function ( value ) {
1556- return ! isValidDate ( value ) || isUndefined ( maxVal ) || parseDate ( value ) <= maxVal ;
1563+ return ! isValidDate ( value ) || isUndefined ( parsedMaxVal ) || parseDate ( value ) <= parsedMaxVal ;
15571564 } ;
15581565 attr . $observe ( 'max' , function ( val ) {
1559- maxVal = parseObservedDateValue ( val ) ;
1560- ctrl . $validate ( ) ;
1566+ if ( val !== maxVal ) {
1567+ parsedMaxVal = parseObservedDateValue ( val ) ;
1568+ maxVal = val ;
1569+ ctrl . $validate ( ) ;
1570+ }
15611571 } ) ;
15621572 }
15631573
@@ -1709,50 +1719,68 @@ function isValidForStep(viewValue, stepBase, step) {
17091719 return ( value - stepBase ) % step === 0 ;
17101720}
17111721
1712- function numberInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
1722+ function numberInputType ( scope , element , attr , ctrl , $sniffer , $browser , $filter , $parse ) {
17131723 badInputChecker ( scope , element , attr , ctrl , 'number' ) ;
17141724 numberFormatterParser ( ctrl ) ;
17151725 baseInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
17161726
1717- var minVal ;
1718- var maxVal ;
1727+ var parsedMinVal ;
17191728
17201729 if ( isDefined ( attr . min ) || attr . ngMin ) {
1730+ var minVal = attr . min || $parse ( attr . ngMin ) ( scope ) ;
1731+ parsedMinVal = parseNumberAttrVal ( minVal ) ;
1732+
17211733 ctrl . $validators . min = function ( modelValue , viewValue ) {
1722- return ctrl . $isEmpty ( viewValue ) || isUndefined ( minVal ) || viewValue >= minVal ;
1734+ return ctrl . $isEmpty ( viewValue ) || isUndefined ( parsedMinVal ) || viewValue >= parsedMinVal ;
17231735 } ;
17241736
17251737 attr . $observe ( 'min' , function ( val ) {
1726- minVal = parseNumberAttrVal ( val ) ;
1727- // TODO(matsko): implement validateLater to reduce number of validations
1728- ctrl . $validate ( ) ;
1738+ if ( val !== minVal ) {
1739+ parsedMinVal = parseNumberAttrVal ( val ) ;
1740+ minVal = val ;
1741+ // TODO(matsko): implement validateLater to reduce number of validations
1742+ ctrl . $validate ( ) ;
1743+ }
17291744 } ) ;
17301745 }
17311746
17321747 if ( isDefined ( attr . max ) || attr . ngMax ) {
1748+ var maxVal = attr . max || $parse ( attr . ngMax ) ( scope ) ;
1749+ var parsedMaxVal = parseNumberAttrVal ( maxVal ) ;
1750+
17331751 ctrl . $validators . max = function ( modelValue , viewValue ) {
1734- return ctrl . $isEmpty ( viewValue ) || isUndefined ( maxVal ) || viewValue <= maxVal ;
1752+ return ctrl . $isEmpty ( viewValue ) || isUndefined ( parsedMaxVal ) || viewValue <= parsedMaxVal ;
17351753 } ;
17361754
17371755 attr . $observe ( 'max' , function ( val ) {
1738- maxVal = parseNumberAttrVal ( val ) ;
1739- // TODO(matsko): implement validateLater to reduce number of validations
1740- ctrl . $validate ( ) ;
1756+ if ( val !== maxVal ) {
1757+ parsedMaxVal = parseNumberAttrVal ( val ) ;
1758+ maxVal = val ;
1759+ // TODO(matsko): implement validateLater to reduce number of validations
1760+ ctrl . $validate ( ) ;
1761+ }
17411762 } ) ;
17421763 }
17431764
17441765 if ( isDefined ( attr . step ) || attr . ngStep ) {
1745- var stepVal ;
1766+ var stepVal = attr . step || $parse ( attr . ngStep ) ( scope ) ;
1767+ var parsedStepVal = parseNumberAttrVal ( stepVal ) ;
1768+
17461769 ctrl . $validators . step = function ( modelValue , viewValue ) {
1747- return ctrl . $isEmpty ( viewValue ) || isUndefined ( stepVal ) ||
1748- isValidForStep ( viewValue , minVal || 0 , stepVal ) ;
1770+ return ctrl . $isEmpty ( viewValue ) || isUndefined ( parsedStepVal ) ||
1771+ isValidForStep ( viewValue , parsedMinVal || 0 , parsedStepVal ) ;
17491772 } ;
17501773
17511774 attr . $observe ( 'step' , function ( val ) {
1752- stepVal = parseNumberAttrVal ( val ) ;
17531775 // TODO(matsko): implement validateLater to reduce number of validations
1754- ctrl . $validate ( ) ;
1776+ if ( val !== stepVal ) {
1777+ parsedStepVal = parseNumberAttrVal ( val ) ;
1778+ stepVal = val ;
1779+ ctrl . $validate ( ) ;
1780+ }
1781+
17551782 } ) ;
1783+
17561784 }
17571785}
17581786
@@ -1782,6 +1810,8 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
17821810 originalRender ;
17831811
17841812 if ( hasMinAttr ) {
1813+ minVal = parseNumberAttrVal ( attr . min ) ;
1814+
17851815 ctrl . $validators . min = supportsRange ?
17861816 // Since all browsers set the input to a valid value, we don't need to check validity
17871817 function noopMinValidator ( ) { return true ; } :
@@ -1794,6 +1824,8 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
17941824 }
17951825
17961826 if ( hasMaxAttr ) {
1827+ maxVal = parseNumberAttrVal ( attr . max ) ;
1828+
17971829 ctrl . $validators . max = supportsRange ?
17981830 // Since all browsers set the input to a valid value, we don't need to check validity
17991831 function noopMaxValidator ( ) { return true ; } :
@@ -1806,6 +1838,8 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
18061838 }
18071839
18081840 if ( hasStepAttr ) {
1841+ stepVal = parseNumberAttrVal ( attr . step ) ;
1842+
18091843 ctrl . $validators . step = supportsRange ?
18101844 function nativeStepValidator ( ) {
18111845 // Currently, only FF implements the spec on step change correctly (i.e. adjusting the
@@ -1827,7 +1861,13 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
18271861 // attribute value when the input is first rendered, so that the browser can adjust the
18281862 // input value based on the min/max value
18291863 element . attr ( htmlAttrName , attr [ htmlAttrName ] ) ;
1830- attr . $observe ( htmlAttrName , changeFn ) ;
1864+ var oldVal = attr [ htmlAttrName ] ;
1865+ attr . $observe ( htmlAttrName , function wrappedObserver ( val ) {
1866+ if ( val !== oldVal ) {
1867+ oldVal = val ;
1868+ changeFn ( val ) ;
1869+ }
1870+ } ) ;
18311871 }
18321872
18331873 function minChange ( val ) {
@@ -1881,11 +1921,11 @@ function rangeInputType(scope, element, attr, ctrl, $sniffer, $browser) {
18811921 }
18821922
18831923 // Some browsers don't adjust the input value correctly, but set the stepMismatch error
1884- if ( supportsRange && ctrl . $viewValue !== element . val ( ) ) {
1885- ctrl . $setViewValue ( element . val ( ) ) ;
1886- } else {
1924+ if ( ! supportsRange ) {
18871925 // TODO(matsko): implement validateLater to reduce number of validations
18881926 ctrl . $validate ( ) ;
1927+ } else if ( ctrl . $viewValue !== element . val ( ) ) {
1928+ ctrl . $setViewValue ( element . val ( ) ) ;
18891929 }
18901930 }
18911931}
0 commit comments