0👍
The issue you’re running into is with how you’re using v-model
on the b-form-group-component
:
<b-form-radio-group
v-model="question_option"
:options="item.qOptions"
:name="index.toString()"
stacked
/>
You’re displaying one radio group per item, but then storing the results from all of those groups in the same, single data variable: question_option
.
In order to fix this, you’ll need to store the selected options in an array, so you can keep track of the selection for each question individually. You can either create a new array for it, or add a property to the item
objects stored in dataList
to use, whichever makes more sense to you.
In the example below, I made the following changes:
- I added a
question_option
property to each item indataList
- Changed
v-model="question_option"
tov-model="item.question_option"
- Changed the "hint" to reference
item.question_option
too - Added a span below "hint" to show the selection for the given question, just as an example to show that they’re storing properly
Example
new Vue({
el: '#app',
data() { return {
dataList: [
{
question: 'The first question',
qOptions: [ { text: 'Option 1', value: 1 },
{ text: 'Option 2', value: 2 },
{ text: 'Option 3', value: 3 },
{ text: 'Option 4', value: 4 }],
hints: 'First question hint',
question_option: '', // New option property for selection storage
},
{
question: 'The second question',
qOptions: [ { text: 'Option 1', value: 1 },
{ text: 'Option 2', value: 2 },
{ text: 'Option 3', value: 3 },
{ text: 'Option 4', value: 4 }],
hints: 'Second question hint',
question_option: '', // New option property for selection storage
},
],
}},
})
<link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap@4/dist/css/bootstrap.min.css" /><link type="text/css" rel="stylesheet" href="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.css" /><script src="//unpkg.com/vue@latest/dist/vue.min.js"></script><script src="//unpkg.com/bootstrap-vue@latest/dist/bootstrap-vue.min.js"></script>
<div id="app">
<ul class="question_list" v-for="(item, index) in dataList" :key="index">
<li>
<p><b>{{ index + 1 + '. ' + item.question }}</b></p>
<b-form-group :id="index.toString()" :name="index.toString()">
<!-- Replace "question_option" with "item.question_option" -->
<b-form-radio-group
v-model="item.question_option"
:options="item.qOptions"
:name="index.toString()"
stacked
/>
</b-form-group>
<b-card-text class="mt-1 mb-0">
<!-- Replace "question_option" with "item.question_option" -->
<p><b>Hints:</b> <span v-if="item.question_option !== ''" v-html="item.hints"></span></p>
</b-card-text>
<!-- Added a span to show selection, for clarity -->
<b-card-text class="mt-1 mb-0">
<p><b>Selected:</b> <span>{{ item.question_option }}</span></p>
</b-card-text>
</li>
</ul>
</div>
- [Vuejs]-In my Vue 3 app, all the Typescript files turn out to be accessible from the browser console
0👍
At first, you have re-assign the data Object by mapping. here is the code
dataFormatedList (data, userReviewList) {
return data.map(item => {
// Options
const mySplitP = item.options.split('<p>')
const mySplitPClose = mySplitP[1].split('</p>')[0]
const mySplitSlash = mySplitPClose.split('///')
const correctAnsIndex = mySplitSlash.findIndex(element => element.includes("@@"))
const mySplitAtTheRate = mySplitSlash[correctAnsIndex].split('@@')[1]
mySplitSlash.splice(correctAnsIndex, 1, mySplitAtTheRate)
// Question
const questionSplit = item.question.split('</p>')[0]
const question = questionSplit.split('<p>')[1]
const myOption = mySplitSlash.map((item, index) => {
const is_correct = index === correctAnsIndex ? true : false
const qOptions = {
text: item,
value: index,
is_correct: is_correct,
bg_color: 'radio_option_default_custom_design',
text_color: 'text-primary',
}
return Object.assign({}, qOptions)
})
const questionOptions = {
qOptions: myOption,
question: question,
correctAnsIndex: correctAnsIndex
}
return Object.assign({}, item, questionOptions)
})
}
for looping here
<ul class="question_list" v-for="(item, index) in dataList" :key="index">
<li>
<div v-for="(qItem, index2) in item.qOptions" :key="index2">
<div class="radio_option_bar">
<p :class="qItem.bg_color"><b-form-radio :name="'question_option' + index" v-model="question_option[index]" :value="qItem.value" @change="itemSelected(qItem, item)"><span :class="qItem.text_color">{{ qItem.text }}</span></b-form-radio></p>
</div>
</div>
<br>
</li>
</ul>
Now you have to use onchange method:
itemSelected (option, item) {
if (option.is_correct) {
option.bg_color = 'radio_option_correct_custom_design'
option.text_color = 'text-success'
} else {
option.bg_color = 'radio_option_incorrect_custom_design'
option.text_color = 'text-danger'
}
}
- [Vuejs]-Vue: Component :prop="object[key]" aren't reactive
- [Vuejs]-Csrf toke is not passing to vuejs in laravel 8
Source:stackexchange.com