web-dev-qa-db-fra.com

Angular Matériau: Masquer le panneau de saisie semi-automatique lorsque l'utilisateur clique sur Entrée

Je travaille actuellement sur une table dans laquelle l'utilisateur peut parcourir des éléments modifiables en appuyant sur Entrée. J'utilise aussi Angular Matériau pour cela.

J'ai un mat-form-field avec plusieurs champs d'entrée créés dynamiquement avec l'élément mat-autocomplete. Cependant, mon événement d'entrée touche un peu différent en cela.

Lorsque vous appuyez sur le champ de saisie, un panneau s'ouvre (liste déroulante) où l'utilisateur peut sélectionner l'entrée ou il peut simplement écrire lui-même et le panneau émet des suggestions (autocomplétion).

Que se passe-t-il si vous appuyez sur la touche de tabulation?

Si vous appuyez sur tab tout en tapant, le curseur se déplacera sur le prochain élément éditable et le panneau (liste déroulante) du dernier élément se fermera.

Que se passe-t-il si vous appuyez sur la touche Entrée

Si vous appuyez sur Entrée tout en tapant, le curseur se déplacera sur le prochain élément éditable, CEPENDANT le panneau (liste déroulante) du dernier élément restant ouvert, donnant lieu à plusieurs champs de saisie ayant un panneau déroulant ouvert même si l'utilisateur a déjà écrit ce dont il avait besoin à.

Modèle:

<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>

Cela crée simplement des lignes en fonction du nombre d'objets dans un tableau (ce n'est pas très important ici). 

Il existe également un événement keyup.enter sur les champs d'entrée qui est déclenché chaque fois que l'utilisateur appuie sur entrée pendant que le focus est sur un champ d'entrée et transmet l'index de ligne et l'index de colonne pour obtenir le prochain élément modifiable.

Composant:

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);
}

}

Cette fonction reçoit deux paramètres. Row Index et Column Index et calcule l'index du prochain élément éditable sur lequel se concentrer. 

La ligne this.autocomplete.showPanel = false a été écrite pour voir si je pouvais simplement fermer le panneau de cette façon mais cela ne fonctionnait pas.

this.autocomplete est un objet de la classe MatAutocomplete . J'ai ajouté ceci en écrivant 

@Input('matAutocomplete')
autocomplete: MatAutocomplete

Ce dont j'ai besoin:

Je souhaite que le panneau déroulant de l'élément de complétion automatique mat se ferme après avoir appuyé sur Entrée.

Merci d'avance!

Mettre à jour:

Donc, après avoir travaillé un peu, j'ai trouvé ceci

@ViewChild('test', { read: MatAutocompleteTrigger }) test: MatAutocompleteTrigger;

+

this.test.closePanel();

Cette fois, je peux fermer le panneau de la cellule FIRST du tableau, mais tous les panneaux des autres champs de saisie resteront ouverts.

4
Ekos

Mon cas d'utilisation était légèrement donc votre mise à jour n'a pas fonctionné pour moi, mais j'ai trouvé un légèrement solution différente qui fait l'affaire:

@ViewChild(MatAutocompleteTrigger) autocomplete: MatAutocompleteTrigger;

Ensuite, vous pouvez utiliser ceci pour fermer les options du menu déroulant:

this.autocomplete.closePanel(); 

Assurez-vous également d'importer ViewChild:

import { ViewChild } from '@angular/core';

Fonctionne comme un charme.

10

Ce commentaire fournit une solution permettant d’obtenir une référence au matAutocompleteTrigger directement sur l’élément d’entrée afin que vous puissiez appeler closePanel () dans le modèle. Par exemple:

    <input
      type="text"
      matInput
      #trigger="matAutocompleteTrigger"
      (keydown.enter)="$event.target.blur(); trigger.closePanel()"
      [formControl]="myControl"
      [matAutocomplete]="auto"
    />
1
Tim