diff --git a/src/lib/autocomplete/autocomplete-trigger.ts b/src/lib/autocomplete/autocomplete-trigger.ts index f019c0196799..0c4a327943e4 100644 --- a/src/lib/autocomplete/autocomplete-trigger.ts +++ b/src/lib/autocomplete/autocomplete-trigger.ts @@ -63,13 +63,13 @@ export const MD_AUTOCOMPLETE_VALUE_ACCESSOR: any = { */ export function getMdAutocompleteMissingPanelError(): Error { return Error('Attempting to open an undefined instance of `md-autocomplete`. ' + - 'Make sure that the id passed to the `mdAutocomplete` is correct and that ' + - 'you\'re attempting to open it after the ngAfterContentInit hook.'); + 'Make sure that the id passed to the `mdAutocomplete` is correct and that ' + + 'you\'re attempting to open it after the ngAfterContentInit hook.'); } @Directive({ selector: 'input[mdAutocomplete], input[matAutocomplete],' + - 'textarea[mdAutocomplete], textarea[matAutocomplete]', + 'textarea[mdAutocomplete], textarea[matAutocomplete]', host: { 'role': 'combobox', 'autocomplete': 'off', @@ -78,7 +78,9 @@ export function getMdAutocompleteMissingPanelError(): Error { '[attr.aria-activedescendant]': 'activeOption?.id', '[attr.aria-expanded]': 'panelOpen.toString()', '[attr.aria-owns]': 'autocomplete?.id', - '(focus)': 'openPanel()', + // Note: we use `focusin`, as opposed to `focus`, in order to open the panel + // a little earlier. This avoids issues where IE delays the focusing of the input. + '(focusin)': 'openPanel()', '(input)': '_handleInput($event)', '(blur)': '_onTouched()', '(keydown)': '_handleKeydown($event)', diff --git a/src/lib/autocomplete/autocomplete.spec.ts b/src/lib/autocomplete/autocomplete.spec.ts index f3e730346d9a..25538b1213de 100644 --- a/src/lib/autocomplete/autocomplete.spec.ts +++ b/src/lib/autocomplete/autocomplete.spec.ts @@ -101,7 +101,7 @@ describe('MdAutocomplete', () => { expect(fixture.componentInstance.trigger.panelOpen) .toBe(false, `Expected panel state to start out closed.`); - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -147,7 +147,7 @@ describe('MdAutocomplete', () => { })); it('should close the panel when input loses focus', async(() => { - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -161,7 +161,7 @@ describe('MdAutocomplete', () => { })); it('should close the panel when an option is clicked', async(() => { - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -177,7 +177,7 @@ describe('MdAutocomplete', () => { })); it('should close the panel when a newly created option is clicked', async(() => { - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.detectChanges(); fixture.whenStable().then(() => { @@ -222,7 +222,7 @@ describe('MdAutocomplete', () => { }); it('should hide the panel when the options list is empty', async(() => { - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -1127,7 +1127,7 @@ describe('MdAutocomplete', () => { fixture.detectChanges(); const input = fixture.debugElement.query(By.css('input')).nativeElement; - dispatchFakeEvent(input, 'focus'); + dispatchFakeEvent(input, 'focusin'); fixture.whenStable().then(() => { fixture.detectChanges(); @@ -1226,7 +1226,7 @@ describe('MdAutocomplete', () => { let fixture = TestBed.createComponent(AutocompleteWithOnPushDelay); fixture.detectChanges(); - dispatchFakeEvent(fixture.debugElement.query(By.css('input')).nativeElement, 'focus'); + dispatchFakeEvent(fixture.debugElement.query(By.css('input')).nativeElement, 'focusin'); tick(1000); fixture.detectChanges();