Hope you all can help here.
I have a drop-down menu that I'm using v-bind
to assign an array to the selected value. See below-
<select v-model="selected" name="SKU[]" @onChange>
<option v-for="infos in data" v-bind:value="{ level: infos.stockLevel, SKU: infos.SKU }" @change="onChange($event)" >{{infos.SKU}} </option>
</select>
There are multiple menus and I'm storing the selected options in SKU[]
and then passing them to a form via a post.
The problem is my controller is now reading SKU[]
as this:
array:2 [▼
0 => "[object Object]"
1 => "[object Object]"
]
I want to store infos.SKU
in SKU[]
, not object object
.
Any idea how I can do this?
CodePudding user response:
You can't store javascript objects in html. You can use there only strings, so you should call JSON.stringify()
method with your object and then pass into value. Than you will be able to use it as an object after JSON.parse()
.
But the best case is to use another vue component for options or pass only id of object in value
CodePudding user response:
Instead of passing an event in @change
event, you can directly pass the selected v-model
attribute and then push the data object into SKU
data variable.
Live Demo :
new Vue({
el: '#app',
data: {
data: [{
stockLevel: 'Level 1',
SKU: 'SKU 1'
}, {
stockLevel: 'Level 2',
SKU: 'SKU 2'
}, {
stockLevel: 'Level 3',
SKU: 'SKU 3'
}, {
stockLevel: 'Level 4',
SKU: 'SKU 4'
}],
selected: '',
SKU: []
},
methods: {
onChange(selectedValue) {
if (!JSON.stringify(this.SKU).includes(JSON.stringify(selectedValue))) {
this.SKU.push(selectedValue);
}
console.log(this.SKU);
}
}
})
<script src="https://cdnjs.cloudflare.com/ajax/libs/vue/2.5.17/vue.js"></script>
<div id="app">
<select v-model="selected" @change="onChange(selected)">
<option
v-for="(infos, index) in data"
:key="index"
v-bind:value="{ level: infos.stockLevel, SKU: infos.SKU }"
>
{{infos.SKU}}
</option>
</select>
</div>
CodePudding user response:
First of all, I am not sure how are you managing multiple selections because without using the multiple
prop or any other way, at a time only a single value would be displayed as selected which seems vague from a "multiple-selection UI" perspective.
Secondly, there is no @onchange
syntax, it should be either onchange
or @change
.
Third, the @change
event should fire on the select
element, not the option element.
At last, your v-model
is what you are using to bind the selected element, then why not use that to track the selected element?
Here is the working demo-
<html>
<div id="app">
{{ SKU }}<br>
<select v-model="selected" @change="onChange">
<option
v-for="infos in data"
:value="{ level: infos.stockLevel, SKU: infos.SKU }"
>{{ infos.SKU }}
</option>
</select>
</div>
<!-- Don't forget to include Vue from CDN! -->
<script src="https://unpkg.com/vue@2"></script>
<script>
new Vue({
el: "#app", //Tells Vue to render in HTML element with id "app"
data() {
return {
SKU: [],
selected: null,
data: [{
stockLevel: "Stock level 1",
SKU: "SKU 1",
},
{
stockLevel: "Stock level 2",
SKU: "SKU 2",
},
],
};
},
methods: {
onChange() {
// Do not push if already exists. I assumed "SKU" was a unique property.
if (this.SKU.find(item => item.SKU == this.selected.SKU)) return;
this.SKU.push(this.selected)
},
},
});
</script>
</html>