wake-up-neo.com

Wie kann die automatische Autovervollständigung angehalten werden, um benutzerdefinierte Benutzereingabewerte von den angegebenen Optionen zu trennen?

Ich verwende die mat-auto complete-Komponente von material.angular.io. Das Standardverhalten ist, dass der Benutzer einen beliebigen Wert eingeben kann und Optionen zur Auswahl bietet. Sie können Ihre Eingabe auch zu ausgewählten Werten hinzufügen. Sie können das Beispiel hier überprüfen. https://stackblitz.com/angular/ngmvgralayd?file=app%2Fautocomplete-simple- example.html

hier ist der Code, den ich für die Generierung des automatischen Eingabefeldes verwende. 

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input type="text" placeholder="Pick one" aria-label="Number" matInput [formControl]="myControl" [matAutocomplete]="auto" disabled="true">
    <mat-autocomplete #auto="matAutocomplete">
      <mat-option *ngFor="let option of options" [value]="option">
        {{ option }}
      </mat-option>
    </mat-autocomplete>
  </mat-form-field>
</form>

Ich möchte jedoch, dass das Formularfeld nur Werte aus der angegebenen Option übernimmt und verhindert, dass Werte von Benutzern eingegeben werden, abgesehen von der angegebenen Option. Wie kann ich das erreichen? Es ist wie ein Eingang mit automatischer Vervollständigung zu wählen. 

4

Sie können so etwas tun

Markup:

<md-input-container class="full-width">
<input mdInput [mdAutocomplete]="autoData"
       #searchMyData
       formControlName="myControl"
       (keyup)="changeMyControl()">
</md-input-container>
<md-autocomplete #autoData="mdAutocomplete">
<md-option
    *ngFor="let option of options"
    [value]="option.name"
    (onSelectionChange)="onSelectedOption($event.source.selected, option.id);">
    {{ option.name }}
</md-option>
</md-autocomplete>

Komponente:

selectedOption;
changeMyControl(): void {
    if (isUndefined(this.selectedOption) {
        // also check selected item and entered text are not same
        this.myForm.get('myControl').setErrors({'incorrect': true});
    }
}

onSelectedOption(isSelected: boolean, id: number): void {
    if (isSelected) {
        setTimeout(() => {
            const option = this.options.filter(bt => bt.id === id);
            if (option.length > 0) {
                this.selectedOption= option[0];
               // patch formcontrol value here
            }
        }, 200);
    }
}
4
Ketan Akbari

Wie bereits in einem Kommentar von @trichetriche vorgeschlagen, ist dies ein Anwendungsfall für select.

Sie können wie folgt die Materialversion von select verwenden

<mat-form-field>
  <mat-select placeholder="Favorite food">
    <mat-option *ngFor="let food of foods" [value]="food.value">
      {{ food.viewValue }}
    </mat-option>
  </mat-select>
</mat-form-field>

Wenn Sie einen Filter über der Auswahl benötigen, dann empfehle ich Ihnen PrimeNg Dropdown https://www.primefaces.org/primeng/#/dropdown

2
David Votrubec

Die Material Demo für Chips Autocomplete zeigt Bindungen sowohl auf dem input als auch auf dem mat-autocomplete:

<input (matChipInputTokenEnd)="add($event)">
<mat-autocomplete (optionSelected)="selected($event)"></mat-autocomplete>

Wenn Sie nur Optionen aus der Autovervollständigung zulassen möchten, lassen Sie die add-Funktion in der Eingabe aus. 

0
adamdport

Ich denke, es gibt hier eine UI/UX-Frage - auf welche Weise hindern wir den Benutzer daran, etwas einzugeben, das nicht in der Liste der Optionen enthalten ist, es ihm aber dennoch erlaubt, nach einem String zu filtern?

Ich sehe einige mögliche Optionen. Zuerst soll nur der Fehler "Ungültiger Eintrag" angezeigt werden, wenn die Option nicht in der Liste neben der Eingabe steht. Die zweite Möglichkeit wäre, die Eingabe von Zeichen zu unterbinden, die mit keiner Option mehr übereinstimmen. Wenn also eine einzige Option "foo" vorhanden ist und ein Benutzer "for" eingibt, wird nur "fo" akzeptiert und das 'r' wird verworfen.

Die PrimeNg -Lösung ist nicht ganz dasselbe wie ein Textfeld, in dem der Benutzer mit der Eingabe beginnen kann. Der Benutzer muss zuerst klicken, um eine Suche zu öffnen, und es scheint nicht möglich zu sein, auf die Tastatur zuzugreifen. Ich verstehe nicht wirklich, warum sie es nicht so implementiert haben, dass Anzeige und Suche gleich sind, außer dass Logos angezeigt werden.

0
Mark