角材料自动完成-如何允许用户添加不在建议列表中的项目?

时间:2018-08-20 17:17:11

标签: javascript angular angular-material

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

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

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

所以可以说建议列表包含以下项目:

Cats
Birds
Dogs

然后用户开始输入"Do",自动完成显示"Dogs"作为建议的选项(因为我也根据输入的内容过滤列表)。但是随后用户继续输入"Dolls",现在自动完成建议中什么也没有显示。然后用户点击Enter,它将被添加到列表中。

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

2 个答案:

答案 0 :(得分:2)

如果将Enter键侦听器添加到输入字段,则可以处理输入的值并将其添加到选项(如果不存在)。您还可以将用户输入的内容动态地添加到过滤的选项列表中,作为“添加新项”选项,或在字段中添加“添加”图标(例如,作为matSuffix)。或者,您可以全部执行以下三个操作:

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() {
      if (!this.items.some(entry => entry === this.itemCtrl.value)) {
        const index = this.items.push(this.itemCtrl.value) - 1;
        this.itemCtrl.setValue(this.items[index]);
      }
    }
}

答案 1 :(得分:1)

用户可以在建议列表中添加一个项目,这很奇怪。该列表由知道建议内容的人向用户提出建议。但是无论如何...

用户可以在字段中输入任何内容,而忽略建议。通过忽略建议的 Dogs 并键入 Dolls ,用户可以按下“添加”按钮,该按钮会将( Dolls )中键入的内容添加到runtime('javax.xml.bind:jaxb-api') 数组。

例如,您可以通过侦听表单上的Submit事件来实现:

options

这里也是complete demo