@@ -367,12 +367,43 @@ function isEmpty(value) {
367
367
}
368
368
369
369
370
- function textInputType ( scope , element , attr , ctrl ) {
371
- element . bind ( 'blur' , function ( ) {
372
- scope . $apply ( function ( ) {
373
- ctrl . $setViewValue ( trim ( element . val ( ) ) ) ;
370
+ function textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
371
+
372
+ var listener = function ( ) {
373
+ var value = trim ( element . val ( ) ) ;
374
+
375
+ if ( ctrl . $viewValue !== value ) {
376
+ scope . $apply ( function ( ) {
377
+ ctrl . $setViewValue ( value ) ;
378
+ } ) ;
379
+ }
380
+ } ;
381
+
382
+ // if the browser does support "input" event, we are fine
383
+ if ( $sniffer . hasEvent ( 'input' ) ) {
384
+ element . bind ( 'input' , listener ) ;
385
+ } else {
386
+ var timeout ;
387
+
388
+ element . bind ( 'keydown' , function ( event ) {
389
+ var key = event . keyCode ;
390
+
391
+ // ignore
392
+ // command modifiers arrows
393
+ if ( key === 91 || ( 15 < key && key < 19 ) || ( 37 <= key && key <= 40 ) ) return ;
394
+
395
+ if ( ! timeout ) {
396
+ timeout = $browser . defer ( function ( ) {
397
+ listener ( ) ;
398
+ timeout = null ;
399
+ } ) ;
400
+ }
374
401
} ) ;
375
- } ) ;
402
+
403
+ // if user paste into input using mouse, we need "change" event to catch it
404
+ element . bind ( 'change' , listener ) ;
405
+ }
406
+
376
407
377
408
ctrl . $render = function ( ) {
378
409
element . val ( isEmpty ( ctrl . $viewValue ) ? '' : ctrl . $viewValue ) ;
@@ -448,8 +479,8 @@ function textInputType(scope, element, attr, ctrl) {
448
479
}
449
480
} ;
450
481
451
- function numberInputType ( scope , element , attr , ctrl ) {
452
- textInputType ( scope , element , attr , ctrl ) ;
482
+ function numberInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
483
+ textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
453
484
454
485
ctrl . $parsers . push ( function ( value ) {
455
486
var empty = isEmpty ( value ) ;
@@ -510,8 +541,8 @@ function numberInputType(scope, element, attr, ctrl) {
510
541
} ) ;
511
542
}
512
543
513
- function urlInputType ( scope , element , attr , ctrl ) {
514
- textInputType ( scope , element , attr , ctrl ) ;
544
+ function urlInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
545
+ textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
515
546
516
547
var urlValidator = function ( value ) {
517
548
if ( isEmpty ( value ) || URL_REGEXP . test ( value ) ) {
@@ -527,8 +558,8 @@ function urlInputType(scope, element, attr, ctrl) {
527
558
ctrl . $parsers . push ( urlValidator ) ;
528
559
}
529
560
530
- function emailInputType ( scope , element , attr , ctrl ) {
531
- textInputType ( scope , element , attr , ctrl ) ;
561
+ function emailInputType ( scope , element , attr , ctrl , $sniffer , $browser ) {
562
+ textInputType ( scope , element , attr , ctrl , $sniffer , $browser ) ;
532
563
533
564
var emailValidator = function ( value ) {
534
565
if ( isEmpty ( value ) || EMAIL_REGEXP . test ( value ) ) {
@@ -709,13 +740,14 @@ function checkboxInputType(scope, element, attr, ctrl) {
709
740
</doc:scenario>
710
741
</doc:example>
711
742
*/
712
- var inputDirective = [ function ( ) {
743
+ var inputDirective = [ '$browser' , '$sniffer' , function ( $browser , $sniffer ) {
713
744
return {
714
745
restrict : 'E' ,
715
746
require : '?ngModel' ,
716
747
link : function ( scope , element , attr , ctrl ) {
717
748
if ( ctrl ) {
718
- ( inputType [ lowercase ( attr . type ) ] || inputType . text ) ( scope , element , attr , ctrl ) ;
749
+ ( inputType [ lowercase ( attr . type ) ] || inputType . text ) ( scope , element , attr , ctrl , $sniffer ,
750
+ $browser ) ;
719
751
}
720
752
}
721
753
} ;
@@ -1004,69 +1036,6 @@ var ngChangeDirective = valueFn({
1004
1036
} ) ;
1005
1037
1006
1038
1007
- /**
1008
- * @ngdoc directive
1009
- * @name angular.module.ng.$compileProvider.directive.ng-model-instant
1010
- *
1011
- * @element input
1012
- *
1013
- * @description
1014
- * By default, Angular udpates the model only on `blur` event - when the input looses focus.
1015
- * If you want to update after every key stroke, use `ng-model-instant`.
1016
- *
1017
- * @example
1018
- * <doc:example>
1019
- * <doc:source>
1020
- * First name: <input type="text" ng-model="firstName" /><br />
1021
- * Last name: <input type="text" ng-model="lastName" ng-model-instant /><br />
1022
- *
1023
- * First name ({{firstName}}) is only updated on `blur` event, but the last name ({{lastName}})
1024
- * is updated immediately, because of using `ng-model-instant`.
1025
- * </doc:source>
1026
- * <doc:scenario>
1027
- * it('should update first name on blur', function() {
1028
- * input('firstName').enter('santa', 'blur');
1029
- * expect(binding('firstName')).toEqual('santa');
1030
- * });
1031
- *
1032
- * it('should update last name immediately', function() {
1033
- * input('lastName').enter('santa', 'keydown');
1034
- * expect(binding('lastName')).toEqual('santa');
1035
- * });
1036
- * </doc:scenario>
1037
- * </doc:example>
1038
- */
1039
- var ngModelInstantDirective = [ '$browser' , function ( $browser ) {
1040
- return {
1041
- require : 'ngModel' ,
1042
- link : function ( scope , element , attr , ctrl ) {
1043
- var handler = function ( ) {
1044
- scope . $apply ( function ( ) {
1045
- ctrl . $setViewValue ( trim ( element . val ( ) ) ) ;
1046
- } ) ;
1047
- } ;
1048
-
1049
- var timeout ;
1050
- element . bind ( 'keydown' , function ( event ) {
1051
- var key = event . keyCode ;
1052
-
1053
- // command modifiers arrows
1054
- if ( key === 91 || ( 15 < key && key < 19 ) || ( 37 <= key && key <= 40 ) ) return ;
1055
-
1056
- if ( ! timeout ) {
1057
- timeout = $browser . defer ( function ( ) {
1058
- handler ( ) ;
1059
- timeout = null ;
1060
- } ) ;
1061
- }
1062
- } ) ;
1063
-
1064
- element . bind ( 'change input' , handler ) ;
1065
- }
1066
- } ;
1067
- } ] ;
1068
-
1069
-
1070
1039
var requiredDirective = [ function ( ) {
1071
1040
return {
1072
1041
require : '?ngModel' ,
0 commit comments