javascript - Angular Material: Skjul Autocomplete-panel når brukeren trykker på enter-tasten
Jeg jobber for øyeblikket med en tabell hvor brukeren kan tabbe gjennom redigerbare elementer ved å trykke på enter. Jeg bruker også Angular Material i dette.
Jeg har et mat-form-field med flere dynamisk opprettede inndatafelt med mat-autocomplete-elementet. Men enter-tasthendelsen min oppfører seg litt annerledes her.
Når du trykker på inndatafeltet, vil et panel åpne seg (rullegardin) hvor brukeren kan velge inndataene, eller han kan enkelt skrive selv, og panelet vil gi forslag (autofullfør).
Hva skjer hvis du trykker på tabulatortasten?
Hvis du trykker på tabulatortasten mens du skriver, vil markøren flytte seg til neste redigerbare element, og panelet (nedtrekksmenyen) til det siste elementet vil lukke seg.
Hva skjer hvis du trykker på Enter-tasten
Hvis du trykker på enter mens du skriver, vil markøren flytte seg til det neste redigerbare elementet, MEN panelet (rullegardinmenyen) til det siste elementet forblir åpent, noe som resulterer i at flere inndatafelt har et åpent rullegardinpanel selv om brukeren allerede har skrevet det han trengte.
Mal:
<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>
Dette oppretter ganske enkelt rader basert på antall objekter i en matrise (ikke så viktig her).
Det finnes også en keyup.enter-hendelse på inndatabfeltene som utløses hver gang brukeren trykker på enter mens fokuset er på et inndatabfelt, og som sender radindeks og kolonneindeks for å få det neste redigerbare elementet.
Komponent:
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);
}
}
Denne funksjonen mottar to parametere. Rekkefølgeindeks og kolonneindeks, og beregner indeksen til det neste redigerbare elementet som skal fokuseres på.
Linjen this.autocomplete.showPanel=false ble skrevet for å se om jeg enkelt kunne lukke panelet på denne måten, men det fungerte ikke.
this.autocomplete er et objekt av klassen MatAutocomplete. Jeg har lagt til dette ved å skrive
@Input('matAutocomplete')
autocomplete: MatAutocomplete
Hva jeg trenger:
Jeg vil at rullegardinpanelet til mat-autocomplete-elementet skal lukkes etter å ha trykket enter.
Takk på forhånd!
Oppdatering:
Så etter å ha jobbet litt fant jeg dette
@ViewChild('test', { read: MatAutocompleteTrigger }) test: MatAutocompleteTrigger;
+
this.test.closePanel();
Denne gangen klarer jeg å lukke panelet til den FØRSTE cellen i tabellen, men alle panelene til de andre inndatafeltene forblir åpne
Svar #1
Min brukstilfelle var litt annerledes, så oppdateringen din fungerte ikke for meg, men jeg fant en litt annerledes løsning som gjør susen:
@ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger;
Deretter kan du bruke dette for å lukke rullegardinvalgene:
this.autocomplete.closePanel();
Sørg for å også importere ViewChild:
import { ViewChild } from '@angular/core';
Fungerer som en drøm.
Svar #2
Denne kommentaren gir en løsning der du kan få en referanse til matAutocompleteTrigger direkte på input-elementet, slik at du kan kalle closePanel() i malen. For eksempel:
<input
type="text"
matInput
#trigger="matAutocompleteTrigger"
(keydown.enter)="$event.target.blur(); trigger.closePanel()"
[formControl]="myControl"
[matAutocomplete]="auto"
/>
