0

I created a quiz by using VueJS. However, there is something that blocks me from clicking on radio buttons. It will check another radio button rather than the one that I want.

HTML code

<div id="app">
      <h1>{{ quiz.title }}</h1>
      <div v-for="(question, index) in quiz.questions" class="question-content">       
        <div v-show="index === questionIndex" class="question-box">
          <h4>{{ question.text }}</h4>
          <ol>
            <li v-for="response in question.responses">
              <label>
                <input type="radio"
                       v-bind:value="response.correct"
                       v-bind:name="index"
                       v-model="userResponses[index]"> {{response.text}}
              </label>
            </li>
          </ol>
          <button v-if="questionIndex > 0" v-on:click="prev">
            Prev
          </button>
          <button v-on:click="next">
            Next
          </button>
        </div>
      </div>
      <div v-show="questionIndex === quiz.questions.length">
        <h2>
        Quiz finished
      </h2>
        <p>
          Total score: {{ score() }} / {{ quiz.questions.length }}
        </p>
        <button v-on:click="start">
          Restart
        </button>
      </div>
    </div>

VueJS code

// A question has one or more answer, and one or more is valid.
var quiz = {
  title: 'Quiz',
  questions: [
   {
      text: "1. Which of the following is a category or element of the balance sheet?",
      responses: [
        {text: 'Expenses'},
        {text: 'Gains'},
        {text: 'Liabilities', correct: true},
        {text: 'Losses'},
      ]

    }, {
      text: "2. Which of the following is an asset account?",
      responses: [
        {text: 'Accounts Payable'},
        {text: 'Prepaid Insurance', correct: true},
        {text: 'Unearned Revenue'}
      ]
    }
  ]
};

new Vue({
  el: '#app',
  data: {
    quiz: quiz,
    // Store current question index
    questionIndex: 0,
    // An array initialized with "false" values for each question
    // It means: "did the user answered correctly to the question n?" "no".
    userResponses: Array(quiz.questions.length).fill(false)
  },
  // The view will trigger these methods on click
  methods: {
    // Go to next question
    next: function() {
      this.questionIndex++;
    },
    // Go to previous question
    prev: function() {
      this.questionIndex--;
    },
    // Return "true" count in userResponses
    score: function() {
      return this.userResponses.filter(function(val) { return val }).length;
    },

    // Restart quiz
    start: function() {
      this.questionIndex = 0;
    }
  }
});

You can check the live code at : https://jsfiddle.net/dalenguyen/z4rj62c6/1/

2 Answers 2

1

Use Nested index for name attribute.

HTML

 <div id="app">
  <h1>{{ quiz.title }}</h1>
  <div v-for="(question, index) in quiz.questions" class="question-content">
    <div v-show="index === questionIndex" class="question-box">
      <h4>{{ question.text }}</h4>
      <ol>
        <li v-for="(response, child_index) in question.responses">
          <label>
            <input type="radio" v-bind:value="response.text" v-bind:name="response.text" v-model="userResponses[index]"> {{response.text}}
          </label>
        </li>
      </ol>
      <button v-if="questionIndex > 0" v-on:click="prev">
        Prev
      </button>
      <button v-on:click="next">
        Next
      </button>
    </div>
  </div>
  <div v-show="questionIndex === quiz.questions.length">
    <h2>
        Quiz finished
      </h2>
    <p>
      Total score: {{ score() }} / {{ quiz.questions.length }}
    </p>
    <button v-on:click="start">
      Restart
    </button>
  </div>
</div>

JS: Calculate Correct Ans

 score: function() {
      correctCount = 0;
      that = this;
      this.quiz.questions.filter(function(val, i) {
        val.userAnswerCorrect = false;
        val.userAnswer = that.userResponses[i];

        val.responses.filter(function(ans, j) {
          if (ans.correct == true && val.userAnswer == ans.text) {
            correctCount++;
          }

        })
      });

      return correctCount;
    }

Demo: https://jsfiddle.net/sumitridhal/esshqr25/

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

3 Comments

Thanks @Sumit Ridhal for your explanation. I still have a little bug. Do you know how to uncheck the radio button when pressing the restart button? I tried but couldn't find a proper answer for it.
Empty userResponses in restart function: Demo: jsfiddle.net/sumitridhal/esshqr25 // Restart quiz start: function() { this.userResponses = []; this.questionIndex = 0; }
Thanks @Sumit Ridhal for your great help!
0

Just doing the following change will make it work:

 v-bind:value="response.text"

response.correct was making all other values undefined, so the radio was getting confused which is the correct value!

I hope that helps!

1 Comment

Thanks @aks. That allows the radio button to work. The correct answer still needs to be solved, but Sumit Ridhal redone it above.

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.