Angular Material Autocomplete - 如何允许用户添加不在建议列表中的项目? [英] Angular Material Autocomplete - How to allow user to add item not in suggested list?

查看:19
本文介绍了Angular Material Autocomplete - 如何允许用户添加不在建议列表中的项目?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试从 Angular Material 实现自动完成组件:

I'm trying to implement the autocomplete component from Angular Material:

https://material.angular.io/components/autocomplete/overview

它非常适合让用户从建议列表中选择特定项目,但我也希望允许用户添加不在列表中的项目.

It works well for letting the user select a particular item from the suggested list but I also want to allow the user to add items not in the list.

假设建议列表包含以下项目:

So lets say the suggested list has the following items:

Cats
Birds
Dogs

并且用户开始输入 "Do" 并且自动完成显示 "Dogs" 作为建议选项(因为我还根据他们输入的内容过滤列表).但随后用户继续输入 "Dolls" 并且现在自动完成建议中没有显示任何内容.然后用户按回车键,它就会被添加到列表中.

And the user starts typing "Do" and the autocomplete shows "Dogs" as the suggested option (because I'm also filtering the list based on what they type). But then the user continues typing "Dolls" and now nothing is displayed in the autocomplete suggestions. Then the user hits enter and it gets added to the list.

当前的行为是,如果列表中不存在用户键入的内容,则他们无法添加该项目.

Current behavior is that if what the user typed doesn't exist in the list then they are unable to add the item.

推荐答案

如果在输入字段中添加回车键侦听器,则可以处理输入的值并将其添加到选项中(如果它不存在).您还可以将用户输入的任何内容作为添加新项目"选项动态添加到过滤选项列表中,或将添加"图标添加到字段中(例如作为 matSuffix).或者你可以同时做这三件事:

If you add an enter key listener to the input field, you can process the entered value and add it to the options if it doesn't exist. You can also dynamically add whatever the user enters to the list of filtered options as an "add new item" option, or add an "add" icon to the field (e.g. as a matSuffix). Or you can do all three:

Stackblitz

HTML

<form class="example-form">
  <mat-form-field class="example-full-width">
    <input matInput placeholder="Item" aria-label="Item" [matAutocomplete]="auto" [formControl]="itemCtrl" (keyup.enter)="addOption()">
    <mat-autocomplete #auto="matAutocomplete" (optionSelected)="optionSelected($event.option)">
      <mat-option *ngFor="let item of filteredItems | async" [value]="item">
        <span>{{ item }}</span>
      </mat-option>
    </mat-autocomplete>
    <button *ngIf="showAddButton && itemCtrl.value" matSuffix mat-button mat-icon-button (click)="addOption()"><mat-icon matTooltip='Add "{{itemCtrl.value}}"'>add</mat-icon></button>
  </mat-form-field>
</form>

TS

import { Component } from '@angular/core';
import { FormControl } from '@angular/forms';

import { Observable } from 'rxjs/Observable';
import { startWith } from 'rxjs/operators/startWith';
import { map } from 'rxjs/operators/map';

/**
 * @title Autocomplete with add new item option
 */
@Component({
  selector: 'autocomplete-overview-example',
  templateUrl: 'autocomplete-overview-example.html',
  styleUrls: ['autocomplete-overview-example.css']
})
export class AutocompleteOverviewExample {
  itemCtrl: FormControl;
  filteredItems: Observable<any[]>;
  showAddButton: boolean = false;

  prompt = 'Press <enter> to add "';

  items: string[] = [
    'Cats',
    'Birds',
    'Dogs'
  ];

  constructor() {
    this.itemCtrl = new FormControl();
    this.filteredItems = this.itemCtrl.valueChanges
      .pipe(
      startWith(''),
      map(item => item ? this.filterItems(item) : this.items.slice())
      );
  }

  filterItems(name: string) {
    let results = this.items.filter(item =>
      item.toLowerCase().indexOf(name.toLowerCase()) === 0);

    this.showAddButton = results.length === 0;
    if (this.showAddButton) {
      results = [this.prompt + name + '"'];
    }

    return results;
  }

  optionSelected(option) {
    if (option.value.indexOf(this.prompt) === 0) {
      this.addOption();
    }
  }

  addOption() {
    let option = this.removePromptFromOption(this.itemCtrl.value);
    if (!this.items.some(entry => entry === option)) {
      const index = this.items.push(option) - 1;
      this.itemCtrl.setValue(this.items[index]);
    }
  }

  removePromptFromOption(option) {
    if (option.startsWith(this.prompt)) {
      option = option.substring(this.prompt.length, option.length -1);
    }
    return option;
  }
}

这篇关于Angular Material Autocomplete - 如何允许用户添加不在建议列表中的项目?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

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