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.