I'm using select
with v-model
and have options with v-for
and object as a value. Options are some elements identified by id. How do I make option preselected based on custom equality (in this case by equal id
field)? I'm looking for something similar to angularjs' track by
from ng-options
.
/
How to make the input preselected with the value with equal id?
template:
<div id="vue-instance">
<select v-model="selected">
<option v-for="item in inventory" :value="item" :key="item.id">
{{ item.name }}
</option>
</select>
<p>
{{ selected.id }}
</p>
</div>
js:
var vm = new Vue({
el: '#vue-instance',
data: {
inventory: [
{name: 'MacBook Air', id: 1},
{name: 'MacBook Pro', id: 2},
{name: 'Lenovo W530', id: 3},
{name: 'Acer Aspire One', id: 4}
],
selected: {
id: 2
}
}
});
I'm using select
with v-model
and have options with v-for
and object as a value. Options are some elements identified by id. How do I make option preselected based on custom equality (in this case by equal id
field)? I'm looking for something similar to angularjs' track by
from ng-options
.
https://jsfiddle/79wsf1n4/5/
How to make the input preselected with the value with equal id?
template:
<div id="vue-instance">
<select v-model="selected">
<option v-for="item in inventory" :value="item" :key="item.id">
{{ item.name }}
</option>
</select>
<p>
{{ selected.id }}
</p>
</div>
js:
var vm = new Vue({
el: '#vue-instance',
data: {
inventory: [
{name: 'MacBook Air', id: 1},
{name: 'MacBook Pro', id: 2},
{name: 'Lenovo W530', id: 3},
{name: 'Acer Aspire One', id: 4}
],
selected: {
id: 2
}
}
});
Share
Improve this question
edited Apr 12, 2017 at 10:54
Tuan Pham
asked Apr 12, 2017 at 10:17
Tuan PhamTuan Pham
1,1202 gold badges15 silver badges29 bronze badges
2
-
Careful with the ma :
:value="item", :key="item.id"
(delete it !) – Happyriri Commented Apr 12, 2017 at 10:22 - @SLYcee Thanks :) – Tuan Pham Commented Apr 12, 2017 at 10:25
3 Answers
Reset to default 7You could add the selected attribute as per Dharmendra's answer.
The issue however is that you're not assigning a valid object to your selected property. Vue will try to look for an identical object in your option list, it will do this by object equality parison.
At this time I'm not aware whether it's possible to tell Vue to base the initial selection on an attribute, however a very simple solution is to assign the selected property based on the ID yourself in the created lifecycle callback:
var vm = new Vue({
el: '#vue-instance',
data: {
inventory: [
{name: 'MacBook Air', id: 1},
{name: 'MacBook Pro', id: 2},
{name: 'Lenovo W530', id: 3},
{name: 'Acer Aspire One', id: 4}
],
selected: 2
},
created: function() {
this.selected = this.inventory.find(i => i.id === this.selected);
}
});
I've updated your Fiddle as well.
You have to change the way you are assigning value to option. change this :value="item"
to v-bind:value="item"
.
HTML part
<select class="form-control" name="template" v-model="selected">
<option v-for="item in inventory" v-bind:value="item">
{{ item.name }}
</option>
</select>
JS part
new Vue({
el: '#selector',
data: {
...
selected: {name: 'MacBook Pro', id: 2}
}
})
Here is a working fiddle
There is a lot of code you don't need but useful to test the behavior (in your case you need to set initSelect
with id
or name
) :
var vm = new Vue({
el: '#vue-instance',
data: {
inventory: [
{name: 'MacBook Air', id: 1},
{name: 'MacBook Pro', id: 2},
{name: 'Lenovo W530', id: 3},
{name: 'Acer Aspire One', id: 4}
],
initSelect : {
id: 2
},
selected: {},
},
created: function() {
this.setSelectedWithInit();
},
methods: {
setSelectedWithInit: function() {
var firstKey = Object.keys(this.initSelect)[0],
value = this.initSelect[firstKey];
for( var i = 0, length = this.inventory.length; i < length; i++ ) {
if( (this.inventory[i].hasOwnProperty(firstKey))
&& (this.inventory[i][firstKey] === value) )
{
this.selected = this.inventory[i];
return;
}
}
},
toggle: function() {//you don't need this method
if( this.initSelect.hasOwnProperty('id') ) {
this.initSelect = { name: 'Lenovo W530' };
} else {
this.initSelect = { id: 2 };
}
}
},
watch: {
'initSelect': {
handler: function (val, oldVal) {
this.setSelectedWithInit();
},
deep: true
}
}
});
<script src="https://cdnjs.cloudflare./ajax/libs/vue/2.2.5/vue.js"></script>
<div id="vue-instance">
<select v-model="selected">
<option v-for="item in inventory" :value="item" :key="item.id">
{{ item.name }}
</option>
</select>
<p>
{{ initSelect.id }}
{{ initSelect.name }}
</p>
<!-- You don't need the rest of the html below -->
<button @click="toggle">Toggle id/name</button>
<div v-if="initSelect.hasOwnProperty('id')">
Id: <input v-model.number="initSelect.id" type="number">
</div>
<div v-else>
Name: <input v-model="initSelect.name" type="text">
</div>
<br><br>
{{ initSelect }}
</div>