web-dev-qa-db-ja.com

<mat-select>コンポーネントにオートコンプリートを実装するにはどうすればよいですか?

オプションリストが非常に長くなるため、オートコンプリート機能と複数選択マット選択セレクターを組み合わせたいと思います。

私はすでにstackoverflowで答えを探していましたが、答えに最も近いのはこれでした angular material の<mat-select>コンポーネントの検索フィルタを実装します

ただし、例はテーブルに関するものであり、mat-selectではありません。

私の質問は、オートコンプリート機能をmat-selectに追加することは可能ですか?リストの各アイテムの前にチェックボックスを含むオートコンプリートを作成できない場合はどうすればよいですか?

ありがとうございました

編集:angularのprimefacesには、リスト項目を検索できる複数選択リストがあります。組み込みの全選択ボタンも含まれています!ここで見つけることができます- https://www.primefaces.org/primeng/#/multiselect

Primefacesはnpm install primeng --saveでインストールできます

6
Maurice

MatAutocompleteといくつかのトリックを使用して、オートコンプリートの複数選択を実装できます。入力要素を制御できないため、MatSelectを使用してそれを実行できないと確信しています。この手法は少し奇妙ですが、うまく機能します。アイデアは、コントローラーで選択を管理し、各mat-optionの「値」を同じもの(選択したオプション)に設定することです。また、クリックをトラップして、ユーザーがリストと対話できるようにし(クリックするとすぐに閉じるのではなく)、もちろんmat-optionアイテム内にチェックボックスを提供する必要があります。他のいくつかのトリックも同様に必要です- ここに迅速で汚い例があります それは何をすべきかを示しています。

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

}
13
G. Tranter

はい、PrimeNG複数選択コントロールを使用できます。問題があるのは、テーマが心配な場合だけです。

mat-select-autocompletを使用する別のオプションがあります

インストール方法:

npm install select-autocomplete --save

npm: https://www.npmjs.com/package/mat-select-autocomplete

デモ: https://stackblitz.com/edit/mat-select-autocomplete

0
Manoj De Mel