Angular Material: How to validate Autocomplete against suggested options?

偶尔善良 提交于 2020-01-24 02:23:08

问题


We have an autocomplete input with required validation. When a user searches for an option by entering a query (but doesn't pick any of the options) then the input is valid, even though it doesn't match any of the suggested options.

What I want to achieve is not permitting the user to post the form unless one of the suggested options is selected. How do I achieve this?

<mat-form-field>
   <input matInput placeholder="Pick one" aria-label="pick one" [matAutocomplete]="auto" [formControl]="form.controls['SELECTBOX_VALUE']">
      <mat-autocomplete #auto="matAutocomplete">
           <mat-option *ngFor="let option of myOptions | async" [value]="option.name"> <span>{{ option.name }}</span> </mat-option>
            </mat-autocomplete>
</mat-form-field>
<small *ngIf="!form.controls['SELECTBOX_VALUE'].valid && form.controls['SELECTBOX_DEGER'].touched" class="mat-text-warn">Please select.</small>

ngOnInit() {
    this.form = this.fb.group({
        ... some other fields
        SELECTBOX_VALUE: [null, Validators.required]
    });

My filter code for Autocomplate is pretty straight forward:

this.form.get('SELECTBOX_VALUE').valueChanges
        .pipe(
            startWith(''),
            map(option => secenek ? this.doFilter(option) : this.options.slice())
        );

doFilter (name: string) {
    return this.myOptions.filter(option =>
        option.name.toLowerCase().indexOf(name.toLowerCase()) === 0);
}

回答1:


For those who may need a similar approach. Here's my solution. I've built a custom validation rule according to my needs.

SELECTBOX_VALUE: [null, Validators.compose(
  [Validators.required, FormCustomValidators.valueSelected(this.myArray)]
)]

export class FormCustomValidators {
  static valueSelected(myArray: any[]): ValidatorFn {

    return (c: AbstractControl): { [key: string]: boolean } | null => {
      let selectboxValue = c.value;
      let pickedOrNot = myArray.filter(alias => alias.name === selectboxValue);

      if (pickedOrNot.length > 0) {
        // everything's fine. return no error. therefore it's null.
        return null;

      } else {
        //there's no matching selectboxvalue selected. so return match error.
        return { 'match': true };
      }
    }
  }
}



回答2:


There are two scenarios with Angular Material Autocomplete that may need to be validated against a list of selected options:

  1. Array of strings - Suggested options are defined in an array of strings
  2. Array of Objects - Suggested options are an object property defined on an array of Objects (In this scenario, displayWith Input would be used.)

** Stackblitz Demo **

Validate Options from Array of strings

To validate autocomplete against an array of string options, the validator may accept the array of options and check if the control value is included.

function autocompleteStringValidator(validOptions: Array<string>): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    if (validOptions.indexOf(control.value) !== -1) {
      return null  /* valid option selected */
    }
    return { 'invalidAutocompleteString': { value: control.value } }
  }
}

The validator could be added to a FormControl along with other built-in validators such as Validators.required:

public autocompleteControl = new FormControl('', 
      { validators: [autocompleteStringValidator(this.options), Validators.required] })

Validate Options from Array of Objects

To validate autocomplete against an array of object options, the validator can leverage the fact that the control.value will only be a string if a valid Object option has not been selected.

function autocompleteObjectValidator(): ValidatorFn {
  return (control: AbstractControl): { [key: string]: any } | null => {
    if (typeof control.value === 'string') {
      return { 'invalidAutocompleteObject': { value: control.value } }
    }
    return null  /* valid option selected */
  }
}



回答3:


You can add on your Submit function a validation check for the fields,

Submit() {
 if(this.form.valid) {
   // send to API
 } else {
   // show error
 }
}


来源:https://stackoverflow.com/questions/51871720/angular-material-how-to-validate-autocomplete-against-suggested-options

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!