Skip to content

Commit 1478c8d

Browse files
committed
fix(material/autocomplete): add support for initial value in form control
Currently, when we have some initial value in formcontrol those are not marked as selected, this fix will check the initial value and if its matched, will be marked as selected. Fixes #29422
1 parent ca73b56 commit 1478c8d

File tree

2 files changed

+68
-0
lines changed

2 files changed

+68
-0
lines changed

src/material/autocomplete/autocomplete-trigger.ts

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -227,6 +227,9 @@ export class MatAutocompleteTrigger
227227
this._canOpenOnNextFocus = this.panelOpen || !this._hasFocus();
228228
};
229229

230+
/** Value of the autocomplete control. */
231+
private _value: any;
232+
230233
/** `View -> model callback called when value changes` */
231234
_onChange: (value: any) => void = () => {};
232235

@@ -273,6 +276,15 @@ export class MatAutocompleteTrigger
273276
ngAfterViewInit() {
274277
this._initialized.next();
275278
this._initialized.complete();
279+
if (this._value) {
280+
const selectedOption = this.autocomplete?.options?.find(
281+
o => this._getDisplayValue(o.value) === this._getDisplayValue(this._value),
282+
);
283+
if (selectedOption && !selectedOption.selected) {
284+
selectedOption.select(false);
285+
this._changeDetectorRef.detectChanges();
286+
}
287+
}
276288
this._cleanupWindowBlur = this._renderer.listen('window', 'blur', this._windowBlurHandler);
277289
}
278290

@@ -455,6 +467,7 @@ export class MatAutocompleteTrigger
455467

456468
// Implemented as part of ControlValueAccessor.
457469
writeValue(value: any): void {
470+
this._value = value;
458471
Promise.resolve(null).then(() => this._assignOptionValue(value));
459472
}
460473

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1607,6 +1607,36 @@ describe('MatAutocomplete', () => {
16071607
});
16081608
});
16091609

1610+
describe('form control with initial value', () => {
1611+
let fixture: ComponentFixture<FormControlWithInitialValue>;
1612+
let input: HTMLInputElement;
1613+
1614+
beforeEach(waitForAsync(async () => {
1615+
fixture = createComponent(FormControlWithInitialValue);
1616+
fixture.detectChanges();
1617+
1618+
input = fixture.debugElement.query(By.css('input'))!.nativeElement;
1619+
1620+
fixture.componentInstance.trigger.openPanel();
1621+
fixture.detectChanges();
1622+
await new Promise(r => setTimeout(r));
1623+
}));
1624+
1625+
it('should mark the initial value as selected if its present', fakeAsync(() => {
1626+
const trigger = fixture.componentInstance.trigger;
1627+
trigger.openPanel();
1628+
fixture.detectChanges();
1629+
1630+
const options = overlayContainerElement.querySelectorAll(
1631+
'mat-option',
1632+
) as NodeListOf<HTMLElement>;
1633+
1634+
expect(input.value).toBe('Three');
1635+
expect(options.length).toBe(3);
1636+
expect(options[2].classList).toContain('mdc-list-item--selected');
1637+
}));
1638+
});
1639+
16101640
describe('option groups', () => {
16111641
let DOWN_ARROW_EVENT: KeyboardEvent;
16121642
let UP_ARROW_EVENT: KeyboardEvent;
@@ -4406,6 +4436,31 @@ class PlainAutocompleteInputWithFormControl {
44064436
formControl = new FormControl('');
44074437
}
44084438

4439+
@Component({
4440+
template: `
4441+
<mat-form-field>
4442+
<input matInput placeholder="Choose" [matAutocomplete]="auto" [formControl]="optionCtrl">
4443+
</mat-form-field>
4444+
<mat-autocomplete #auto="matAutocomplete" >
4445+
@for (option of options; track option) {
4446+
<mat-option [value]="option">
4447+
{{option}}
4448+
</mat-option>
4449+
}
4450+
</mat-autocomplete>
4451+
`,
4452+
imports: [MatAutocomplete, MatAutocompleteTrigger, MatOption, ReactiveFormsModule],
4453+
})
4454+
class FormControlWithInitialValue {
4455+
optionCtrl = new FormControl('Three');
4456+
filteredOptions: Observable<any>;
4457+
options = ['One', 'Two', 'Three'];
4458+
4459+
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
4460+
4461+
constructor() {}
4462+
}
4463+
44094464
@Component({
44104465
template: `
44114466
<mat-form-field>

0 commit comments

Comments
 (0)