So at the moment, the quiz keeps looping through the quiz until it switches to the endQuiz Function. What I am trying to do is determine if the answer is equal to the ID in the array when it has been checked, so I callback to the function called selectedAnswer. So when I can call back to it later in the displayNextQuestion so it can show that it is equal to the filteredQuestion[randomQuestion].answer resulting in the score being increase. This is what I have been working on
let easyDifficulty = document.getElementById("easy-diff"); let mediumDifficulty = document.getElementById("medium-diff"); let hardDifficulty = document.getElementById("hard-diff"); let difficulty = document.getElementById("difficulty"); let difficultyLevel = ""; let submitBtn = document.getElementById("submit"); let questionCounter = 1; let maxQuestion = 10; let questions = [{ question: `Al Pacino starred in the 1975 film Dog Day Afternoon that is the true story of a bank robbery gone bad. Where did the attempted robbery take place?`, a: `Chicago`, b: `Los Angeles`, c: `Boston`, d: `New York`, answer: `d`, difficulty: `hard`, }, { question: `Al Pacino and Robert De Niro have starred in a total of four movies together, can you name the film that they first shared screen time in?`, a: `Righteous Kill`, b: `Heat`, c: `The Godfather Part II`, d: `The Irishman`, answer: `b`, difficulty: `hard`, }, { question: `Al Pacino has starred in the The Godfather Trilogy, can you name the charter he portrays?`, a: `Fredo Corleone`, b: `Michael Corleone`, c: `Tom Hagen`, d: `Sonny Corleone`, answer: `b`, difficulty: `medium`, }, { question: `Al Pacino starred in the 1973 film Serpico that was director by which director?`, a: `Sidney Lumet`, b: `David Lean`, c: `Mel Brooks`, d: `Alfred Hitchcock`, answer: `a`, difficulty: `medium`, }, { question: `Al Pacino starred in 2019 film The Irishman, can you pick the actor who doesn't co-star in the film`, a: `Robert De Niro`, b: `Christopher Walken`, c: `Joe Pesci`, d: `Harvey Keitel`, answer: `b`, difficulty: `easy`, }, { question: `Al Pacino portrays Michael Corleone in the Godfather Trilogy that was directed by which director?`, a: `George Lucas`, b: `Stanley Kubrick`, c: `Francis Ford Coppola`, d: `Roman Polanski`, answer: `c`, difficulty: `easy`, } ] let pickDifficulty = () => { if (easyDifficulty.checked) { difficultyLevel = "easy"; } else if (mediumDifficulty.checked) { difficultyLevel = "medium"; } else if (hardDifficulty.checked) { difficultyLevel = "hard"; } }; function displayQuestion(quizQuestion, quiz) { quizQuestion.querySelector("#question").innerText = quiz.question; quizQuestion.querySelector("#a-answer").innerText = quiz.a; quizQuestion.querySelector("#b-answer").innerText = quiz.b; quizQuestion.querySelector("#c-answer").innerText = quiz.c; quizQuestion.querySelector("#d-answer").innerText = quiz.d; } difficulty.addEventListener("change",() => { pickDifficulty(); const filteredQuestions = questions.filter((question) => question.difficulty === difficultyLevel); const randomQuestion = Math.floor(Math.random() *filteredQuestions.length); const quiztemplate = document.querySelectorAll(".quiz"); const quizparent = quiztemplate[0].parentNode; quiztemplate.forEach((qq) => quizparent.removeChild(qq)); let quizQuestion = quizparent.appendChild(quiztemplate[0].cloneNode(true)); displayQuestion(quizQuestion, filteredQuestions[randomQuestion]); //filteredQuestions.splice(randomQuestion, 1); },true); let answers = document.querySelectorAll(".answer"); function selectedAnswer() { let answer = undefined; answers.forEach((answers) => { if (answers.checked) { answer = answers.id; } }); return answer; } let score = 0; function nextQuestion() { if (questionCounter >= maxQuestion) { endQuiz(); } else { const quiztemplate = document.querySelectorAll(".quiz"); const quizparent = quiztemplate[0].parentNode; quiztemplate.forEach((qq) => quizparent.removeChild(qq)); const quizquestion = quizparent.appendChild(quiztemplate[0].cloneNode(true)); const filteredQuestions = questions.filter((question) => question.difficulty === difficultyLevel); const randomQuestion = Math.floor(Math.random() * filteredQuestions.length); //filteredQuestions.splice(randomQuestion, 1); displayQuestion(quizquestion, filteredQuestions[randomQuestion]); } let answer = selectedAnswer(); const filteredQuestions = questions.filter((question) => question.difficulty === difficultyLevel); const randomQuestion = Math.floor(Math.random() * filteredQuestions.length); if (answer) { if (answer === filteredQuestions[randomQuestion].answer) { score++; document.getElementById( "score-counter" ).innerHTML = `<h3>Score:${score} / ${maxQuestion}</h3>`; } } } submitBtn.addEventListener("click", nextQuestion);
<div id="difficulty" class="center"> <div> <input type="radio" name="difficulty" id="easy-diff" value="easy"> <label for="easy-diff">Easy</label> </div> <div> <input type="radio" name="difficulty" id="medium-diff" value="medium"> <label for="medium-diff">Medium</label> </div> <div> <input type="radio" name="difficulty" id="hard-diff" value="hard"> <label for="hard-diff">Hard</label> </div> </div> <div id="question-holder" class="hide"> <div id="question-counter"></div> <div id="score-counter"></div> <p id="post"></p> <div class="quiz"> <h4 id="question">Question placement</h4> <ul id="answer-holder"> <li> <label for="a" id="a-answer">possible answer</label> <input type="radio" name="answer" id="a" class="answer"> </li> <li> <label for="b" id="b-answer">possible answer</label> <input type="radio" name="answer" id="b" class="answer"> </li> <li> <label for="c" id="c-answer">possible answer</label> <input type="radio" name="answer" id="c" class="answer"> </li> <li> <label for="d" id="d-answer">possible answer</label> <input type="radio" name="answer" id="d" class="answer"> </li> </ul> </div> <button id="submit" class="btn">Submit</button> </div>
Advertisement
Answer
The following is a rewrite to a large extent. I tried to set up the whole thing without relying too much on (calculated) id
attributes. Instead I used CSS selectors based on class and parent-child relationships.
I also changed your answers into choices
, a property containing an array with the options “a” to “d”.
The random sequence of questions was achieved by shuffling the selcted questions using a Durstenfeld shuffle algorithm.
const questions=[{question: "Al Pacino starred in the 1975 film Dog Day Afternoon that is the true story of a bank robbery gone bad. Where did the attempted robbery take place?",choices:["Chicago","Los Angeles","Boston","New York"],answer: "d", difficulty: "hard"},{question: "Al Pacino and Robert De Niro have starred in a total of four movies together, can you name the film that they first shared screen time in?",choices:["Righteous Kill","Heat","The Godfather Part II","The Irishman"],answer:"b",difficulty: "hard"},{question: "Al Pacino has starred in the The Godfather Trilogy, can you name the character he portrays?",choices:["Fredo Corleone","Michael Corleone","Tom Hagen","Sonny Corleone"],answer: "b",difficulty: "medium" },{question: "Al Pacino starred in the 1973 film Serpico that was director by which director?",choices:["Sidney Lumet","David Lean","Mel Brooks","Alfred Hitchcock"],answer: "a",difficulty: "medium"},{question: "Al Pacino starred in 2019 film The Irishman, can you pick the actor who doesn't co-star in the film",choices:["Robert De Niro","Christopher Walken","Joe Pesci","Harvey Keitel"],answer:"b",difficulty: "easy"},{question: "Al Pacino portrays Michael Corleone in the Godfather Trilogy that was directed by which director?",choices:["George Lucas","Stanley Kubrick","Francis Ford Coppola","Roman Polanski"],answer: "c",difficulty: "easy"},{question: "Where did the Boston Tea party take place?",choices: ["Chicago", "Los Angeles", "Boston", "New York"],answer: "c",difficulty: "easy"},{question: "When did the United States declare their independence?",choices: [1492, 1776, 1812, 1918],answer: "b",difficulty: "easy"}, {question: "Where is Venice Beach?",choices: ["Chicago", "Los Angeles", "Boston", "New York"],answer: "b",difficulty: "easy"}], question = document.querySelector("#question"), answers = document.querySelectorAll("#answer-holder label span"), qcount = document.querySelector("#question-counter"), qtotal = document.querySelector("#questions-total"), acount = document.querySelector("#score-counter"); function shfl(a){ // Durstenfeld shuffle for(let j,i=a.length;i>1;){ j=Math.floor(Math.random()*i--); if (i!=j) [a[i],a[j]]=[a[j],a[i]] } return a } function nextQ() { // get next question of filtered and shuffled selection if (questions.Q=questions.sel.shift()){ question.textContent = questions.Q.question; answers.forEach((a, i) =>{ a.textContent = questions.Q.choices[i]; a.previousElementSibling.checked=false; }) } else console.log("Game over.") } document.querySelectorAll("input[name=level]").forEach( lvl=>lvl.onclick=_=>{ // filter questions according to level and shuffle them into questions.sel questions.sel=shfl(questions.filter(q=>q.difficulty==lvl.value)); qcount.textContent=acount.textContent="0"; qtotal.textContent=questions.sel.length; nextQ(); } ) document.querySelector("button").onclick=_=>{ // submit button ==> submit answer if (questions.Q){ // only after game is initialised ... const ans=document.querySelector("#answer-holder input:checked") ++qcount.textContent; if (ans?.value == questions.Q.answer) ++acount.textContent; nextQ(); } }
<div id="question-holder" class="hide"> <label><input type="radio" name="level" value="easy">easy</label><br> <label><input type="radio" name="level" value="medium">medium</label><br> <label><input type="radio" name="level" value="hard">hard</label><br><br> <div>Questions: <span id="question-counter"></span> / <span id="questions-total"></span></div> <div>Correct answers: <span id="score-counter"></span></div> <p id="post"></p> <div class="quiz"> <h4 id="question">Question placement</h4> <ul id="answer-holder"> <li><label><input type="radio" name="answer" value="a"><span>possible answer</span></label></li> <li><label><input type="radio" name="answer" value="b"><span>possible answer</span></label></li> <li><label><input type="radio" name="answer" value="c"><span>possible answer</span></label></li> <li><label><input type="radio" name="answer" value="d"><span>possible answer</span></label></li> </ul> </div> <button id="submit" class="btn">Submit</button> </div>