Skip to content

Commit 47ecc3d

Browse files
committed
fix(autocomplete): unable to click to select items in IE
* Fixes being unable to select autocomplete items by clicking in IE. This was due to IE not setting the `event.relatedTarget` for blur events. * Fixes potential issue if the user uses `mat-option`, instead of `md-option`.
1 parent d1abc9e commit 47ecc3d

File tree

4 files changed

+18
-10
lines changed

4 files changed

+18
-10
lines changed

src/lib/autocomplete/autocomplete-trigger.ts

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -58,8 +58,8 @@ export const MD_AUTOCOMPLETE_VALUE_ACCESSOR: any = {
5858
'[attr.aria-expanded]': 'panelOpen.toString()',
5959
'[attr.aria-owns]': 'autocomplete?.id',
6060
'(focus)': 'openPanel()',
61-
'(blur)': '_handleBlur($event.relatedTarget?.tagName)',
6261
'(input)': '_handleInput($event)',
62+
'(focusout)': '_handleFocusOut($event)',
6363
'(keydown)': '_handleKeydown($event)',
6464
},
6565
providers: [MD_AUTOCOMPLETE_VALUE_ACCESSOR]
@@ -220,11 +220,17 @@ export class MdAutocompleteTrigger implements ControlValueAccessor, OnDestroy {
220220
}
221221
}
222222

223-
_handleBlur(newlyFocusedTag: string): void {
223+
/**
224+
* Handles the input element losing focus. Note that this should be handled on `focusout`,
225+
* instead of `blur`, because IE doesn't set the `relatedTarget` for blur events.
226+
*/
227+
_handleFocusOut(event: FocusEvent): void {
228+
const relatedTarget = event.relatedTarget as HTMLElement;
229+
224230
this._onTouched();
225231

226-
// Only emit blur event if the new focus is *not* on an option.
227-
if (newlyFocusedTag !== 'MD-OPTION') {
232+
// Only emit blur event if the new focus is *not* on an element inside the panel.
233+
if (relatedTarget && !this._overlayRef.overlayElement.contains(relatedTarget)) {
228234
this._blurStream.next(null);
229235
}
230236
}

src/lib/autocomplete/autocomplete.spec.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ describe('MdAutocomplete', () => {
9696
fixture.detectChanges();
9797

9898
fixture.whenStable().then(() => {
99-
dispatchFakeEvent(input, 'blur');
99+
dispatchFakeEvent(input, 'focusout', { relatedTarget: document.body });
100100
fixture.detectChanges();
101101

102102
expect(fixture.componentInstance.trigger.panelOpen)
@@ -469,7 +469,7 @@ describe('MdAutocomplete', () => {
469469
expect(fixture.componentInstance.stateCtrl.touched)
470470
.toBe(false, `Expected control to start out untouched.`);
471471

472-
dispatchFakeEvent(input, 'blur');
472+
dispatchFakeEvent(input, 'focusout');
473473
fixture.detectChanges();
474474

475475
expect(fixture.componentInstance.stateCtrl.touched)

src/lib/core/testing/dispatch-events.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,8 +5,8 @@ import {
55
} from './event-objects';
66

77
/** Shorthand to dispatch a fake event on a specified node. */
8-
export function dispatchFakeEvent(node: Node, type: string) {
9-
node.dispatchEvent(createFakeEvent(type));
8+
export function dispatchFakeEvent(node: Node, type: string, eventProps?: any) {
9+
node.dispatchEvent(createFakeEvent(type, eventProps));
1010
}
1111

1212
/** Shorthand to dispatch a keyboard event with a specified key code. */

src/lib/core/testing/event-objects.ts

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,5 @@
1+
import {extendObject} from '../util/object-extend';
2+
13
/** Creates a browser MouseEvent with the specified options. */
24
export function createMouseEvent(type: string, x = 0, y = 0) {
35
let event = document.createEvent('MouseEvent');
@@ -39,8 +41,8 @@ export function createKeyboardEvent(type: string, keyCode: number) {
3941
}
4042

4143
/** Creates a fake event object with any desired event type. */
42-
export function createFakeEvent(type: string) {
43-
let event = document.createEvent('Event');
44+
export function createFakeEvent(type: string, eventProps?: any) {
45+
let event = extendObject(document.createEvent('Event'), eventProps);
4446
event.initEvent(type, true, true);
4547
return event;
4648
}

0 commit comments

Comments
 (0)