简体   繁体   中英

Vue-js remember check box choices for every question

I'm making a quiz app. I have question selection menu and I need to save each checkbox state for each question. For example, if you were to select an answer for 1st question, I need to save your choices even if you skip to 3rd question so when you come back to 1st your old choices are still there.

Now the problem that I have is - my checkboxes aren't unique, they are same for each question. Please take a look at gif on what happens.

在此处输入图片说明 https://i.imgur.com/hua2NI8.gif

This is my code

<template>
  <div v-if="loading"><loader></loader></div>
  <div v-else class="main">
    <h5 class="test-title">Test</h5>
    <h5 class="choosequestion">
      <font-awesome-icon icon="list-ul" style="margin-right: 8px" />Choose question
    </h5>
    <div v-dragscroll="true" class="questionsbox">
      <!-- answered, current -->
      <input v-for="(question, index) in questions" :key="index" :value="index + 1" @click="chooseQuestion(index)" class="questionbox" type="button" />
    </div>
    <div class="buttons">
      <a class="ctlBtn">Restart</a>
      <a class="ctlBtn">End</a>
    </div>
    <div class="questionmain">
      <h5 class="questiontext">
        <font-awesome-icon icon="question-circle" style="margin-right: 8px" />
        {{ currentQuestion.question }}
      </h5>
      <ul>
        <li
          v-for="( answer, key ) in currentQuestion.answers"
          :index="currentQuestion.key"
          :key="answer.title"
        >
          <input v-model="checkedAnswers[key]" @change="answerClick" :id="answer.title" type="checkbox" />
          <label :for="answer.title" >{{ answer.title }}</label>
        </li>
        {{ checkedAnswers }}
      </ul>
      <img
        class="questionimg"
        :src="currentQuestion.image_url"
      />
      <a class="nextBtn" @click="nextQuestion"><font-awesome-icon icon="arrow-right" style="color: black;"/></a>
    </div>
  </div>
</template>

<script>
import { dragscroll } from "vue-dragscroll";
import Loader from "./Loader.vue";

export default {
  components: { Loader }, 
  name: "TestCard",
  data() {
    return {
      questions: [],
      loading: true,
      index: 0,
      checkedAnswers: []
    };
  },
  computed: {
    currentQuestion() {
      if (this.questions !== []) {
        return this.questions[this.index];
      }
      return null;
    },
  },
  methods: {
    async getQuestions() {
      this.loading = true;
      let response = await fetch("http://localhost:4000/test");
      let jsonResponse = await response.json();
      // put data on questions property
      this.questions = jsonResponse.questions;
      this.loading = false;
    },
    answerClick() {
      console.log("answer clicked");
    },
    chooseQuestion(index) {
      this.index = index;
    },
    nextQuestion() {
      this.index += 1;
      console.log("next question")
    }
  },
  mounted() {
    this.getQuestions();
  },
  directives: {
    dragscroll,
  },
};
</script>

After that, I would like to check if answers are correct when user presses on "End". How do I connect each checkbox to it's answer and question, then check it if its correct? I have "correct: true" in JSON for each correct answer :)

Thank you

Without changing too much of your existing code you could go about mapping your answers to questions like this. No need for Vuex or more complexity.

<template>
  ...
      <ul>
        <li
          v-for="( answer, key ) in currentQuestion.answers"
          :index="currentQuestion.key"
          :key="answer.title"
        >
// we pass the key to answerClick to be able to map the answer to the current question
          <input v-model="checkedAnswers[key]" @change="answerClick(key)" :id="answer.title" type="checkbox" />
          <label :for="answer.title" >{{ answer.title }}</label>
        </li>
        {{ checkedAnswers }}
...
</template>
</template>
<script>
export default {
  name: "TestCard",
  data() {
    return {
      questions: [],
      loading: true,
      index: 0,
      checkedAnswers: [],
      answers: []
    };
  },
  computed: {
    currentQuestion() {
      if (this.questions !== []) {
        return this.questions[this.index];
      }
      return null;
    }
  },
  methods: {
    async getQuestions() {
      this.loading = true;
      let response = await fetch("http://localhost:4000/test");
      let jsonResponse = await response.json();
      // put data on questions property
      this.questions = jsonResponse.questions;
      this.loading = false;
    },
    answerClick(key) {
      console.log("answer clicked");
      if (!this.answers[this.index]) this.answers[this.index] = [] // if the current question has no answers mapped yet set an empty array 
      this.answers[this.index][key] = this.checkedAnswers[key]; // set the answer to whatever value it has currently (true, false)
    },
    chooseQuestion(index) {
      this.index = index;
      this.checkedAnswers = this.answers[this.index] ? this.answers[this.index] : []; // set the checkedAnswers to what we can find in our mapping, if there is nothing to find use an empty array
    },
    nextQuestion() {
      this.index += 1;
      this.checkedAnswers = []; // unset the checked answers for the next question
      console.log("next question")
    }
  },
  mounted() {
    this.getQuestions();
  },
};

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM