JSFiddle - React, Tailwind, and code Playground
HTML
<h1>questionnaire</h1>
<div id="questionaire"></div>
<div class="toolstrip">
<button id="btnNext" type="button">Next</button>
</div>
JavaScript
const questions = [
{
question: 'What platform are you on?',
answers: 'Stackoverflow',
points: 5
},
{
question: '40 + 2?',
answers: "42",
points: 1
},
{
question: 'How much is 7*6',
answers: "42",
points: 1
}
];
// a simple generator that is used in the questionaire
function *questionsGenerator( questions ) {
yield* questions;
}
// creates a questionaire, with forward only options (due to the use of the generator function)
// all variables are locally scoped, when all questions were answered, the onCompleted callback would be called
// it returns an object with nextQuestion function though it could call nextButton internally, and you just have to call the function once if you would want to change it
const questionaire = ( query, nextButton, target, onCompleted ) => {
let score = 0;
let iterator = questionsGenerator( query );
let question = null;
let selectedAnswer = -1;
nextButton.addEventListener('click', nextQuestion);
function evaluateAnswer() {
if (!question) {
// no question yet
return;
}
if (selectedAnswer < 0) {
return;
}
if (question.answers === selectedAnswer) {
score += question.points;
}
return;
}
function nextQuestion() {
evaluateAnswer();
question = iterator.next();
// this is a bit of a hack to check if we just had the last question or not
if (question.done) {
nextButton.removeEventListener('click', nextQuestion);
onCompleted( score );
return;
}
question = question.value;
drawUI();
}
function drawUI() {
// disable next button
nextButton.setAttribute('disabled', true);
selectedAnswer = -1;
// remove existing items
Array.from( target.childNodes ).forEach( child => target.removeChild( child ) );
// create new questions (if available)
const title = document.createElement('h1');
title.innerHTML = question.question;
target.appendChild(...