Clear Angular Material autocomplete after selection
Solution 1
I think you're close, it looks like the only missing piece is resetting the form control value in selectCategory
. This is how
we accomplished it in our own app, but it's effectively the same thing:
/** Reference to the autocomplete trigger. */
@ViewChild(MdAutocompleteTrigger)
private trigger: MdAutocompleteTrigger;
/** Form control for the input. */
searchControl = new FormControl('');
ngAfterViewInit() {
// Clear the input and emit when a selection is made
this.trigger.autocomplete.optionSelected
.map(event => event.option)
.subscribe(option => {
// This may or may not be needed, depending on your purposes
option.deselect();
// Emit the selection (so parent component can add chip)
this.selection.emit(option.value);
// Reset the value of the input
this.searchControl.setValue('');
});
}
Whenever you select a value, there will be a brief "flash" of the selected text. To avoid this,
you can use the displayWith
property to just display selected values as empty:
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayNull">
...
</md-autocomplete>
/** Display function for selected autocomplete values. */
displayNull(value) {
return null;
}
Solution 2
Came across this solution, but I didn't like the displayNull
fix.
My solution looks similar to this:
component.html:
<input matInput [matAutocomplete]="auto" (input)="filter($event.target.value)" #autoInput>
<mat-autocomplete #auto [displayWith]="displayKey" (optionSelected)="emit($event, autoInput)">
// ...
</mat-autocomplete>
component.ts:
@Output() optionSelected = new EventEmitter<MatAutocompleteSelectedEvent>();
emit(event: MatAutocompleteSelectedEvent, ele: HTMLInputElement) {
ele.value = '';
ele.blur();
this.filter('');
this.optionSelected.emit(event);
}
Solution 3
Here my approach
in template
...
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayNull" (optionSelected)="selectHandler($event)">
...
in component.ts
public selectHandler(event : MdAutocompleteSelectedEvent) : void
{
event.option.deselect()
this.doStuffWith(event.option.value)
}
public displayNull()
{
return null
}
Solution 4
If you are using reactive forms the easiest way is to get the control and set the value to an empty string
- Get the control: https://angular.io/api/forms/AbstractControl#get
- Set the value: https://angular.io/api/forms/AbstractControl#setvalue
In my case i had to do:
<input [matAutocomplete]="auto" formControlName="currentContact" type="text" matInput placeholder="Locatie">
this.reactiveForm = this.formBuilder.group({currentContact: ['']})
this.reactiveForm.get('currentContact').setValue('');
tobi
Updated on July 09, 2022Comments
-
tobi almost 2 years
The problem I'm having is the following: the behaviour I need is, when an option is selected from the autocomplete input, it should add a chip to the Angular Material Chips component (which it does) and it should also clear the autocomplete input, so I can then select another option.
This is my html:
<div class="col-md-6"> <md-form-field> <input type="text" placeholder="Categoría" aria-label="Categoría" mdInput [mdAutocomplete]="auto" [formControl]="categoryCtrl"> <md-autocomplete #auto="mdAutocomplete" (optionSelected)="selectCategory($event)"> <md-option *ngFor="let category of filteredCategories | async" [value]="category.name"> {{ category.name }} </md-option> </md-autocomplete> </md-form-field> </div>
This is my TypeScript code:
constructor(private placeService: PlaceService, private categoryService: CategoryService) { this.categoryCtrl = new FormControl(); this.filteredCategories = this.categoryCtrl.valueChanges .startWith('') .map(category => category ? this.filterCategories(category) : this.categories.slice()); } filterCategories(name: string) { return this.categories.filter(category => category.name.toLowerCase().indexOf(name.toLowerCase()) === 0); } selectCategory(category: any) { const index = this.selectedCategories.indexOf(category.option.value); if (index === -1) { this.selectedCategories.push(category.option.value) } }
I've checked the Angular Material documentation and I haven't found a method to do this.
Thanks.
-
SkarXa over 4 yearsI'm not using ReactiveForm, so this is great for me
-
Admin over 3 yearsWhat about clearing input if there is not selected value? In this case I try to use input's
blur()
event, but in that case I cannot access the autocomplete value (if selected or not). Any idea? -
Ted Elliott over 2 yearsThis seems to be the only solution that works with angular material >=12. setValue on the formControl works fine when not attached to an autocomplete.