如何在< mat-select>中实现自动完成功能成分? [英] How do i implement autocomplete in a <mat-select> component?

查看:51
本文介绍了如何在< mat-select>中实现自动完成功能成分?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想将自动完成功能与多选垫选选择器结合使用,因为选项列表会很长.

I would like to combine the autocomplete feature with a multiselect mat-select chooser because the optionslist will be quite long.

我已经在stackoverflow上搜索了答案,最接近答案的是这个

I've already searched on stackoverflow for the answer and the closest to an answer was this implement a search filter for the <mat-select> component of angular material

但是这些示例是关于表格而不是基于mat-select的.

However the examples are about table and not mat-select.

我的问题是,是否可以将自动完成功能添加到按选择.如果不能,我是否可以进行自动填充,在列表中每个项目的前面都包含复选框?

My question is, is it possible to add the autocomplete feature to mat-select. And if not could i make an autocomplete that includes checkboxes in front of each item in the list?

谢谢

我发现角度的素面确实有一个多选列表,可让您搜索列表项.它还包括一个内置的全选按钮!您可以在这里找到它 https://www.primefaces.org/primeng/#/multiselect

I've found out that primefaces for angular does have a multiselect list that allows you to search for listitems. It also includes a builtin select-all button! You can find it here https://www.primefaces.org/primeng/#/multiselect

您可以使用npm install primeng --save

推荐答案

您可以使用MatAutocomplete和一些技巧来实现自动完成的多项选择.我相当确定您不能使用MatSelect进行操作,因为这不能使您控制输入元素.该技术有点奇怪,但效果很好.这个想法是在控制器中管理选择,并将每个mat-option的值"设置为相同的东西-您选择的选项.您还需要捕获单击以允许用户与列表进行交互(而不是单击时立即将其关闭),并且当然需要在mat-option项内提供复选框.其他一些技巧也是必要的-这是一个快速而肮脏的示例,该示例显示了该怎么做.

You can implement an autocomplete multi-select using MatAutocomplete and some tricks. I'm fairly sure you can't do it with MatSelect since that doesn't give you control over the input element. The technique is a little odd, but it works fine. The idea is to manage selections in your controller, and set the "value" of each mat-option to the same thing - your selected options. You also need to trap clicks to allow users to interact with the list (rather than have it close immediately when clicked), and of course provide checkboxes inside the mat-option items. A few other tricks are necessary as well - here is a quick and dirty example that shows what to do.

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

}

这篇关于如何在&lt; mat-select&gt;中实现自动完成功能成分?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆