Angular 2 Material. Using an example of MD autocomplete in a form
Is there a way to work with autocomplete inside a form? I have a form that takes input for an address. I'm using autocomplete ( copied from Material Design docs ) for states (that's in the US) and it works, except the selected state is not set in user.state. So when I exit the console, myForm.form.value when submitted looks like this:
user.name : "Test"
user.phone: ...
etc.
with user.state not even showing.
My (related) code:
<md-input-container>
<input
mdInput
placeholder="State"
[mdAutocomplete]="auto"
[formControl]="stateCtrl"
name="user.state"
[(ngModel)]="user.state"
>
</md-input-container>
<md-autocomplete
#auto="mdAutocomplete"
>
<md-option
*ngFor="let state of filteredStates | async" [value]="state"
(onSelectionChange)="selectState(state)"
>
{{ state }}
</md-option>
</md-autocomplete>
TS:
constructor(public dialog: MdDialog,) {
this.stateCtrl = new FormControl();
this.filteredStates = this.stateCtrl.valueChanges
.startWith(null)
.map(name => this.filterStates(name));
}
filterStates(val: string) {
return val ? this.states.filter(s => new RegExp(`^${val}`, 'gi').test(s))
: this.states;
}
Even when I try to use (onSelectionChange) to call the selectState (state) function to set the user.state, it still doesn't appear when I console.log the form on submit.
selectState(value){
this.user.state = value;
}
source to share
Take a look at this GitHub example: Demo with md autocomplete (forms)
There is an example with both reactive and templated form. With a template driven form, you completely remove formControl
and just use [(ngModel)]
and (ngModelChange)
. Here's a sample for you with a template solution:
<form #f="ngForm">
<md-input-container>
<input mdInput placeholder="State" [mdAutocomplete]="tdAuto" name="state"
#state="ngModel" [(ngModel)]="currentState"
(ngModelChange)="tdStates = filterStates(currentState)">
</md-input-container>
<md-autocomplete #tdAuto="mdAutocomplete">
<md-option *ngFor="let state of tdStates" [value]="state">
<span>{{ state }}</span>
</md-option>
</md-autocomplete>
</form>
and in the component, we will assign the filtered value to another variable ( tdStates
) and store all states in an array states
:
filterStates(val: string) { if (val) { const filterValue = val.toLowerCase(); return this.states.filter(state => state.toLowerCase().startsWith(filterValue)); } return this.states; }
source to share
I gave an example form
from the materials site and added md-autocomplete
to it. In the demo, you can filter and select the state from autocomplete. When the form is submitted, you can see that the value is being passed to alert
.
HTML:
Full code in plunker demo
<form>
// add all form code
<md-autocomplete #auto="mdAutocomplete" >
<md-option *ngFor="let state of filteredStates | async" [value]="state" (onSelectionChange)="selectState(state, addForm.value)">
{{ state }}
</md-option>
</md-autocomplete>
</form>
app.ts:
selectState(state, form){
form.state = state;
}
source to share