I'm building a form where I use the Angular Material Autocomplete module. I load the options from a server and I filter them with an input. It works great, and now I wanted to add a "clear" icon to clear the field if needed.
The clear option clears the field, but it doesn't show the autocomplete options again. It shows them when I manually delete the input contents with backspace but not with the icon.
To "clear" the field I use this code:
clear(control: string): void {
this.form.get(control).setValue('');
}
And I call it from a mat-icon
component:
<mat-form-field>
<input matInput type="text" ... >
<mat-icon matSuffix (click)="clear(fieldName)" ...>
clear</mat-icon>
</mat-form-field>
<mat-autocomplete> ... </mat-autocomplete>
Where fieldName (string) is the name of the control I want to clear.
And this is how I filter the autocomplete options:
this.filter = this.form.get(field).valueChanges.pipe(
startWith(''), // Don't even know what this does...
map(value => this.options.filter(option => option.name.toLowerCase().includes(value.toString().toLowerCase())))
);
I suspect that maybe there's an error with the setValue('')
inside the clear()
method. Or maybe its the filter method that I'm using.
Here's the full example in StackBlitz:
https://stackblitz.com/edit/angular-autocomplete-clear9zzmw2
It seems like you want to open the options panel as soon as you click on clear button. This is not happening because once you select an option of matAutocomplete
, it selects the value and close the options panel. In order to open it again you have to either remove character from textbox or type matching character sequence.
Over here you are manually clearing up the value, but it doesn't intimate matAutoComplete
to open the panel. If you look at source code of matAutocomplete
you will find that input
/blur
/keydown
event happened are responsible for opening and closing panel. You can do that by triggering those event manually(into separate change detection cycle). But the most convenient way would be calling openPanel
method of matAutocomplete
.
So lets concentrate on how can we do call openPanel
method of matAutocomplete
. Since you've used matAutocomplete
with combination of matInput
, it does exported as matAutocompleteTrigger
. So add #automcomplete="matAutocompleteTrigger"
inside your matInput element like shown below.
Markup
<input
matInput
type="text"
#automcomplete="matAutocompleteTrigger"
placeholder="Select something"
formControlName="autocomplete"
[matAutocomplete]="autocompleteStuff"
required>
Now using ViewChild
decorator we can query autocomplete
template variable
Component
// It will have an autocomplete component instance
@ViewChild('automcomplete') autocomplete;
//...
//...
clear(control: string): void {
this.form.get(control).setValue('');
// call autoComplete `openPanel` to show up options
setTimeout(()=> {this.autocomplete.openPanel() })
}
Running Demo
Alternative solution could be blur out and focus in to the input programmatically. For the same just keep #automcomplete
on matInput
and then query the element using ViewChild
and then trigger event on the nativeElement
of queried result.
Html
<input
matInput
type="text"
#automcomplete
placeholder="Select something"
formControlName="autocomplete"
[matAutocomplete]="autocompleteStuff"
required>
Component
@ViewChild('automcomplete') autocomplete;
//...
//...
clear(control: string): void {
this.form.get(control).setValue('');
setTimeout(()=> {
this.autocomplete.nativeElement.blur();
this.autocomplete.nativeElement.focus();
})
}
Forked Demo
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With