I have an array
that comes from my API and I'm using Material2#AutoComplete to filter this... it's working so far, however I'm in trouble to display the another property instead of the binded value in option.
I know I have to use displayWith
, however it isn't working as I'm expecting. The function called as [displayWith]="displayFn.bind(this)">
just returns me the id
, how can I get the full object and so return the name
on function.
BTW, I still want to have the id binded in my FormControl.
Some code:
Component:
export class AutocompleteOverviewExample {
stateCtrl: FormControl;
filteredStates: any;
states = [
{
id: 1,
name: 'Alabama'
},
{
id: 2,
name: 'North Dakota'
},
{
id: 3,
name: 'Mississippi'
}
];
constructor() {
this.stateCtrl = new FormControl();
this.filteredStates = this.filterStates('');
}
onKeyUp(event: Event): void {
this.filteredStates = this.filterStates(event.target.value);
}
filterStates(val: string): Observable<any> {
let arr: any[];
console.log(val)
if (val) {
arr = this.states.filter(s => new RegExp(`^${val}`, 'gi').test(s.name));
} else {
arr = this.states;
}
// Simulates request
return Observable.of(arr);
}
displayFn(value) {
// I want to get the full object and display the name
return value;
}
}
Template:
<md-input-container>
<input mdInput placeholder="State" (keyup)="onKeyUp($event)" [mdAutocomplete]="auto" [formControl]="stateCtrl">
</md-input-container>
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn.bind(this)">
<md-option *ngFor="let state of filteredStates | async" [value]="state.id">
{{ state.name }}
</md-option>
</md-autocomplete>
Basically, it's almost the same as this question (unfortunately both answers are incorrect or throw errors).
Here's the PLUNKER.
Use displayWith to Show Object Value that's it. So, when you select any option the [displayWith] directive triggers the displayFn function which takes the object as an argument and returns the string based on the selected value.
Start 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.
If you want the entire object to be binded with md-options
, then you should bind to option with state
and return state.name
at displayFn
and this way you don't have to bind this
.
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn"> <md-option *ngFor="let state of filteredStates | async" [value]="state"> {{ state.name }} </md-option> </md-autocomplete> displayFn(state) { return state.name; }
demo plunker.
and if you want to bind only state.id
to md-options
, you have to loop through states
to find state.name
based on state.id
and this way binding this
is needed.
<md-autocomplete #auto="mdAutocomplete" [displayWith]="displayFn.bind(this)"> <md-option *ngFor="let state of filteredStates | async" [value]="state.id"> {{ state.name }} </md-option> </md-autocomplete> displayFn(id) { if (!id) return ''; let index = this.states.findIndex(state => state.id === id); return this.states[index].name; }
demo plunker.
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