Je voudrais combiner la fonctionnalité de saisie semi-automatique avec un sélecteur de sélection de tapis multisélection car la liste d'options sera assez longue.
J'ai déjà cherché sur stackoverflow la réponse et la plus proche d'une réponse était celle-ci implémenter un filtre de recherche pour le composant <mat-select> de angular material
Cependant, les exemples concernent la table et non la sélection mat.
Ma question est, est-il possible d'ajouter la fonction de saisie semi-automatique à mat-select. Et sinon, pourrais-je faire une saisie semi-automatique qui inclut des cases à cocher devant chaque élément de la liste?
Je vous remercie
EDIT: J'ai découvert que les primefaces pour angular a une liste multisélection qui vous permet de rechercher des éléments de liste. Il comprend également un bouton de sélection intégré! Vous pouvez le trouver ici - https://www.primefaces.org/primeng/#/multiselect
Vous pouvez installer des primefaces avec npm install primeng --save
Vous pouvez implémenter une sélection multiple à saisie semi-automatique en utilisant MatAutocomplete
et quelques astuces. Je suis assez sûr que vous ne pouvez pas le faire avec MatSelect
car cela ne vous donne pas le contrôle sur l'élément d'entrée. La technique est un peu étrange, mais elle fonctionne bien. L'idée est de gérer les sélections dans votre contrôleur et de définir la "valeur" de chaque mat-option
à la même chose - vos options sélectionnées. Vous devez également intercepter les clics pour permettre aux utilisateurs d'interagir avec la liste (plutôt que de la fermer immédiatement lorsque vous cliquez dessus), et bien sûr de fournir des cases à cocher à l'intérieur du mat-option
articles. Quelques autres astuces sont également nécessaires - voici un exemple rapide et sale qui montre quoi faire.
HTML:
<mat-form-field class="example-full-width">
<input type="text" placeholder="Select Users" aria-label="Select Users" matInput [matAutocomplete]="auto" [formControl]="userControl">
<mat-hint>Enter text to find users by name</mat-hint>
</mat-form-field>
<mat-autocomplete #auto="matAutocomplete" [displayWith]="displayFn">
<mat-option *ngFor="let user of filteredUsers | async" [value]="selectedUsers">
<div (click)="optionClicked($event, user)">
<mat-checkbox [checked]="user.selected" (change)="toggleSelection(user)" (click)="$event.stopPropagation()">
{{ user.firstname }} {{ user.lastname }}
</mat-checkbox>
</div>
</mat-option>
</mat-autocomplete>
<br><br>
<label>Selected Users:</label>
<mat-list dense>
<mat-list-item *ngIf="selectedUsers?.length === 0">(None)</mat-list-item>
<mat-list-item *ngFor="let user of selectedUsers">
{{ user.firstname }} {{ user.lastname }}
</mat-list-item>
</mat-list>
TS:
import { Component, OnInit, ViewChild } from '@angular/core';
import { FormControl } from '@angular/forms';
import { Observable } from 'rxjs';
import { map, startWith } from 'rxjs/operators';
export class User {
constructor(public firstname: string, public lastname: string, public selected?: boolean) {
if (selected === undefined) selected = false;
}
}
/**
* @title Multi-select autocomplete
*/
@Component({
selector: 'multiselect-autocomplete-example',
templateUrl: 'multiselect-autocomplete-example.html',
styleUrls: ['multiselect-autocomplete-example.css']
})
export class MultiselectAutocompleteExample implements OnInit {
userControl = new FormControl();
users = [
new User('Misha', 'Arnold'),
new User('Felix', 'Godines'),
new User('Odessa', 'Thorton'),
new User('Julianne', 'Gills'),
new User('Virgil', 'Hommel'),
new User('Justa', 'Betts'),
new User('Keely', 'Millington'),
new User('Blanca', 'Winzer'),
new User('Alejandrina', 'Pallas'),
new User('Rosy', 'Tippins'),
new User('Winona', 'Kerrick'),
new User('Reynaldo', 'Orchard'),
new User('Shawn', 'Counce'),
new User('Shemeka', 'Wittner'),
new User('Sheila', 'Sak'),
new User('Zola', 'Rodas'),
new User('Dena', 'Heilman'),
new User('Concepcion', 'Pickrell'),
new User('Marylynn', 'Berthiaume'),
new User('Howard', 'Lipton'),
new User('Maxine', 'Amon'),
new User('Iliana', 'Steck'),
new User('Laverna', 'Cessna'),
new User('Brittany', 'Rosch'),
new User('Esteban', 'Ohlinger'),
new User('Myron', 'Cotner'),
new User('Geri', 'Donner'),
new User('Minna', 'Ryckman'),
new User('Yi', 'Grieco'),
new User('Lloyd', 'Sneed'),
new User('Marquis', 'Willmon'),
new User('Lupita', 'Mattern'),
new User('Fernande', 'Shirk'),
new User('Eloise', 'Mccaffrey'),
new User('Abram', 'Hatter'),
new User('Karisa', 'Milera'),
new User('Bailey', 'Eno'),
new User('Juliane', 'Sinclair'),
new User('Giselle', 'Labuda'),
new User('Chelsie', 'Hy'),
new User('Catina', 'Wohlers'),
new User('Edris', 'Liberto'),
new User('Harry', 'Dossett'),
new User('Yasmin', 'Bohl'),
new User('Cheyenne', 'Ostlund'),
new User('Joannie', 'Greenley'),
new User('Sherril', 'Colin'),
new User('Mariann', 'Frasca'),
new User('Sena', 'Henningsen'),
new User('Cami', 'Ringo')
];
selectedUsers: User[] = new Array<User>();
filteredUsers: Observable<User[]>;
lastFilter: string = '';
ngOnInit() {
this.filteredUsers = this.userControl.valueChanges.pipe(
startWith<string | User[]>(''),
map(value => typeof value === 'string' ? value : this.lastFilter),
map(filter => this.filter(filter))
);
}
filter(filter: string): User[] {
this.lastFilter = filter;
if (filter) {
return this.users.filter(option => {
return option.firstname.toLowerCase().indexOf(filter.toLowerCase()) >= 0
|| option.lastname.toLowerCase().indexOf(filter.toLowerCase()) >= 0;
})
} else {
return this.users.slice();
}
}
displayFn(value: User[] | string): string | undefined {
let displayValue: string;
if (Array.isArray(value)) {
value.forEach((user, index) => {
if (index === 0) {
displayValue = user.firstname + ' ' + user.lastname;
} else {
displayValue += ', ' + user.firstname + ' ' + user.lastname;
}
});
} else {
displayValue = value;
}
return displayValue;
}
optionClicked(event: Event, user: User) {
event.stopPropagation();
this.toggleSelection(user);
}
toggleSelection(user: User) {
user.selected = !user.selected;
if (user.selected) {
this.selectedUsers.Push(user);
} else {
const i = this.selectedUsers.findIndex(value => value.firstname === user.firstname && value.lastname === user.lastname);
this.selectedUsers.splice(i, 1);
}
this.userControl.setValue(this.selectedUsers);
}
}
Oui, vous pouvez utiliser le contrôle multisélection PrimeNG. Le seul problème avec cela, c'est si vous êtes préoccupé par les thèmes.
Il existe une autre option utilisant mat-select-autocomplet
Comment installer:
npm install select-autocomplete --save