I have 2 arrays of objects like below. I need to create a select for every questions
element, and I need to have the options connected with the selections
by the id. In this case I need to have 2 selects, the first one will have 1000
, 5000
and 10000
as options meanwhile the second select will have yes
and no
as options
const questions = [{
'id': 1,
'question': 'KM'
},
{
'id': 2,
'question': 'Works'
}
]
const selections = [{
'question_id': 1,
'value': 1000
},
{
'question_id': 1,
'value': 5000
},
{
'question_id': 1,
'value': 10000
},
{
'question_id': 2,
'value': 'yes'
},
{
'question_id': 2,
'value': 'no'
}
]
I made it like this in vue but the issue is that I can't save the data in the v-model as I'm returning the values from cars()
and not a variable specified in data()
<div class="form-group" v-for="item in questions" v-bind:key="item.question">
<h5 v-if="showQuestion(item.id)">{{ item.question }}</h5>
<div class="tour-options-select" v-if="showQuestion(item.id)">
<select id="select-suggestions" name="tour-options-dropdown" class="tour-options-dropdown" v-model="questions.value">
<option v-for="item1 in cars(item.id)" v-bind:key="item1.id" :value="item1.display_name">{{ item1.display_name }}</option>
</select>
</div>
</div>
Ultimately, I just need to know, how do I get the value when I have a structure like the one I defined above?
If you have an array in data()
to store your selected options, you can use v-model
to dynamically bind with an element in that array if you give it an index:
new Vue({
el: '#app',
data: {
questions: [{
'id': 1,
'question': 'KM'
},
{
'id': 2,
'question': 'Works'
}
],
selections: [{
'question_id': 1,
'value': 1000
},
{
'question_id': 1,
'value': 5000
},
{
'question_id': 1,
'value': 10000
},
{
'question_id': 2,
'value': 'yes'
},
{
'question_id': 2,
'value': 'no'
}
],
selected: [],
},
methods: {
cars: function(id) {
return this.selections.reduce((arr, currSel) => {
if (currSel.question_id == id)
arr.push(currSel);
return arr;
}, []);
},
}
});
<script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
<div id="app">
<div v-for="(question, index) in questions" :name="question.question" :key="question.id">
<select v-model="selected[index]">
<option v-for="option in cars(question.id)" :key="option.question_id" :value="option.value">
{{ option.value }}
</option>
</select>
</div>
<p>Selected:</p>
<pre>{{ $data.selected }}</pre>
</div>
Another approach would be to use events to handle the changes, calling a custom function each time the user makes a selection, eg using @change
:
new Vue({
el: '#app',
data: {
questions: [{
'id': 1,
'question': 'KM'
},
{
'id': 2,
'question': 'Works'
}
],
selections: [{
'question_id': 1,
'value': 1000
},
{
'question_id': 1,
'value': 5000
},
{
'question_id': 1,
'value': 10000
},
{
'question_id': 2,
'value': 'yes'
},
{
'question_id': 2,
'value': 'no'
}
],
},
methods: {
cars: function(id) {
return this.selections.reduce((arr, currSel) => {
if (currSel.question_id == id)
arr.push(currSel);
return arr;
}, []);
},
}
});
<script src="https://unpkg.com/vue@2.6.12/dist/vue.min.js"></script>
<div id="app">
<div v-for="(question, index) in questions" :name="question.question" :key="question.id">
<select @change="console.log('Option', $event.target.value, 'chosen for Q', question.id)">
<option selected disabled>Select...</option>
<option v-for="option in cars(question.id)" :key="option.question_id" :value="option.value">
{{ option.value }}
</option>
</select>
</div>
</div>
This way will give you more freedom to store or process the data as you wish, but you'll have to do it manually.