Skip to content

Commit 1a4e9ea

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 d02338b commit 1a4e9ea

File tree

2 files changed

+74
-0
lines changed

2 files changed

+74
-0
lines changed

src/material/autocomplete/autocomplete-trigger.ts

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

209+
/** Value of the autocomplete control. */
210+
private _value: any;
211+
209212
/** `View -> model callback called when value changes` */
210213
_onChange: (value: any) => void = () => {};
211214

@@ -252,6 +255,15 @@ export class MatAutocompleteTrigger
252255
ngAfterViewInit() {
253256
this._initialized.next();
254257
this._initialized.complete();
258+
if (this._value) {
259+
const selectedOption = this.autocomplete?.options?.find(
260+
o => this._getDisplayValue(o.value) === this._getDisplayValue(this._value),
261+
);
262+
if (selectedOption && !selectedOption.selected) {
263+
selectedOption.select(false);
264+
this._changeDetectorRef.detectChanges();
265+
}
266+
}
255267
this._cleanupWindowBlur = this._renderer.listen('window', 'blur', this._windowBlurHandler);
256268
}
257269

@@ -434,6 +446,7 @@ export class MatAutocompleteTrigger
434446

435447
// Implemented as part of ControlValueAccessor.
436448
writeValue(value: any): void {
449+
this._value = value;
437450
Promise.resolve(null).then(() => this._assignOptionValue(value));
438451
}
439452

src/material/autocomplete/autocomplete.spec.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1614,6 +1614,36 @@ describe('MatAutocomplete', () => {
16141614
});
16151615
});
16161616

1617+
describe('form control with initial value', () => {
1618+
let fixture: ComponentFixture<FormControlWithInitialValue>;
1619+
let input: HTMLInputElement;
1620+
1621+
beforeEach(waitForAsync(async () => {
1622+
fixture = createComponent(FormControlWithInitialValue);
1623+
fixture.detectChanges();
1624+
1625+
input = fixture.debugElement.query(By.css('input'))!.nativeElement;
1626+
1627+
fixture.componentInstance.trigger.openPanel();
1628+
fixture.detectChanges();
1629+
await new Promise(r => setTimeout(r));
1630+
}));
1631+
1632+
it('should mark the initial value as selected if its present', fakeAsync(() => {
1633+
const trigger = fixture.componentInstance.trigger;
1634+
trigger.openPanel();
1635+
fixture.detectChanges();
1636+
1637+
const options = overlayContainerElement.querySelectorAll(
1638+
'mat-option',
1639+
) as NodeListOf<HTMLElement>;
1640+
1641+
expect(input.value).toBe('Three');
1642+
expect(options.length).toBe(3);
1643+
expect(options[2].classList).toContain('mdc-list-item--selected');
1644+
}));
1645+
});
1646+
16171647
describe('option groups', () => {
16181648
let DOWN_ARROW_EVENT: KeyboardEvent;
16191649
let UP_ARROW_EVENT: KeyboardEvent;
@@ -4414,6 +4444,37 @@ class PlainAutocompleteInputWithFormControl {
44144444
formControl = new FormControl('');
44154445
}
44164446

4447+
@Component({
4448+
template: `
4449+
<mat-form-field>
4450+
<input matInput placeholder="Choose" [matAutocomplete]="auto" [formControl]="optionCtrl">
4451+
</mat-form-field>
4452+
<mat-autocomplete #auto="matAutocomplete" >
4453+
@for (option of options; track option) {
4454+
<mat-option [value]="option">
4455+
{{option}}
4456+
</mat-option>
4457+
}
4458+
</mat-autocomplete>
4459+
`,
4460+
imports: [
4461+
MatAutocomplete,
4462+
MatAutocompleteTrigger,
4463+
MatOption,
4464+
MatInputModule,
4465+
ReactiveFormsModule,
4466+
],
4467+
})
4468+
class FormControlWithInitialValue {
4469+
optionCtrl = new FormControl('Three');
4470+
filteredOptions: Observable<any>;
4471+
options = ['One', 'Two', 'Three'];
4472+
4473+
@ViewChild(MatAutocompleteTrigger) trigger: MatAutocompleteTrigger;
4474+
4475+
constructor() {}
4476+
}
4477+
44174478
@Component({
44184479
template: `
44194480
<mat-form-field>

0 commit comments

Comments
 (0)