@@ -388,6 +388,13 @@ function isEmpty(value) {
388
388
return isUndefined ( value ) || value === '' || value === null || value !== value ;
389
389
}
390
390
391
+ function validityChanged ( ctrl , element ) {
392
+ return ctrl . $checkValidity && ! equals ( ctrl . $validityState , element . prop ( 'validity' ) ) ;
393
+ }
394
+
395
+ function isBadInput ( ctrl ) {
396
+ return ctrl . $validityState && ctrl . $validityState . badInput ;
397
+ }
391
398
392
399
function textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
393
400
@@ -401,7 +408,7 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
401
408
value = trim ( value ) ;
402
409
}
403
410
404
- if ( ctrl . $viewValue !== value ) {
411
+ if ( ctrl . $viewValue !== value || validityChanged ( ctrl , element ) ) {
405
412
scope . $apply ( function ( ) {
406
413
ctrl . $setViewValue ( value ) ;
407
414
} ) ;
@@ -522,12 +529,21 @@ function textInputType(scope, element, attr, ctrl, $sniffer, $browser) {
522
529
}
523
530
}
524
531
532
+ function numberIsBadInput ( ctrl ) {
533
+ if ( ! isEmpty ( ctrl . $viewValue ) && NUMBER_REGEXP . test ( ctrl . $viewValue ) ) {
534
+ return false ;
535
+ }
536
+ return ctrl . $validityState && ctrl . $validityState . badInput ;
537
+ }
538
+
539
+
525
540
function numberInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
541
+ ctrl . $checkValidity = true ;
526
542
textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
527
543
528
544
ctrl . $parsers . push ( function ( value ) {
529
545
var empty = isEmpty ( value ) ;
530
- if ( empty || NUMBER_REGEXP . test ( value ) ) {
546
+ if ( ! numberIsBadInput ( ctrl ) && ( empty || NUMBER_REGEXP . test ( value ) ) ) {
531
547
ctrl . $setValidity ( 'number' , true ) ;
532
548
return value === '' ? null : ( empty ? value : parseFloat ( value ) ) ;
533
549
} else {
@@ -546,7 +562,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
546
562
if ( ! isEmpty ( value ) && value < min ) {
547
563
ctrl . $setValidity ( 'min' , false ) ;
548
564
return undefined ;
549
- } else {
565
+ } else if ( ! isEmpty ( value ) ) {
550
566
ctrl . $setValidity ( 'min' , true ) ;
551
567
return value ;
552
568
}
@@ -562,7 +578,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
562
578
if ( ! isEmpty ( value ) && value > max ) {
563
579
ctrl . $setValidity ( 'max' , false ) ;
564
580
return undefined ;
565
- } else {
581
+ } else if ( ! isEmpty ( value ) ) {
566
582
ctrl . $setValidity ( 'max' , true ) ;
567
583
return value ;
568
584
}
@@ -574,7 +590,7 @@ function numberInputType(scope, element, attr, ctrl, $sniffer, $browser) {
574
590
575
591
ctrl . $formatters . push ( function ( value ) {
576
592
577
- if ( isEmpty ( value ) || isNumber ( value ) ) {
593
+ if ( ! isBadInput ( ctrl ) && ( isEmpty ( value ) || isNumber ( value ) ) ) {
578
594
ctrl . $setValidity ( 'number' , true ) ;
579
595
return value ;
580
596
} else {
@@ -972,6 +988,7 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
972
988
this . $valid = true ;
973
989
this . $invalid = false ;
974
990
this . $name = $attr . name ;
991
+ this . $validityState = copy ( $element . prop ( 'validity' ) ) ;
975
992
976
993
var ngModelGet = $parse ( $attr . ngModel ) ,
977
994
ngModelSet = ngModelGet . assign ;
@@ -1116,15 +1133,17 @@ var NgModelController = ['$scope', '$exceptionHandler', '$attrs', '$element', '$
1116
1133
var ctrl = this ;
1117
1134
1118
1135
$scope . $watch ( function ngModelWatch ( ) {
1119
- var value = ngModelGet ( $scope ) ;
1136
+ var value = ngModelGet ( $scope ) , validity = $element . prop ( 'validity' ) ;
1120
1137
1121
1138
// if scope model value and ngModel value are out of sync
1122
- if ( ctrl . $modelValue !== value ) {
1139
+ if ( ctrl . $modelValue !== value ||
1140
+ ( ctrl . $checkValidity && ! equals ( validity , ctrl . $validityState ) ) ) {
1123
1141
1124
1142
var formatters = ctrl . $formatters ,
1125
1143
idx = formatters . length ;
1126
1144
1127
1145
ctrl . $modelValue = value ;
1146
+ ctrl . $validityState = ctrl . $checkValidity && copy ( validity ) ;
1128
1147
while ( idx -- ) {
1129
1148
value = formatters [ idx ] ( value ) ;
1130
1149
}
0 commit comments