I'm currently working on a table where the user is able to tab through editable elements by pressing enter. I also use Angular Material in this.
I have a mat-form-field with several dynamically created input fields with the mat-autocomplete element. However my enter key event acts a bit different in this.
When you press on the input field, a panel will open (dropdown) where the user can select the input or he can simply write himself and the panel will give suggestions (autocomplete).
What happens if you press the tab key?
If you press on tab while typing, the cursor will move onto the next editable element and the panel (dropdown) of the latest element will close.
What happens if you press the enter key
If you press on enter while typing, the cursor will move onto the next editable element HOWEVER the panel (dropdown) of the latest element stays open which resulst in multiple input fields having an open dropdown panel even though the user has already wrote what he needed to.
Template:
<tr *ngFor="let row of rows; let rowIdx = index">
<td *ngFor="let col of columns; let colIdx = index">
<mat-form-field class="example-full-width">
<input #inputs type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto"
(keyup.enter)="shiftFocusEnter(rowIdx, colIdx)">
<mat-autocomplete #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
</td>
</tr>
This simply creates rows based on the number of objects in an array (not quite important here).
There's also a keyup.enter event on the input fields which gets triggered when ever the user presses on enter while focus is on an input field and passes row index and column index to get the next editable element.
Component:
shiftFocusEnter(rowIdx: number, colIdx: number) {
console.log("Enter", rowIdx, colIdx);
if(colIdx == 4 && rowIdx == 5) {
console.log("Reached end of row");
}
else {
colIdx = colIdx + this.columns.findIndex(c => c.editable);
this.autocomplete.showPanel = false;
this.focusInput(rowIdx, colIdx);
}
}
This function receives two parameters. Row Index and Column Index and calculates the index of the next editable element to focus on that.
The line this.autocomplete.showPanel = false was written to see if I could simply close the panel like this but it didnt work.
this.autocomplete is an object of class MatAutocomplete. I've added this by writing
@Input('matAutocomplete')
autocomplete: MatAutocomplete
What I need:
I want the dropdown panel of the mat autocomplete element to close after pressing enter.
Thanks in advance!
Update:
So after working a bit I found this
@ViewChild('test', { read: MatAutocompleteTrigger }) test: MatAutocompleteTrigger;
+
this.test.closePanel();
This time I'm able to close the panel of the FIRST cell in the table however all the panels of the other input fields will stay open
My use case was slightly different so your update didn't work for me, but I found a slightly different solution that does the trick:
@ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger;
Then you can use this to close the dropdown options:
this.autocomplete.closePanel();
Make sure to also import ViewChild:
import { ViewChild } from '@angular/core';
Works like a charm.