I have an Angular Material Autocomplete drop-down with a filter that filters by CustomerName
.
This was implemented via my returned Customers from my getAllCustomers()
method. I then do a loop
through each Customer
to push
the CustomerName
into a new array
, which essentially becomes my filteredOptions
.
My question is: How can I implement this filter with the search on the CustomerName, but have a binding to the Id of each Customer?
In the object
that I eventually want to save, I want to save the Customer.Id
and not the CustomerName
.
I have tried creating a new object array
, containing both the CustomerName
and Id
, but this does not work with the filteredOptions
and filter
method. It seems like the filter
method only takes an array
with single values and not objects
.
Also, I would need to bind this correctly in my HTML
.
Here is my basic fileredOptions
implementation: (Note: I included my object
{name: element.CustomerName, id: element.Id}
that I wish to use. This doesn't work as explained. The working method simply pushes element.CustomerName
into the array
:
filteredOptions: Observable<string[]>;
constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }
ngOnInit() {
this.getAllCustomers();
}
filter(val: string): string[] {
return this.customerNameArray.filter(option => option.toLowerCase().indexOf(val.toLowerCase()) === 0);
}
getAllCustomers() {
this.loadDataService.getAllCustomers()
.subscribe(data => {
this.customerArray = data;
let thisArray = [];
this.customerArray.forEach(element => {
thisArray.push({name: element.CustomerName, id: element.Id});
});
this.customerNameArray = thisArray;
this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
startWith(''),
map(val => this.filter(val))
);
});
}
Here is my HTML
:
<mat-form-field>
<input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
Answers 1 : of How to clear mat- autocomplete when no option is selected from autocomplete dropdown. You can remove the formControl-binding from your input and when you select an option you set that id to your form.
Simple autocompleteStart by creating the autocomplete panel and the options displayed inside it. Each option should be defined by a mat-option tag. Set each option's value property to whatever you'd like the value of the text input to be when that option is selected.
The <mat-autocomplete>, an Angular Directive, is used as a special input control with an inbuilt dropdown to show all possible matches to a custom query. This control acts as a real-time suggestion box as soon as the user types in the input area.
If 'mat-option' is an Angular component and it has 'value' input, then verify that it is part of this module. If 'mat-option' is a Web Component then add 'CUSTOM_ELEMENTS_SCHEMA' to the '@NgModule. schemas' of this component to suppress this message.
If you use an object for your options, you will need to modify your filter function and filteredOptions to use the object and not a string array. You will also need to use the displayWith feature of mat-autocomplete to allow the input to work with the object. A stackblitz example is here.
Your code:
export class Customer{
constructor(public CustomerName: string, public Id: number) { }
}
...
filteredOptions: Observable<Customer[]>;
constructor(private loadDataService: LoadDataService, private assetDataService: AssetDataService, private router: Router, private toastr: ToastrService) { }
ngOnInit() {
this.getAllCustomers();
}
filter(val: any) {
let name = val.CustomerName || val; // val can be Customer or string
return this.customerNameArray.filter(option => option.CustomerName.toLowerCase().indexOf(name.toLowerCase()) === 0);
}
getAllCustomers() {
this.loadDataService.getAllCustomers()
.subscribe(data => {
this.customerArray = data;
let thisArray = [];
this.customerArray.forEach(element => {
thisArray.push(new Customer(element.CustomerName, element.Id));
});
this.customerNameArray = thisArray;
this.filteredOptions = this.myCustomerSearchControl.valueChanges.pipe(
startWith(null),
map(val => this.filter(val))
);
});
}
displayCustomer(cust: Customer) {
return cust ? cust.CustomerName : '';
}
HTML:
<mat-form-field>
<input type="text" placeholder="Customer Search" aria-label="Number" matInput [formControl]="myCustomerSearchControl" [matAutocomplete]="auto">
<mat-autocomplete autoActiveFirstOption #auto="matAutocomplete" [displayWith]="displayCustomer">
<mat-option *ngFor="let option of filteredOptions | async" [value]="option">
{{ option.CustomerName }}
</mat-option>
</mat-autocomplete>
</mat-form-field>
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With