I have an Angular Application, I want to implement and Autocomplete Dropdown in my Application, I checked the sample code from Angular material, its not perfect, and does allow users to type even after they select an option. and it does not validate. I want something like this (https://bootsnipp.com/snippets/0Bn1j ) and my options should be as Key Value, Key should be CountryID and Value should be CountryName I am new to This any help would be appreciated. I saw an example here (https://stackblitz.com/edit/angular-autocomplete-validation?file=src%2Fapp%2Fautocomplete-validation-example.html) but its options is string my option is coming from database table with CountryId and CountryName
component.ts:
function autocompleteStringValidator(validOptions: Array<string>): ValidatorFn {
console.log(validOptions);
return (control: AbstractControl): { [key: string]: any } | null => {
if (validOptions.indexOf(control.value) !== -1) {
return null /* valid option selected */
}
return { 'invalidAutocompleteString': { value: control.value } }
}
}
export class TasksformComponent implements OnInit {
public phoneLabelOptions: any[] = [];
public filteredPhoneLabelOptions: Observable<any[]>
public phoneLabelAutocompleteControl = new FormControl('',
{ validators: [autocompleteStringValidator(this.phoneLabelOptions), Validators.required] })
public validation_msgs = {
'contactAutocompleteControl': [
{ type: 'invalidAutocompleteObject', message: 'Contact name not recognized. Click one of the autocomplete options.' },
{ type: 'required', message: 'Contact is required.' }
],
'phoneLabelAutocompleteControl': [
{ type: 'invalidAutocompleteString', message: 'Phone label not recognized. Click one of the autocomplete options.' },
{ type: 'required', message: 'Phone label is required.' }
]
}
private _filterPhoneLabels(label: any): any[] {
console.log('---cling----');
console.log(label);
if (label === '') {
return this.phoneLabelOptions.slice()
}
const filterValue = label.toLowerCase()
return this.phoneLabelOptions.filter(option => option.Name.toLowerCase().includes(filterValue))
}
ngOnInit(): void{
this.filteredPhoneLabelOptions = this.phoneLabelAutocompleteControl.valueChanges.pipe(
startWith(''),
map((value) => {
console.log('---ite here----');
console.log(value);
return this._filterPhoneLabels(value)
})
)
let lookupTablename: string;
console.log('------'+this.categoryID);
this.selected = this.categoryID;
this.lookupService.getLookupByTableAlias((lookupTablename = 'category')).subscribe(
(icategory: any) => {
this.category = icategory;
//console.log(icategory);
icategory.forEach((item)=>{
this.phoneLabelOptions.push({ID:item.ID, Name:item.Name});
});
console.log(this.phoneLabelOptions);
},
error => {
const res = this.dialogService.ErrorDialog('Server Error', 'Sorry, the system is unavailable at the moment.', 'Close', 'Try Again');
res.afterClosed().subscribe(dialogResult => {
if (dialogResult) {
this.callNext(4000);
}
});
}
);
}
component.html:
<mat-form-field>
<input type="text" placeholder="Phone label" aria-label="Phone label" matInput
[formControl]="phoneLabelAutocompleteControl" [matAutocomplete]="autoPhoneLabel">
<mat-autocomplete #autoPhoneLabel="matAutocomplete">
<mat-option *ngFor="let label of filteredPhoneLabelOptions | async" [value]="label.ID">
{{label.Name}}
</mat-option>
</mat-autocomplete>
<mat-error *ngFor="let validation of validation_msgs.phoneLabelAutocompleteControl">
<div *ngIf="phoneLabelAutocompleteControl.hasError(validation.type)">
{{validation.message}}
</div>
</mat-error>
</mat-form-field>