From ebd46197be1cabc4d7cc3c47b0b7241a235c3245 Mon Sep 17 00:00:00 2001 From: crisbeto Date: Tue, 20 Jun 2017 21:40:48 +0200 Subject: [PATCH] fix(autocomplete): not closing when tapping away on mobile Currently the autocomplete panel won't close when tapping away on iOS, because the browser doesn't fire the click event on anything that it doesn't consider clickable. These changes add a `touchend` listener that will handle the functionality on mobile. --- src/lib/autocomplete/autocomplete-trigger.ts | 6 ++++-- src/lib/autocomplete/autocomplete.spec.ts | 16 +++++++++++++++- 2 files changed, 19 insertions(+), 3 deletions(-) diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index 86cdbfbadd9c..ffee532f5328 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -211,7 +211,10 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy { /** Stream of clicks outside of the autocomplete panel. */ private get _outsideClickStream(): Observable { if (this._document) { - return Observable.fromEvent(this._document, 'click').filter((event: MouseEvent) => { + return Observable.merge( + Observable.fromEvent(this._document, 'click'), + Observable.fromEvent(this._document, 'touchend') + ).filter((event: MouseEvent | TouchEvent) => { const clickTarget = event.target as HTMLElement; const inputContainer = this._inputContainer ? this._inputContainer._elementRef.nativeElement : null; @@ -442,4 +445,3 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy { } } - diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index 422456f40bd4..cb0926192a2c 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -146,7 +146,7 @@ describe('MdAutocomplete', () => { }); })); - it('should close the panel when input loses focus', async(() => { + it('should close the panel when the user clicks away', async(() => { dispatchFakeEvent(input, 'focusin'); fixture.detectChanges(); @@ -160,6 +160,20 @@ describe('MdAutocomplete', () => { }); })); + it('should close the panel when the user taps away on a touch device', async(() => { + dispatchFakeEvent(input, 'focus'); + fixture.detectChanges(); + + fixture.whenStable().then(() => { + dispatchFakeEvent(document, 'touchend'); + + expect(fixture.componentInstance.trigger.panelOpen) + .toBe(false, `Expected tapping outside the panel to set its state to closed.`); + expect(overlayContainerElement.textContent) + .toEqual('', `Expected tapping outside the panel to close the panel.`); + }); + })); + it('should close the panel when an option is clicked', async(() => { dispatchFakeEvent(input, 'focusin'); fixture.detectChanges();