Reputation: 1521
I've managed to get a Select list to bind with my model for the purpose of saving, but I cannot work out how to make Angular2 automatically select the correct option on the Select list if I'm providing editing functionality. In other words, if I'm editing a pre-existing object via a form, I need the Select list to reflect the initial state of the object (e.g. option 5 in the select list), rather than it just defaulting to the first item.
<select [ngModel]="originalObject">
<option *ngFor="let object of objects" [ngValue]="object">{{object.name}}</option>
</select>
How I imagine it should work, but doesn't!
<select [ngModel]="originalObject">
<option *ngFor="let object of objects" [ngValue]="object" [selected]="object === originalObject">{{object.name}}</option>
</select>
So essentially I'm trying to make use of the 'selected' property on option, but for whatever reason it doesn't do anything. The 'selectedObject' in this case would be an object in the component that it can read.
Upvotes: 53
Views: 117696
Reputation: 1195
The easiest way to solve this problem in Angular is to do:
In Template:
<select [ngModel]="selectedObjectIndex">
<option [value]="i" *ngFor="let object of objects; let i = index;">{{object.name}}</option>
</select>
In your class:
this.selectedObjectIndex = 1/0/your number wich item should be selected
Upvotes: 0
Reputation: 726
Update to angular 4.X.X, there is a new way to mark an option selected:
<select [compareWith]="byId" [(ngModel)]="selectedItem">
<option *ngFor="let item of items" [ngValue]="item">{{item.name}}
</option>
</select>
byId(item1: ItemModel, item2: ItemModel) {
return item1.id === item2.id;
}
Some tutorial here
Upvotes: 56
Reputation: 2748
I hope it will help someone ! (works on Angular 6)
I had to add lots of select/options dynamically and following worked for me:
<div *ngFor="let option of model.q_options; let ind=index;">
<select
[(ngModel)]="model.q_options[ind].type"
[ngModelOptions]="{standalone: true}"
>
<option
*ngFor="let object of objects"
[ngValue]="object.type"
[selected]="object.type === model.q_options[ind].type"
>{{object.name}}
</option>
</select>
<div [ngSwitch]="model.q_options[ind].type">
( here <div *ngSwitchCase="'text' or 'imagelocal' or etc."> is used to add specific input forms )
</div>
</div>
and in *.ts
// initial state of the model
// q_options in html = NewOption and its second argument is option type
model = new NewQuestion(1, null, 2,
[
new NewOption(0, 'text', '', 1),
new NewOption(1, 'imagelocal', '', 1)
]);
// dropdown options
objects = [
{type: 'text', name: 'text'},
{type: 'imagelocal', name: 'image - local file'},
{type: 'imageurl', name: 'image URL'}
( and etc.)
];
When user adds one more 'input option' (pls do not confuse 'input option' with select/options - select/options are static here) specific select/option, selected by the user earlier, is preserved on each/all dynamically added 'input option's select/options.
Upvotes: 0
Reputation: 103
You can achieve the same using
<select [ngModel]="object">
<option *ngFor="let object of objects;let i= index;" [value]="object.value" selected="i==0">{{object.name}}</option>
</select>
Upvotes: 3
Reputation: 657058
If you use
<select [ngModel]="object">
<option *ngFor="let object of objects" [ngValue]="object">{{object.name}}</option>
</select>
You need to set the property object
in you components class to the item from objects
that you want to have pre-selected.
class MyComponent {
object;
objects = [{name: 'a'}, {name: 'b'}, {name: 'c'}];
constructor() {
this.object = this.objects[1];
}
}
Upvotes: 9
Reputation: 1521
Okay, so I figured out what the problem was, and the approach I believe works best. In my case, because the two objects weren't identical from a Javascript perspective, as in: they may have shared the same values, but they were different actual objects, e.g. originalObject
was instantiated entirely separately from objects
which was essentially an array of reference data (to populate the dropdown).
I found that the approach that worked best for me was to compare a unique property of the objects, rather than directly compare the two entire objects. This comparison is done in the bound property selected
:
<select [ngModel]="originalObject">
<option *ngFor="let object of objects" [ngValue]="object" [selected]="object.uniqueId === originalObject.uniqueId">{{object.name}}</option>
</select>
Upvotes: 62