Reputation: 13
I am currently creating a timed quiz with 10 questions by using arrays.
I managed to create a timer in HTML with JS, but somehow, my quiz (arrays in js file) does not show up in the html.
I double checked that there is no bug in my code, all variables are declared, and I made sure that I correctly linked my javascript file in the html code.
The following is the javascript section... ( I did not post my quiz questions)
var myQuestions = [
{ ~~~~~ my questions go here }
]
function generateQuiz(questions, quizContainer, resultsContainer, submitButton){
function showQuestions(questions, quizContainer){
//storing the answers
var output = [];
var answers;
// by using for loops.
for(var i=0; i<questions.length; i++){
answers = [];
for(letter in questions[i].answers){
// radio buttion in html
answers.push(
'<label>'
+ '<input type="radio" name="question'+i+'" value="'+letter+'">'
+ letter + ': '
+ questions[i].answers[letter]
+ '</label>'
);
}
// add the Q&A to results
output.push(
'<div class="question">' + questions[i].question + '</div>'
+ '<div class="answers">' + answers.join('') + '</div>'
);
}
// join to html
quizContainer.innerHTML = output.join('');
}
// --------- showing results
function showResults(questions, quizContainer, resultsContainer){
// collect answer containers quiz
var answerContainers = quizContainer.querySelectorAll('.answers');
// count correct/wrong answers
var userAnswer = '';
var numCorrect = 0;
for(var i=0; i<questions.length; i++){
userAnswer = (answerContainers[i].querySelector('input[name=question'+i+']:checked')||{}).value;
// if/else loop
// correct answer, answer will display in green and # of correct answer will added
// wrong answer, answer will display in red
if(userAnswer===questions[i].correctAnswer){
numCorrect++;
answerContainers[i].style.color = 'lightgreen';
}
else{
answerContainers[i].style.color = 'red';
}
}
// show number of correct answers out of total
resultsContainer.innerHTML = numCorrect + ' out of ' + questions.length;
}
// --------- declare variables and display in html
var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');
generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
// --------- showing results on submit
submitButton.onclick = function(){
showResults(questions, quizContainer, resultsContainer);
}
and in the html, I only posted the following:
<form method="POST" name="javaInterviewQuiz">
<div id="time"><h4>Time left = <span id="timer"></span></h4></div>
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>
</form>
I was expecting the timer to show up in the top (which it did), but my question section just does not show up.
Just as if I did not put any code there.
Upvotes: 1
Views: 649
Reputation: 702
I see that you are using nested functions and didn't call 'showQuestions' method at first. Also, you are trying to call 'showResults' from onclick event that is initialized outer scope of the nested functions. You can try as below;
var myQuestions = [{
question: "What does 'Lorem ipsum dolor' mean?",
answers: ['Nothing', 'Something'],
correctAnswer: '1'
}];
function generateQuiz(questions, quizContainer, resultsContainer, submitButton) {
function showQuestions(questions, quizContainer) {
//storing the answers
var output = [];
var answers;
// by using for loops.
for (var i = 0; i < questions.length; i++) {
answers = [];
for (let letter in questions[i].answers) {
// radio buttion in html
answers.push(
'<label>' +
'<input type="radio" name="question' + i + '" value="' + letter + '">' +
letter + ': ' +
questions[i].answers[letter] +
'</label>'
);
}
// add the Q&A to results
output.push(
'<div class="question">' + questions[i].question + '</div>' +
'<div class="answers">' + answers.join('') + '</div>'
);
}
// join to html
quizContainer.innerHTML = output.join('');
}
// --------- showing results
function showResults(questions, quizContainer, resultsContainer) {
// collect answer containers quiz
var answerContainers = quizContainer.querySelectorAll('.answers');
// count correct/wrong answers
var userAnswer = '';
var numCorrect = 0;
for (var i = 0; i < questions.length; i++) {
userAnswer = (answerContainers[i].querySelector('input[name=question' + i + ']:checked') || {}).value;
// if/else loop
// correct answer, answer will display in green and # of correct answer will added
// wrong answer, answer will display in red
if (userAnswer === questions[i].correctAnswer) {
numCorrect++;
answerContainers[i].style.color = 'lightgreen';
} else {
answerContainers[i].style.color = 'red';
}
}
// show number of correct answers out of total
resultsContainer.innerHTML = numCorrect + ' out of ' + questions.length;
}
// --------- showing results on submit
submitButton.onclick = function() {
showResults(questions, quizContainer, resultsContainer);
}
showQuestions(questions, quizContainer);
}
// --------- declare variables and display in html
var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');
generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
<form method="POST" name="javaInterviewQuiz">
<div id="time">
<h4>Time left = <span id="timer"></span></h4>
</div>
<div id="quiz"></div>
<button id="submit">Get Results</button>
<div id="results"></div>
</form>
This code snippet is intended to give a little insight.
Upvotes: 0
Reputation: 257
You declared inner functions but never called them. You can take them out and write them like this.
var myQuestions = [
]
function showQuestions(questions, quizContainer) {
//storing the answers
var output = [];
var answers;
// by using for loops.
for (var i = 0; i < questions.length; i++) {
answers = [];
for (letter in questions[i].answers) {
// radio buttion in html
answers.push(
'<label>'
+ '<input type="radio" name="question' + i + '" value="' + letter + '">'
+ letter + ': '
+ questions[i].answers[letter]
+ '</label>'
);
}
// add the Q&A to results
output.push(
'<div class="question">' + questions[i].question + '</div>'
+ '<div class="answers">' + answers.join('') + '</div>'
);
}
// join to html
quizContainer.innerHTML = output.join('');
}
function showResults(questions, quizContainer, resultsContainer) {
// collect answer containers quiz
var answerContainers = quizContainer.querySelectorAll('.answers');
// count correct/wrong answers
var userAnswer = '';
var numCorrect = 0;
for (var i = 0; i < questions.length; i++) {
userAnswer = (answerContainers[i].querySelector('input[name=question' + i + ']:checked') || {}).value;
// if/else loop
// correct answer, answer will display in green and # of correct answer will added
// wrong answer, answer will display in red
if (userAnswer === questions[i].correctAnswer) {
numCorrect++;
answerContainers[i].style.color = 'lightgreen';
}
else {
answerContainers[i].style.color = 'red';
}
}
// show number of correct answers out of total
resultsContainer.innerHTML = numCorrect + ' out of ' + questions.length;
}
// --------- declare variables and display in html
var quizContainer = document.getElementById('quiz');
var resultsContainer = document.getElementById('results');
var submitButton = document.getElementById('submit');
showQuestions(myQuestions, quizContainer);
// generateQuiz(myQuestions, quizContainer, resultsContainer, submitButton);
// --------- showing results on submit
submitButton.onclick = function () {
showResults(questions, quizContainer, resultsContainer);
}
Upvotes: 1