How can I force Angular 7+ Material Autocomplete t

2020-07-27 03:44发布

问题:

Edit: There are some workarounds as posted below (see answers) for template-driven forms. (I am looking for a solution for reactive forms).


How can I force Angular Material Autocomplete to enter letters only provided by a data source?

>> See the whole app here at stackblitz.com

"Adel" is initial value and it is provided by the options-array:

options: User[] = [
    {name: 'George Michael'},
    {name: 'Aretha Franklin'},
    {name: 'Adel'},
    {name: 'Janet Jackson'},
  ];

The auto-complete works properly:

However, the following should not be possible:

The user may only enter the letters corresponding to an entry in the list, i. the first letters of an existing entry.

If the user attempts to enter letters that do not correspond to any of the existing values, an error message should inform the user: "The entered value must correspond to a list entry".

Is there possibility to do that with Angular Material Autocomplete?

回答1:

I've solved this problem with a custom validator. If you want to see it, here,..

In the list but case sensitive:

Wrong Value

Everything is OK



回答2:

It might be more efficient to trap the key entry at input time by adding a keydown handler to the input. Then look ahead at what the value would be and compare it to the list, 'cancelling' the event if necessary. Crudely:

<input (keydown)="keydownHandler($event)" ...


keydownHandler(event: KeyboardEvent) {
  const character = event.key;
  if (character.length === 1) {

    let value = this.myForm.controls.myControl.value;
    if (typeof value === 'object') {
      value = value.name;
    }

    value = (value + character).toLowerCase();

    if (!this.options.some(option => option.name.toLowerCase().indexOf(value) === 0)) {
      event.preventDefault();
    }
  } 
}

This works with any kind of form.

Stackblitz