@@ -63,7 +63,7 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
63
63
ctrl . select = select ;
64
64
ctrl . listEnter = onListEnter ;
65
65
ctrl . listLeave = onListLeave ;
66
- ctrl . mouseUp = onMouseup ;
66
+ ctrl . focusInput = focusInputElement ;
67
67
ctrl . getCurrentDisplayValue = getCurrentDisplayValue ;
68
68
ctrl . registerSelectedItemWatcher = registerSelectedItemWatcher ;
69
69
ctrl . unregisterSelectedItemWatcher = unregisterSelectedItemWatcher ;
@@ -103,6 +103,10 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
103
103
gatherElements ( ) ;
104
104
moveDropdown ( ) ;
105
105
106
+ // Touch devices often do not send a click event on tap. We still want to focus the input
107
+ // and open the options pop-up in these cases.
108
+ $element . on ( 'touchstart' , focusInputElement ) ;
109
+
106
110
// Forward all focus events to the input element when autofocus is enabled
107
111
if ( $scope . autofocus ) {
108
112
$element . on ( 'focus' , focusInputElement ) ;
@@ -366,12 +370,31 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
366
370
367
371
// event/change handlers
368
372
373
+ /**
374
+ * @param {Event } $event
375
+ */
376
+ function preventDefault ( $event ) {
377
+ $event . preventDefault ( ) ;
378
+ }
379
+
380
+ /**
381
+ * @param {Event } $event
382
+ */
383
+ function stopPropagation ( $event ) {
384
+ $event . stopPropagation ( ) ;
385
+ }
386
+
369
387
/**
370
388
* Handles changes to the `hidden` property.
371
- * @param {boolean } hidden
372
- * @param {boolean } oldHidden
389
+ * @param {boolean } hidden true to hide the options pop-up, false to show it.
390
+ * @param {boolean } oldHidden the previous value of hidden
373
391
*/
374
392
function handleHiddenChange ( hidden , oldHidden ) {
393
+ var scrollContainerElement ;
394
+
395
+ if ( elements ) {
396
+ scrollContainerElement = angular . element ( elements . scrollContainer ) ;
397
+ }
375
398
if ( ! hidden && oldHidden ) {
376
399
positionDropdown ( ) ;
377
400
@@ -380,13 +403,23 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
380
403
reportMessages ( true , ReportType . Count | ReportType . Selected ) ;
381
404
382
405
if ( elements ) {
383
- $mdUtil . disableScrollAround ( elements . ul ) ;
384
- enableWrapScroll = disableElementScrollEvents ( angular . element ( elements . wrap ) ) ;
385
- ctrl . documentElement . on ( 'click' , handleClickOutside ) ;
406
+ $mdUtil . disableScrollAround ( elements . scrollContainer ) ;
407
+ enableWrapScroll = disableElementScrollEvents ( elements . wrap ) ;
408
+ if ( $mdUtil . isIos ) {
409
+ ctrl . documentElement . on ( 'touchend' , handleTouchOutsidePanel ) ;
410
+ if ( scrollContainerElement ) {
411
+ scrollContainerElement . on ( 'touchstart touchmove touchend' , stopPropagation ) ;
412
+ }
413
+ }
386
414
$mdUtil . nextTick ( updateActiveOption ) ;
387
415
}
388
416
} else if ( hidden && ! oldHidden ) {
389
- ctrl . documentElement . off ( 'click' , handleClickOutside ) ;
417
+ if ( $mdUtil . isIos ) {
418
+ ctrl . documentElement . off ( 'touchend' , handleTouchOutsidePanel ) ;
419
+ if ( scrollContainerElement ) {
420
+ scrollContainerElement . off ( 'touchstart touchmove touchend' , stopPropagation ) ;
421
+ }
422
+ }
390
423
$mdUtil . enableScrolling ( ) ;
391
424
392
425
if ( enableWrapScroll ) {
@@ -397,29 +430,27 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
397
430
}
398
431
399
432
/**
400
- * Handling click events that bubble up to the document is required for closing the dropdown
401
- * panel on click outside of the panel on iOS.
433
+ * Handling touch events that bubble up to the document is required for closing the dropdown
434
+ * panel on touch outside of the options pop-up panel on iOS.
402
435
* @param {Event } $event
403
436
*/
404
- function handleClickOutside ( $event ) {
437
+ function handleTouchOutsidePanel ( $event ) {
405
438
ctrl . hidden = true ;
439
+ // iOS does not blur the pop-up for touches on the scroll mask, so we have to do it.
440
+ doBlur ( true ) ;
406
441
}
407
442
408
443
/**
409
- * Disables scrolling for a specific element
444
+ * Disables scrolling for a specific element.
445
+ * @param {!string|!DOMElement } element to disable scrolling
446
+ * @return {Function } function to call to re-enable scrolling for the element
410
447
*/
411
448
function disableElementScrollEvents ( element ) {
412
-
413
- function preventDefault ( e ) {
414
- e . preventDefault ( ) ;
415
- }
416
-
417
- element . on ( 'wheel' , preventDefault ) ;
418
- element . on ( 'touchmove' , preventDefault ) ;
449
+ var elementToDisable = angular . element ( element ) ;
450
+ elementToDisable . on ( 'wheel touchmove' , preventDefault ) ;
419
451
420
452
return function ( ) {
421
- element . off ( 'wheel' , preventDefault ) ;
422
- element . off ( 'touchmove' , preventDefault ) ;
453
+ elementToDisable . off ( 'wheel touchmove' , preventDefault ) ;
423
454
} ;
424
455
}
425
456
@@ -439,13 +470,6 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
439
470
ctrl . hidden = shouldHide ( ) ;
440
471
}
441
472
442
- /**
443
- * When the mouse button is released, send focus back to the input field.
444
- */
445
- function onMouseup ( ) {
446
- elements . input . focus ( ) ;
447
- }
448
-
449
473
/**
450
474
* Handles changes to the selected item.
451
475
* @param selectedItem
@@ -837,14 +861,14 @@ function MdAutocompleteCtrl ($scope, $element, $mdUtil, $mdConstant, $mdTheming,
837
861
* Defines a public property with a handler and a default value.
838
862
* @param {string } key
839
863
* @param {Function } handler function
840
- * @param {* } value default value
864
+ * @param {* } defaultValue default value
841
865
*/
842
- function defineProperty ( key , handler , value ) {
866
+ function defineProperty ( key , handler , defaultValue ) {
843
867
Object . defineProperty ( ctrl , key , {
844
- get : function ( ) { return value ; } ,
868
+ get : function ( ) { return defaultValue ; } ,
845
869
set : function ( newValue ) {
846
- var oldValue = value ;
847
- value = newValue ;
870
+ var oldValue = defaultValue ;
871
+ defaultValue = newValue ;
848
872
handler ( newValue , oldValue ) ;
849
873
}
850
874
} ) ;
0 commit comments