When typing some text into the input and selecting an option from the autocomplete by hiting enter, it saves as chips both of the strings. Image here
However, this doesn
It is working fine for me. Here I am attaching the example link which provided by meterial.angular.io
https://stackblitz.com/angular/klblpljogjd?file=app%2Fchips-autocomplete-example.ts
While the solution presented by André Dias works when you have a strict selection choice, it won't do if you need to add a substring of one in the selection (think of "java" when you have only "javascript" in autocomplete). For this also to work you can use the optionActivated
event with a global variable (this does not solve completely the problem, you still have the issue if you select with the mouse). Below an example.
The html part:
<mat-autocomplete
#auto="matAutocomplete"
(optionActivated)="optionActivated($event)"
(optionSelected)="selectedTag($event)">
<mat-option *ngFor="let tag of filteredTags | async" [value]="tag">
{{ tag }}
</mat-option>
</mat-autocomplete>
The component part:
autocompleteTagsOptionActivated = false;
optionActivated($event: MatAutocompleteActivatedEvent) {
if ($event.option) {
this.autocompleteTagsOptionActivated = true;
}
}
and then check the boolean variable and set it to false when actually added from keyboard selection:
addTag(event: MatChipInputEvent): void {
const input = event.input;
const value = event.value;
if ((value || '').trim() && !this.autocompleteTagsOptionActivated) {
this.formArrayTags.push(this.formBuilder.control(value.trim().toLowerCase()));
}
// Reset the input value
if (input) {
input.value = '';
}
this.tagsControl.setValue(null);
this.formArrayTags.markAsDirty();
}
selectedTag(event: MatAutocompleteSelectedEvent): void {
this.formArrayTags.push(this.formBuilder.control(event.option.viewValue));
this.tagInput.nativeElement.value = '';
this.tagsControl.setValue(null);
this.autocompleteTagsOptionActivated = false;
}
Regarding the selection event, when you press ENTER, both the matChipInputTokenEnd, from your input, and the optionSelected, from mat-autocomplete, will fire. Normally, this happens with the optionSelected first, so that when the input event fires, the chip will already be added and the input will have no value to add. This is the reason why you don't get this issue by clicking with your mouse, since only the optionSelected event will be fired.
Now I said normally because I've also been getting this problem on a module imported component. If this is your case, this is probably a bug.
However, I did find a quick solution. What I did was check if the mat-autocomplete dialog was open and prevent the mat-chip-input from adding a new element. Checking for a selected item on the options list is also a possibility but it's less performant and not the behavior I was looking for.
Hope this helps:
@ViewChild('chipAutocomplete') chipAutocomplete: MatAutocomplete;
addElement(event: MatChipInputEvent) {
if ((event.value || '').trim() && !this.chipAutocomplete.isOpen) {
this.value.push({
name: event.value.trim()
});
}
if (event.input) {
event.input.value = '';
}
this.chipInputControl.setValue(null);
}
I combined the answer from @ama and this other answer to get the functionality I think you're describing. The key was to combine the optionActivated global variable with manually closing the autocomplete panel:
optionActivated
to your mat-autocomplete
<input #autoInput (matChipInputTokenEnd)="inputTokenEnd($event)" ... >
<mat-autocomplete (optionActivated)="optionActivated($event)"
(optionSelected)="optionSelected($event)... >
optionActivated
function and global varautocompleteTagsOptionActivated = false;
optionActivated(event: MatAutocompleteActivatedEvent) {
if (event.option) {
this.autocompleteTagsOptionActivated = true;
}
}
MatAutocompleteTrigger
of your input@ViewChild('autoInput', { read: MatAutocompleteTrigger }) matAutocompleteTrigger: MatAutocompleteTrigger;
inputTokenEnd
to only process the input if there tags weren't activated and conditionally close the autocomplete inputTokenEnd(event: MatChipInputEvent): void {
const input = event.input;
const value = event.value;
if ((value || '').trim() && !this.autocompleteTagsOptionActivated) {
this.value.push(value.trim());
}
// Reset the input value
if (input) {
input.value = '';
}
this.controlsForm.autocomplete.setValue(null);
// If no autocomplete options were activated, then issue the command to close the panel. The enter key that
// triggers the input will inadventantly open the panel
if (!this.autocompleteTagsOptionActivated) {
this.matAutocompleteTrigger.closePanel()
}
}
optionSelected
to reset the activation var
optionSelected(event: MatAutocompleteSelectedEvent): void {
this.autocompleteTagsOptionActivated = false;
...
}