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 i
There are two scenarios with Angular Material Autocomplete that may need to be validated against a list of selected options:
displayWith
Input would be used.)** Stackblitz Demo **
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] })
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 */
}
}
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 };
}
};
}
}
You can add on your Submit function a validation check for the fields,
Submit() {
if(this.form.valid) {
// send to API
} else {
// show error
}
}