2

My requirement is something like this.

  1. I am rendering a question paper from an object using v-for.
  2. Once the user select an answer for a question, the question number (index) has to be v-model with that answer. How can I achieve this? this is my code.

<template lang="html">
  <div class="container">
    <div class="" v-for="(question,index) in questions">
      <h1>Question {{index}}</h1>
      <p>{{question.question}}</p>
      <input type="radio" name="index" value="1">{{question.answer1}}<br>
      <input type="radio" name="index" value="2">{{question.answer2}}<br>
      <input type="radio" name="index" value="3">{{question.answer3}}

    </div>
    <hr>
    <button type="button" name="button" class="btn">Save and Submit</button>

  </div>
</template>

<script>
export default {
  data(){
    return{
      questions:[
        {question:"what is the capital of france?",answer1:"paris",answer2:"normandy",answer3:"rome"},
        {question:"what is the capital of france?",answer1:"paris",answer2:"normandy",answer3:"rome"},
        {question:"what is the capital of france?",answer1:"paris",answer2:"normandy",answer3:"rome"}]
    }
  }
}
</script>

3 Answers 3

3

Use a v-model to in the radioboxes.

A simple way to do that is to create a selectedAnswer property in each question and bind v-model to it, like:

<input type="radio" value="1" v-model="question.selectedAnswer">{{question.answer1}}<br>

Notice also that I removed the name. You were using the same name attributes to all checkboxes, and HTML will only allow one selected radio per group (per name)

To get an array of selected answers, you could simply create a computed property that maps the selected answers into an array. In the example below, the this.answers computed property is available with the answers.

Full demo below.

new Vue({
  el: '#app',
  data() {
    return {
      questions: [{
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome",
          selectedAnswer: null
        },
        {
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome",
          selectedAnswer: null
        },
        {
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome",
          selectedAnswer: null
        }
      ]
    }
  },
  computed: {
    answers() {
      return this.questions.map(q => q.selectedAnswer);
    }
  }
});
<script src="https://unpkg.com/vue"></script>

<div id="app">
  Answers: {{ answers }}
  <div class="container">
    <div class="" v-for="(question,index) in questions">
      <h1>Question {{index}}</h1>
      <p>{{question.question}} | selected: {{question.selectedAnswer || 'none'}}</p>
      <input type="radio" value="1" v-model="question.selectedAnswer">{{question.answer1}}<br>
      <input type="radio" value="2" v-model="question.selectedAnswer">{{question.answer2}}<br>
      <input type="radio" value="3" v-model="question.selectedAnswer">{{question.answer3}}
    </div>
    
    <hr>
    <button type="button" name="button" class="btn">Save and Submit</button>
  </div>
</div>

Sign up to request clarification or add additional context in comments.

12 Comments

This would not work. Where are you assigning the variable in the data for question.selectedAnswer? The data present as an array.
In the v-model.
Add a <p>{{question.question}} | selected {{ question.selectedAnswer }}</p> to see how it changes. I did test it before posting :D
You cannot access something directly with question.selectedAnswer when it is questions[index].selectedAnswer
There's a v-for there. question is the local variable of the v-for. It is not questionS.selectedAnswer it is question.selectedAnswer.
|
2

I feel v-model might not be the right solution in this case. Here is what I suggest you to do.

<template lang="html">
  <div class="container">
    <div class="" v-for="(question,index) in questions">
      <h1>Question {{index}}</h1>
      <p>{{question.question}}</p>
      <input type="radio" :name="index" :value="question.answer1" @click="answerSelect(index, question.answer1)">{{question.answer1}}<br>
      <input type="radio" :name="index" :value="question.answer2" @click="answerSelect(index, question.answer2)">{{question.answer2}}<br>
      <input type="radio" :name="index" :value="question.answer3" @click="answerSelect(index, question.answer3)">{{question.answer3}}

    </div>
    <hr>
    <button type="button" name="button" class="btn">Save and Submit</button>

  </div>
</template>

<script>
export default {
  data() {
    return {
      questions: [
        {
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome"
        },
        {
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome"
        },
        {
          question: "what is the capital of france?",
          answer1: "paris",
          answer2: "normandy",
          answer3: "rome"
        }
      ]
    };
  },
  methods: {
    answerSelect(questionIndex, answer) {
      const questions = [
        ...this.questions.slice(0, questionIndex),
        { ...this.questions[questionIndex], solution: answer },
        ...this.questions.slice(questionIndex + 1, this.questions.length)
      ];

      this.questions = questions;
    }
  }
};
</script>

<style>
#app {
  font-family: "Avenir", Helvetica, Arial, sans-serif;
  -webkit-font-smoothing: antialiased;
  -moz-osx-font-smoothing: grayscale;
  text-align: center;
  color: #2c3e50;
  margin-top: 60px;
}
</style>

Here is a link to the code sandbox. https://codesandbox.io/s/o5r2xqypo9

1 Comment

Yes you're correct. I follow you're method and change it further. Thanks a lot for your support! =) I attached my code as an answer as well.
2
<template lang="html">
  <div class="container">
    <div class="" v-for="(question,index) in questions">
      <h1>Question {{index}}</h1>
      <p>{{question.question}}</p>
      <input type="radio" :name="index" :value="question.answer1" @click="pushAnswers(index, 1)">{{question.answer1}}<br>
      <input type="radio" :name="index" :value="question.answer2" @click="pushAnswers(index, 2)">{{question.answer2}}<br>
      <input type="radio" :name="index" :value="question.answer3" @click="pushAnswers(index, 3)">{{question.answer3}}
    </div>
    <hr>
    <button type="button" name="button" class="btn">Save and Submit</button>
  </div>
</template>

Method

pushAnswers(questionIndex,answer) {
  this.answerSet[questionIndex] = answer;
  console.log(this.answerSet);
}

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.