Is there a way to have the autocomplete work inside a form? I have a form that takes input for an address. I'm using autocomplete (copied from Material Design's docs) for states (this is in the US) and that is working except that the selected state is not being set to user.state. So when I console log out the myForm.form.value on submit it looks like this:
user.name : "Test"
user.phone: ...
etc.
with user.state not even showing up.
My (relevant) 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 function selectState(state) to set the user.state it still doesn't show up when I console.log the form on submit.
selectState(value){
this.user.state = value;
}
Take a look at this GitHub example: Demo with md-autocomplete (forms)
There is an example with both reactive and template-driven form. With the template driven form you remove the formControl
completely, and just use [(ngModel)]
and (ngModelChange)
instead. Here's sample for you with the template-driven 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 component we assign the filtered value to a different variable (tdStates
) and keep all states in the states
array:
filterStates(val: string) {
if (val) {
const filterValue = val.toLowerCase();
return this.states.filter(state => state.toLowerCase().startsWith(filterValue));
}
return this.states;
}
DEMO
I have taken the example form
from material's website and added md-autocomplete
to it. In the demo, you can filter and select a state from the autocomplete. When the form is submitted, you can see the value getting 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;
}
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