147 lines
5 KiB
Vue
147 lines
5 KiB
Vue
<template>
|
|
<div v-for="(q, i) in questions" :key="i">
|
|
<transition appear name="fade" mode="out-in">
|
|
<buttonQuestion
|
|
v-if="q.answerSelected || (q.questionSequence === currentQuestionNum)"
|
|
class="radioQuestion"
|
|
:class="(q.questionSequence === currentQuestionNum) && 'current-question'"
|
|
:questionText="q.questionText"
|
|
:answers="q.answers"
|
|
:groupName="`${questionData.glassName}-${questionData.glassLocation}-${i}`"
|
|
v-model="selectedValue"
|
|
isRequired
|
|
:validationRules="validationRules"
|
|
:clearOnUnmount=false
|
|
/>
|
|
</transition>
|
|
</div>
|
|
</template>
|
|
|
|
<script>
|
|
import buttonQuestion from "@/common-components/button-question/button-question";
|
|
|
|
export default {
|
|
name: "questionChain",
|
|
data() {
|
|
return {
|
|
currentQuestionNum: 1,
|
|
questions: [{ "BlankObject": "NOT USED... placeholder for question #0 to simplify indexing"}],
|
|
};
|
|
},
|
|
props: {
|
|
questionData: Object,
|
|
validationRules: String,
|
|
modelValue: Array,
|
|
partIndex: Number,
|
|
},
|
|
created() {
|
|
this.questionData.partQuestions.map((q, i) => {
|
|
let answerPair = [];
|
|
const eachQuestion = {
|
|
questionText: q.questionText,
|
|
questionSequence: q.questionSequence,
|
|
answers: q.answers.map((a) => {
|
|
answerPair.push(a.nextQuestionSequence ? a.nextQuestionSequence : a.answerResult);
|
|
return {
|
|
Text: a.answerText,
|
|
// Name will either be nextQuestionSequence or answerResult
|
|
// Name will be used by list-button as the input value.
|
|
// It must be a single string or number, so concatenating together a string with
|
|
// 4 pieces of data separated by pipe characters:
|
|
// question number|type of answer|answer value|answer text
|
|
Name: a.nextQuestionSequence ?
|
|
q.questionSequence + "|nextQuestion|" + a.nextQuestionSequence + "|" + a.answerText :
|
|
q.questionSequence + "|answer|" + a.answerResult + "|" + a.answerText,
|
|
nextQuestionSequence: a.nextQuestionSequence,
|
|
}
|
|
}),
|
|
answerSelected: "",
|
|
};
|
|
eachQuestion.answerPair = answerPair;
|
|
this.questions.push(eachQuestion);
|
|
});
|
|
},
|
|
computed: {
|
|
selectedValue: {
|
|
get: function() {
|
|
return "";
|
|
},
|
|
set: function(returnedAnswer) {
|
|
const isQuestionChainComplete = this.handleReturnedAnswer(returnedAnswer);
|
|
|
|
if (isQuestionChainComplete) {
|
|
this.$emit("update:modelValue", isQuestionChainComplete);
|
|
}
|
|
}
|
|
},
|
|
currentQuestion() {
|
|
return this.questions[this.currentQuestionNum];
|
|
},
|
|
},
|
|
methods: {
|
|
handleReturnedAnswer(returnedAnswer) { // returns either a final answer or Boolean false
|
|
if (!returnedAnswer) { return false }
|
|
|
|
// Example returnedAnswers:
|
|
// "1|nextQuestion|3|No"
|
|
// "5|answer|DW02104|Yes"
|
|
|
|
const returnedAnswerArray = returnedAnswer.split("|");
|
|
const questionNum = returnedAnswerArray[0];
|
|
const questionType = returnedAnswerArray[1];
|
|
const questionAnswer = returnedAnswerArray[2];
|
|
const questionAnswerText = returnedAnswerArray[3];
|
|
|
|
// remove all previous answers after the index of this one in questions
|
|
this.questions.map((q) => {
|
|
if ((q.questionSequence > questionNum) || (q.answerPair?.includes(questionAnswer))) {
|
|
q.answerSelected = "";
|
|
}
|
|
return q;
|
|
});
|
|
|
|
// set this question as "answered"
|
|
this.questions[questionNum].answerSelected = questionAnswerText;
|
|
this.questions[questionNum].answerNumber = questionNum;
|
|
|
|
// update to next question index
|
|
this.currentQuestionNum = questionType === "nextQuestion" ? parseInt(questionAnswer) : parseInt(questionNum); // update count to display next question
|
|
|
|
// return false if there's a nextQuestion... or return an object with "final" answers
|
|
if (questionType === "nextQuestion") {
|
|
return false;
|
|
} else {
|
|
const answeredQuestions = [];
|
|
this.questions.forEach(( q ) => {
|
|
if (q.answerSelected) {
|
|
answeredQuestions.push({
|
|
questionText: q.questionText,
|
|
selectedAnswerText: q.answerSelected,
|
|
questionNum: q.answerNumber,
|
|
});
|
|
}
|
|
});
|
|
return {
|
|
answerResult: questionAnswer,
|
|
answeredQuestions: answeredQuestions,
|
|
partIndex: this.partIndex,
|
|
};
|
|
}
|
|
},
|
|
},
|
|
watch: {
|
|
currentQuestion: {
|
|
handler() {
|
|
// scrolls page to next active question
|
|
this.$nextTick(() => {
|
|
document.querySelector('.current-question').scrollIntoView({behavior: "smooth"});
|
|
})
|
|
},
|
|
deep: true
|
|
}
|
|
},
|
|
components: {
|
|
buttonQuestion,
|
|
},
|
|
};
|
|
</script>
|