Skip to content

Commit

Permalink
fix(autocomplete): restore focus after emitting option selected event (
Browse files Browse the repository at this point in the history
…#18707)

Currently we restore focus to the input and then we emit the change event, but we have a report that it may be making some use cases more difficult. From what I can tell, this shouldn't have much of an impact on existing users so these changes swap the order so that the focus event is last.

Fixes #18650.

(cherry picked from commit 7409bd6)
  • Loading branch information
crisbeto authored and andrewseguin committed Jan 18, 2022
1 parent 109d5a1 commit 402c07b
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 5 deletions.
12 changes: 7 additions & 5 deletions src/material/autocomplete/autocomplete-trigger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -556,12 +556,14 @@ export abstract class _MatAutocompleteTriggerBase
* stemmed from the user.
*/
private _setValueAndClose(event: MatOptionSelectionChange | null): void {
if (event && event.source) {
this._clearPreviousSelectedOption(event.source);
this._setTriggerValue(event.source.value);
this._onChange(event.source.value);
const source = event && event.source;

if (source) {
this._clearPreviousSelectedOption(source);
this._setTriggerValue(source.value);
this._onChange(source.value);
this.autocomplete._emitSelectEvent(source);
this._element.nativeElement.focus();
this.autocomplete._emitSelectEvent(event.source);
}

this.closePanel();
Expand Down
22 changes: 22 additions & 0 deletions src/material/autocomplete/autocomplete.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2872,6 +2872,28 @@ describe('MatAutocomplete', () => {
expect(event.option.value).toBe('Washington');
}));

it('should refocus the input after the selection event is emitted', fakeAsync(() => {
const events: string[] = [];
const fixture = createComponent(AutocompleteWithSelectEvent);
fixture.detectChanges();
const input = fixture.nativeElement.querySelector('input');

fixture.componentInstance.trigger.openPanel();
zone.simulateZoneExit();
fixture.detectChanges();

const options =
overlayContainerElement.querySelectorAll('mat-option') as NodeListOf<HTMLElement>;
spyOn(input, 'focus').and.callFake(() => events.push('focus'));
fixture.componentInstance.optionSelected.and.callFake(() => events.push('select'));

options[1].click();
tick();
fixture.detectChanges();

expect(events).toEqual(['select', 'focus']);
}));

it('should emit an event when a newly-added option is selected', fakeAsync(() => {
const fixture = createComponent(AutocompleteWithSelectEvent);

Expand Down

0 comments on commit 402c07b

Please sign in to comment.