<div v-else-if="question.type === 'range'"><p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p><div class="form-group d-flex justify-content-center" ><label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)"><<;span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>标签>
<div v-else-if="question.type === 'range'"><p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p><div class="form-group d-flex justify-content-center"><label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers"><input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>标签>
I'm learning vue while creating a simple poll generator, but I have an issue with radio inputs.
The question can have one of two types - select or range (both are radio inputs, 'select' is a radio input single-choice question and 'range' is a radio input question with 1-5 values, as shown on the picture below; I'll have to fix the naming later...).
The problem is that while I'm rendering the poll, I have as many radio input groups as there are questions and selecting a value doesn't check the radio input.
I get the poll with questions and possible answers via axios.get.
Template fragment:
<label>Ankieta</label>
<div class="card mb-2" v-for="question in poll.Questions">
<div class="card-header p-2">{{question.question}}</div>
<div class="card-body pb-1">
<div class="form-group" v-if="question.type === 'radio'" >
<div v-for="answer in question.QuestionAnswers">
<input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)">
<label v-bind:for="answer.id">{{answer.answer}}</label>
</div>
</div>
<div v-else-if="question.type === 'range'">
<p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p>
<div class="form-group d-flex justify-content-center" >
<label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers">
<input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>
</label>
</div>
</div>
</div>
</div>
Basically do it for both the inputs of both question types (radio and range).
And adapt your method to make it checked when clicked:
updateAnswer(question, answer) {
question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));
answer.checked = true; // no need to call Vue.set because it is now reactive
The method above "unchecks" all answers of that question and then marks the clicked question as selected.
Full Demo:
new Vue({
el: '#app',
data() {
return {
submission: {
email: undefined,
age: undefined,
answers: []
},
poll: {Questions: [
{question: "radio question", id: 1, type: 'radio', QuestionAnswers: [
{id: 1, answer: 'a'}, {id: 2, answer: 'b'}
]},
{question: "range question", id: 2, type: 'range', QuestionAnswers: [
{id: 1, answer: 'a'}, {id: 2, answer: 'b'}
]}
]},
loading: false
}
},
methods: {
updateAnswer(question, answer) {
question.QuestionAnswers.forEach(a => Vue.set(a, 'checked', false));
answer.checked = true; // no need to call Vue.set because it is now reactive
let index = this.submission.answers.findIndex(q => q.questionId === question.id);
let ans = {
questionId: question.id,
answerId: answer.id
};
if (index === -1) {
this.submission.answers.push(ans);
} else {
this.submission.answers.splice(index, 1);
this.submission.answers.push(ans);
}
console.log(this.submission);
}
}
})
<script src="https://unpkg.com/vue"></script>
<div id="app">
<label>Ankieta</label>
<div class="card mb-2" v-for="question in poll.Questions">
<div class="card-header p-2">{{question.question}}</div>
<div class="card-body pb-1">
<div class="form-group" v-if="question.type === 'radio'">
<div v-for="answer in question.QuestionAnswers">
<input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked">
<label v-bind:for="answer.id">{{answer.answer}}</label>
</div>
</div>
<div v-else-if="question.type === 'range'">
<p class="text-muted mb-4 d-flex justify-content-center">W jakim stopniu zgadzasz się ze stwierdzeniem w pytaniu?<br/>1 - Bardzo się nie zgadzam, 3 - Neutralny/a, 5 - Bardzo się zgadzam<br></p>
<div class="form-group d-flex justify-content-center">
<label class="radio-inline d-flex justify-content-center w-100" v-for="answer in question.QuestionAnswers">
<input type="radio" :name="'question'+question.id" v-bind:value="answer.answer" v-on:click.prevent="updateAnswer(question, answer)" v-bind:checked="answer.checked"><span class="text-muted font-weight-bold m-1">{{answer.answer}}</span>
</label>
</div>
</div>
</div>
</div>
</div>