Javascript quiz won't recall previous answers - javascript

I'm new to programming and Javascript, and as a first project I'm trying to create a small quiz application.
I've included it here on jsfiddle:
http://jsfiddle.net/ben220/L0y43q3d/
I've tried to design the program so that the user is able go back through the quiz and change any of their answers before they click to get their final score at the end. The user checks the radio button next to their chosen answer. When the user clicks 'next' to move on (or 'back' to revisit a previous question) their answer is passed to an array called 'choices', and this array will store all of the user's answers as they go through the quiz.
I've managed to write the program so that previous answers can be saved and recalled but there is one annoying problem. If the user checks a particular radio button more than once in the quiz, the program will only remember the first one. For example: if I am on Question 4 and check the radio button for Answer 2, I might decide to go back to the previous question and change my answer, before moving on. So I go back to Question 3 and change the answer to Answer 2. I have now chosen the same radio button on two consecutive questions. But now when I click 'next' to move onto Question 4 again I find that no radio button is checked, my answer was not saved.
I've really tried to fix this by myself but I do not understand what I've done wrong. If anyone out there could suggest a solution I'd be grateful. If any further clarification is needed let me know. Sorry if my explanation or my code is confusing - I'm still a newbie with Javascript! Many thanks.
<div id="container">
<div id="quizArea">
<h2 id="theQuestion">Question 1</h2>
<fieldset id="myForm">
<label><input type="radio" name="question" value="0" />Answer 1</label><br/>
<label><input type="radio" name="question" value="1" />Answer 2</label><br/>
<label><input type="radio" name="question" value="2" />Answer 3</label><br/>
<label><input type="radio" name="question" value="3" />Answer 4</label><br/>
<label><input type="radio" name="question" value="4" />Answer 5</label><br/>
</fieldset>
<div class="mini_container"><button id="next">Next</button></div>
<button id="getScore">Get Score</button>
<div class="mini_container"><button id="back">Back</button></div>
<p id="submitError">Please choose an answer before proceeding to the next question</p>
<div id="score"></div>
</div>
</div>
Javascript:
var module = (function () {
var theQuestions = [{question: "Question 1", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 2}, {question: "Question 2", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 4}, {question: "Question 3", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 1}, {question: "Question 4", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 1}, {question: "Question 5", choices: ["Answer 1", "Answer 2", "Answer 3", "Answer 4", "Answer 5"], answer: 3}],
score = 0,
title = document.getElementById("theQuestion"),
back = document.getElementById("back"),
next = document.getElementById("next"),
radioButtons = document.getElementById("options"),
options = document.getElementsByTagName("label"),
radios = document.getElementsByTagName("input"),
submitError = document.getElementById("submitError"),
scoreBtn = document.getElementById("getScore"),
scoreBox = document.getElementById("score"),
currentQ = 0;
var choices = [];
function getRadioInfo() {
var decision = null;
for(var i = 0; i < radios.length; i += 1) {
if(radios[i].checked) {
decision = radios[i].value;
}
}
return decision;
}
back.onclick = function() {
var decision = getRadioInfo();
choices[currentQ] = decision;
currentQ -= 1;
if(currentQ === 0) {
back.style.display = "none";
}
if(currentQ < theQuestions.length) {
next.style.display = "block";
scoreBtn.style.display = "none";
}
title.innerHTML = theQuestions[currentQ].question;
var a = 0;
for(var i = 0; i < options.length; i += 1) {
options[i].innerHTML = '<input type="radio" name="question" value="' + a + '" />' + theQuestions[currentQ].choices[a];
a += 1;
}
restorePreviousAnswer();
};
var restorePreviousAnswer = function() {
for(var i = 0; i < choices.length; i += 1) {
if(choices.indexOf(choices[i]) == currentQ) {
var prev = choices[i];
}
}
for(var x = 0; x < radios.length; x += 1) {
if (radios[x].value == prev) {
radios[x].checked = true;
}
}
};
next.onclick = function() {
var decision = getRadioInfo();
if(decision == null) {
submitError.style.display = "block";
return;
} else {
submitError.style.display = "none";
}
choices[currentQ] = decision;
currentQ += 1;
if(currentQ > 0) {
back.style.display = "block";
}
if(currentQ == theQuestions.length - 1) {
next.style.display = "none";
scoreBtn.style.display = "block";
}
title.innerHTML = theQuestions[currentQ].question;
var a = 0;
for(var i = 0; i < options.length; i += 1) {
options[i].innerHTML = '<input type="radio" name="question" value="' + a + '" />' + theQuestions[currentQ].choices[a];
a += 1;
}
restorePreviousAnswer();
};
scoreBtn.onclick = function() {
hideAll();
scoreBox.innerHTML = "You scored " + score + " out of " + theQuestions.length;
};
})();

I cleaned up your restorePreviousAnswer function to just if (choices[currentQ] != null) radios[choices[currentQ]].checked = true. Another part of the problem was that null values were being inserted in your array of answers when you went back before selecting a radio button.
jsFiddle example

Related

Categorized Scoring of Questions

I want to take an array of questions in a quiz and categorize them into 3 different scores. Like Math/English/Science per-say.
So, if each of the 3 questions in the array was a separate category, can I label them and have a function that calculates based on category and how would that look?
I know I could duplicate my functions and slightly modify them based on the category, but I feel like there is a more efficient way to do that.
// Initialize the current question index
let currentQuestionIndex = 0;
// Array of questions
const questions = [{
question: "What does 2+2 equal?",
answers: [{
text: "4",
value: 1
},
{
text: "2",
value: 0
},
{
text: "8",
value: 0
},
{
text: "16",
value: 0
}
]
},
{
question: "What does oblitirate most nearly mean?",
answers: [{
text: "translate",
value: 0
},
{
text: "scatter",
value: 0
},
{
text: "wipe out",
value: 1
},
{
text: "blame",
value: 0
}
]
},
{
question: "What is the chemical formula for water?",
answers: [{
text: "H2O",
value: 0
},
{
text: "K",
value: 0
},
{
text: "Na",
value: 1
},
{
text: "H",
value: 0
}
]
}
];
// Initialize the total score
let totalScore = 0;
// Add the value of the selected answer to the total score and uncheck the other radio buttons
function updateScore(selectedAnswer) {
// Check if a radio button has been selected
if (!selectedAnswer.checked) {
return;
}
// Add the value of the selected answer to the total score
totalScore += parseInt(selectedAnswer.value);
// Get all the radio buttons
const radioButtons = document.getElementsByName("answer");
// Loop through the radio buttons
for (const radioButton of radioButtons) {
// If the radio button is not the selected answer, uncheck it
if (radioButton !== selectedAnswer) {
radioButton.checked = false;
}
}
}
// Show the next question
function showNextQuestion() {
// Hide the form
document.getElementById("form").style.display = "none";
// Show the question and answers
document.getElementById("question").style.display = "block";
document.getElementById("answers").style.display = "block";
document.getElementById("next-button").style.display = "block";
// Check if the current question is the last question
if (currentQuestionIndex < questions.length) {
// If it is not, get the current question
const currentQuestion = questions[currentQuestionIndex];
// Update the question text
document.getElementById("question").innerHTML = currentQuestion.question;
//clear answers
document.getElementById("answers").innerHTML = '';
// Show the answers for the current question
for (const answer of currentQuestion.answers) {
document.getElementById("answers").innerHTML += `
<input type="radio" name="answer" value="${answer.value}" onchange="updateScore(this)"> ${answer.text}<br>
`;
}
// Update the current question index
currentQuestionIndex++;
}
if (currentQuestionIndex === questions.length) {
// If it is, hide the "Next" button and show the "Submit" button
document.getElementById("next-button").style.display = "none";
document.getElementById("submit-button").style.display = "block";
}
}
// Show the total score
function showTotalScore() {
// Hide the question and answers
document.getElementById("question").style.display = "none";
document.getElementById("answers").style.display = "none";
document.getElementById("submit-button").style.display = "none";
// Show the total score
document.getElementById("total-score").style.display = "block";
document.getElementById("total-score").innerHTML = "Total Score: " + totalScore;
}
<form id="form">
<label for="name">Name:</label><br>
<input type="text" id="name" name="name"><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email"><br>
<label for="phone">Phone:</label><br>
<input type="text" id="phone" name="phone"><br><br>
<input type="button" value="Next" onclick="showNextQuestion()">
</form>
<div id="question" style="display: none;"></div>
<div id="answers" style="display: none;"></div>
<div id="next-button" style="display: none;"><input type="button" value="Next" onclick="showNextQuestion()"></div>
<div id="submit-button" style="display: none;"><input type="button" value="Submit" onclick="showTotalScore()"></div>
<div id="total-score" style="display: none;">Total Score: 0</div>
You just need to create an object mapping each category to its score, and a category assigned to every question like so :
// Initialize the current question index
let currentQuestionIndex = 0;
// Array of questions
const questions = [{
question: "What does 2+2 equal?",
category: 'maths',
answers: [{
text: "4",
value: 1
},
{
text: "2",
value: 0
},
{
text: "8",
value: 0
},
{
text: "16",
value: 0
}
]
},
{
question: "What does oblitirate most nearly mean?",
category: 'english',
answers: [{
text: "translate",
value: 0
},
{
text: "scatter",
value: 0
},
{
text: "wipe out",
value: 1
},
{
text: "blame",
value: 0
}
]
},
{
question: "What is the chemical formula for water?",
category: 'science',
answers: [{
text: "H2O",
value: 1
},
{
text: "K",
value: 0
},
{
text: "Na",
value: 0
},
{
text: "H",
value: 0
}
]
}
];
// Initialize the total score
const scores = {}
let totalScore = 0
// Add the value of the selected answer to the total score and uncheck the other radio buttons
function updateScore (selectedAnswer, category) {
// Check if a radio button has been selected
if (!selectedAnswer.checked) return;
const v = parseInt(selectedAnswer.value)
// Add the value of the selected answer to the total score
totalScore += v;
// Add the value of the selected answer to the category score
scores[category] += v
// Get all the radio buttons
const radioButtons = document.getElementsByName("answer");
// Loop through the radio buttons
for (const radioButton of radioButtons) {
// If the radio button is not the selected answer, uncheck it
if (radioButton !== selectedAnswer) {
radioButton.checked = false;
}
}
}
// Show the next question
function showNextQuestion() {
// Hide the form
document.getElementById("form").style.display = "none";
// Show the question and answers
document.getElementById("question").style.display = "block";
document.getElementById("answers").style.display = "block";
document.getElementById("next-button").style.display = "block";
// Check if the current question is the last question
if (currentQuestionIndex < questions.length) {
// If it is not, get the current question
const currentQuestion = questions[currentQuestionIndex];
// Update the question text
document.getElementById("question").innerHTML = currentQuestion.question;
//clear answers
document.getElementById("answers").innerHTML = '';
// Init the category score
scores[currentQuestion.category] = 0
// Show the answers for the current question
for (const answer of currentQuestion.answers) {
document.getElementById("answers").innerHTML += `
<input type="radio" name="answer" value="${answer.value}" onchange="updateScore(this, '${ currentQuestion.category }')"> ${answer.text}<br>
`;
}
// Update the current question index
currentQuestionIndex++;
}
if (currentQuestionIndex === questions.length) {
// If it is, hide the "Next" button and show the "Submit" button
document.getElementById("next-button").style.display = "none";
document.getElementById("submit-button").style.display = "block";
}
}
// Show the total score
function showTotalScore() {
let txt = "Total Score: " + totalScore
console.log(scores)
Object.keys(scores).forEach(category => {
// Catpitalize the category
const categoryStr = category.split('').map((e, i) => i ? e : e.toUpperCase()).join('')
txt += `<br />${ categoryStr }: ${ scores[category] }`
})
// Hide the question and answers
document.getElementById("question").style.display = "none";
document.getElementById("answers").style.display = "none";
document.getElementById("submit-button").style.display = "none";
// Show the total score
document.getElementById("total-score").style.display = "block";
document.getElementById("total-score").innerHTML = txt;
}
<form id="form">
<label for="name">Name:</label><br>
<input type="text" id="name" name="name"><br>
<label for="email">Email:</label><br>
<input type="email" id="email" name="email"><br>
<label for="phone">Phone:</label><br>
<input type="text" id="phone" name="phone"><br><br>
<input type="button" value="Next" onclick="showNextQuestion()">
</form>
<div id="question" style="display: none;"></div>
<div id="answers" style="display: none;"></div>
<div id="next-button" style="display: none;"><input type="button" value="Next" onclick="showNextQuestion()"></div>
<div id="submit-button" style="display: none;"><input type="button" value="Submit" onclick="showTotalScore()"></div>
<div id="total-score" style="display: none;">Total Score: 0</div>

For loop loses variable value after first loop [duplicate]

This question already has answers here:
How to add two strings as if they were numbers? [duplicate]
(20 answers)
Closed 5 years ago.
Apologies if my question title is not accurate, I couldn't think how to phrase it.
var options = [2,3,4]
// select drop down
var select = document.getElementById("itemSet");
for (var i = 0; i < options.length; i++) {
var opt = options[i];
var el = document.createElement("option");
el.text = opt;
el.value = opt;
select.add(el);
}
// define arrays
var arrActivity = ["alien monster", "man in business suit levitating", "fencer", "horse racing", "skier", "snowboarder", "golfer", "surfer", "rowboat", "swimmer"];
var arrFood = ["grapes", "melon", "watermelon", "tangerine", "lemon", "banana", "pineapple", "red apple", "green apple", "pear"];
var arrObjects = ["skull and crossbones", "love letter", "bomb", "hole", "shopping bags", "prayer beads", "gem stone", "hocho", "amphora", "world map"];
var arrLetters = ["letter a", "letter b", "letter c", "letter d", "letter e", "letter f", "letter g", "letter h", "letter i", "letter j"];
// format the array data for output into the textarea
function boom() {
var e = document.getElementById("itemSet");
var myCols = e.options[e.selectedIndex].value;
console.log(myCols);
var arrNew = [];
if (document.getElementById("radioActivity").checked) {
y = arrActivity;
} else if (document.getElementById("radioFood").checked) {
y = arrFood;
} else if (document.getElementById("radioObjects").checked) {
y = arrObjects;
} else if (document.getElementById("radioLetters").checked) {
y = arrLetters;
}
for (var i = 0; i < y.length; i += myCols) {
arrNew.push(
y.slice(i, i + myCols)
);
}
// set the textarea output
op = JSON.stringify(arrNew, null, 4);
document.getElementById('output').value = op;
}
<form onSubmit="return false;">
<label class="radio-inline">
<input type="radio" name="myArray" id="radioActivity" value="valActivity"> Activity
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioFood" value="arrFood"> Food
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioObjects" value="arrObjects"> Objects
</label>
<label class="radio-inline">
<input type="radio" name="myArray" id="radioLetters" value="arrLetters"> Letters
</label>
<select class="form-control" id="itemSet" name="itemSet"></select>
<button onClick="boom();"> Check Radio </button>
<textarea id="output" class="form-control" style="width:95%; height:500px; margin-top:20px;"></textarea>
</form>
When I click the "Check Radio" button, I want to reformat the arrays into chunks using this for loop:
for (var i = 0; i < y.length; i+=myCols) {
arrNew.push(
y.slice(i, i+myCols)
);
}
If I submit the form with a select value of e.g. 2 then the array is reformatted as:
[
[
"alien monster",
"man in business suit levitating"
],
[
"fencer",
"horse racing",
"skier",
"snowboarder",
"golfer",
"surfer",
"rowboat",
"swimmer"
]
]
Instead of in chunks of 2:
[
[
"alien monster",
"man in business suit levitating"
],
[
"fencer",
"horse racing"
],
[
"skier",
"snowboarder"
],
[
"golfer",
"surfer"
],
[
"rowboat",
"swimmer"
]
]
This CodePen demonstrates the issue: https://codepen.io/paperknees/pen/boXjXW
I can't work out what I'm doing wrong.
myCols is a string, therefore
y = 0;
myCols = "2"
//first iteration
y += myCols // "2"
//second iteration:
y += myCols // "22"
To solve this, add an unary plus operator:
var myCols = +e.options[e.selectedIndex].value;
You'll get it here -
while (y.length > 0)
arrNew.push(y.splice(0, myCols))
console.log(arrNew);
That's it!

Getting the value of "on" for radio buttons

var allQuestions = [{
question1: "What is 1 + 1?",
choices: ["1", "2", "3", 4],
correctAnswer: ["2"]
}, {
question2: "What is 2 + 2?",
choices: ["6", "2", "3", 4, ],
correctAnswer: ["4"]
}, {
question3: "What is 3 + 3?",
choices: ["3", "6", "9", 12],
correctAnswer: ["6"]
}];
var newArray = shuffleArray(allQuestions);
function shuffleArray(array) {
for (var i = array.length - 1; i > 0; i--) {
var j = Math.floor(Math.random() * (i + 1));
var temp = array[i];
array[i] = array[j];
array[j] = temp;
}
return array;
}
function appendQuestions(number) {
if (newArray == "undefined" || newArray == "null" || newArray.length == 0) {
document.getElementById("questionForm").innerHTML = "Complete!";
} else {
for (i = 0; i < 4; i++) {
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>")
}
}
}
$(function() {
$("#questionList").empty();
appendQuestions();
newArray.shift();
})
function isCorrectAnswer() {
checkedVal = $("input[type=radio][name=question]:checked").val();
if (checkedVal == newArray[0].correctAnswer) {
alert("Correct!");
} else {
alert("Wrong!");
}
alert(checkedVal);
}
$("#submitButton").click(function() {
isCorrectAnswer();
$("#questionForm").empty();
appendQuestions();
newArray.shift();
})
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class='container'>
<section id='questions'>
<form id="questionForm">
</form>
<div style='clear:both'></div>
<input id='submitButton' type='button' value='Submit'>
</section>
</div>
First off, sorry for the amount of code pasted. I have no idea if I'm missing some small bug or if I'm just writing the wrong code, so I figured it would be best to post all of it.
I am trying to get the value of a radio button. In the isCorrectAnswer function the first 2 lines are to determine the value of the radio button that is currently checked. The problem is when I alert the value of the radio button, it just says "on". I have searched for the last hour trying to figure out what this means or how to fix it and could not find a thing.
I apologize if this is a stupid question or if it has already been answered.
You have to change this line :
$("#questionForm").append("<input name='question' type='radio'>" +
JSON.stringify(newArray[0].choices[i]) + "</input>");
To :
$("#questionForm").append("<input name='question' type='radio' value='" +
JSON.stringify(newArray[0].correctAnswer[i]) + "' />"+JSON.stringify(newArray[0].choices[i]));
Hope this helps.

Getting multiple data attributes from checkboxs

I have a quiz I am making.
Some questions have multiple answers.
My html is as:
<div>Which problems equal 4?</div>
<input type="checkbox" id="qid" class="checks" data-correct="yes">2 + 2<br />
<input type="checkbox" id="qid" class="checks" data-correct="no">2 - 2<br />
<input type="checkbox" id="qid" class="checks" data-correct="yes">2 * 2<br />
I would like to alert if checked answers are both wrong or right.
Currently, my Javascript looks like this:
function checkMsResults(){
var result = $('input[name="qid"]:checked').attr("data-correct");
if(result == '1'){
result = "Answer is Correct";
}
else if(result == '0'){
result = "Answer is Not Correct";
}
else{
result = "Please make a selection";
}
alert(result + ".");
}
This will alert only one selection.
Can someone teach me how to loop through each on so I can alert multiple selections?
You have three inputs with the same id, you can't do that, id must be unique.
function checkMsResults() {
if ($('input[name="quid"]:checked').length === 0) {
var result = "Please make a selection";
alert(result);
return;
}
$('input[name="quid"]:checked').each(function() {
var result;
if (this.getAttribute("data-correct") === "yes") {
result = "Answer is Correct";
} else {
result = "Answer is Not Correct"
}
alert(result);
});
}
Cleaned up your original. Here's a jsfiddle that takes the answer of each and sticks all into an array off answers; you can do whatever you want with it after that...https://jsfiddle.net/r2xc22Ld/1/
function checkMsResults(){
var result = "";
var answers = [];
$('input[name="qid"]:checked').each(function() {
answers.push($(this).attr('data-correct'));
});
//console.log(answers);
for(var i = 0; i< answers.length; i++){
result += 'Question '+i+': ' + answers[i] +'\n';
}
if(result==""){
alert('make a selection...');
}else{
alert(result);
}

Matching radio button selection with nested Array content in Javascript

UPDATE 6-25-2014
Any insight would be appreciated!
UPDATE 6-21-2014
I tried to make the radio variables, global so the 'if block' in the 'answerFwd' function could be compared to the correctAnswer Array, but that didn't work!
UPDATE 6-16-2014
ADDED JS FIDDLE
I am building a quiz and creating an array of radio buttons dynamically, and would like to match the selected button with the correct answer I have established in the question array.
html
<div id="responses">
<input type="radio" name="choices" class="radioButtons" value="0" id="choice0">
<div id="c0" class="choiceText">The Observers</div>
<input type="radio" name="choices" class="radioButtons" value="1" id="choice1">
<div id="c1" class="choiceText">The Watchers </div>
<input type="radio" name="choices" class="radioButtons" value="2" id="choice2">
<div id="c2" class="choiceText">The Sentinels</div>
<input type="radio" name="choices" class="radioButtons" value="3" id="choice3">
<div id="c3" class="choiceText">The Oa</div>
</div>
questions:
var allQuestions = [{
"question": "Who was Luke's wingman in the battle at Hoth?",
"choices": ["Dak", "Biggs", "Wedge", "fx-7"],
"correctAnswer": 0 }, {
"question": "What is the name of Darth Vader's flag ship?",
"choices": ["The Avenger", "Devastator ", "Conquest", "The Executor"],
"correctAnswer": 3 },{},{} //other questions];
var item = allQuestions[0];
var currentQuestion = 0;
var playersScore = 0;
//function which creates the buttons
function createRadioButtonFromArray(array) {
var len = array.length;
var responses = document.getElementById("responses");
responses.innerHTML = '';
for (var i = 0; i < len; i++) {
radio = document.createElement("input"); //Updated 6-21-2014 removed 'var'
radio.type = "radio";
radio.name = "choices";
radio.className = "radioButtons";
radio.value = i;
radio.id = "choice" + i;
ar radioText = document.createElement("div");
radioText.id = "c" + i;
radioText.className = "choiceText";
radioText.innerHTML = array[i];
responses.appendChild(radio);
responses.appendChild(radioText);
}
}
function answerFwd() {
var answerOutput = " ";
var itemAnswers = allQuestions;
var playerTally = 0; //Updated 6-9-2014
var playerFeedback = " "; //Updated 6-9-2014
var playerMessage = document.getElementById("playerMessage"); //Updated 6-9-2014
if (currentAnswer <= itemAnswers.length) {
currentAnswer++;
}
createRadioButtonFromArray(itemAnswers[currentQuestion].choices);
* Updated 6-9-2014 I am stumped; This doesn't work but I was encouraged I got a score tally on the page! Am I comparing the elements correctly? Updated 6-21-2014 This reversed the gain, where I had the tally render on the screen*
if (itemAnswers.correctAnswer === responses.id) { //Updated 6-21-2014
playerTally += 1;
playerFeedback += "<h5>" + playerTally + "</h5> <br/>";
playerMessage.innerHTML = playerFeedback;
}
}
At first I tried to debug this but had trouble finding where the error was coming from.
One thing I noticed was currentAnswer variable was only being set once. (when it was declared)
Another thing that would make this cleaner is storing each response to each question as a property of the questions object.
For example: {"question": "What is the registry of the Starship Reliant?","choices": ["NX-01", "NCC-1864", "NCC-1701", "NCC-2000"],"correctAnswer": 1,"selectedAnswer": 0}
This is a good example of why you may want to use object oriented programming. You can keep the global namespace clean, while also having tighter control over your variables.
I put together this Quiz Code using some object oriented principles:
JavaScript
var Quiz = function(questions) {
this.questions = questions;
this.$template = {
"header": document.querySelector(".question"),
"options": document.querySelector(".question-choices")
};
this.init();
}
Quiz.prototype = {
"init": function() {
this.question = 0;
this.generateQuestion();
this.bindEvents();
},
//gets called when this.question == this.questions.length, calculates a score percentage and alerts it
"score": function() {
var correctCount = 0;
this.questions.forEach(function(question){
if ( (question.selectedAnswer || -1) === question.correctAnswer ) correctCount += 1
})
alert("Score: " + ((correctCount / this.questions.length) * 100) + "%")
},
//Gets called during initialization, and also after a nav button is pressed, loads the question and shows the choices
"generateQuestion": function() {
var question = this.questions[this.question];
this.$template.header.innerHTML = question.question;
this.$template.options.innerHTML = "";
question.choices.forEach(this.createRadio.bind(this));
},
//Binds the previous, and next event handlers, to navigate through the questions
"bindEvents": function() {
var _this = this,
$nextBtn = document.querySelector(".question-navigation--next"),
$prevBtn = document.querySelector(".question-navigation--prev");
$nextBtn.addEventListener("click", function(e) {
//Go to the next question
_this.question++;
if ( _this.question == _this.questions.length ) {
_this.score();
} else {
_this.generateQuestion();
}
});
$prevBtn.addEventListener("click", function(e) {
_this.question--;
if ( _this.question <= 0 ) _this.question = 0
_this.generateQuestion();
});
},
//Create each individual radio button, is callback in a forEach loop
"createRadio": function(choice, index) {
var question = this.questions[this.question];
var radio = document.createElement("input");
radio.type = "radio";
radio.name = "options";
radio.id = "option-"+index;
if ( question.selectedAnswer === index ) {
radio.checked = true;
}
radio.addEventListener("click", function(e) {
question.selectedAnswer = index;
})
var radioText = document.createElement("label");
radioText.setAttribute("for", "option-"+index)
radioText.innerHTML = choice;
radioText.insertBefore(radio, radioText.firstChild);
this.$template.options.appendChild(radioText);
}
}
var q = new Quiz(allQuestions)

Categories

Resources