As I’m still on my journey to learn properly the basics of Javascript before getting into Angular. I tried a new Challenge; a Quizz but slightly differently.
- The user can enter his username.
- I display the username and ask the user to pick a subject.
- Once the subject is picked and displayed, the player has to answer 3 random questions on the subject.
- A dialog with his final score is displayed then the page is reloaded to play again.
NOTE: My question objects have 4 fields; question, options (string array), answer and subject.
My 2 questions/requests:
- Is there a way to update the score on the view in real time?
- Would it be possible to have a feedback on what I did (ie: How amateur is my code :’) and if there are any advices to raise the quality of it).
Thank you.
HTML:
<main>
<h1>Quizz project</h1>
<div class="content-header-section"></div>
<div class="quizz-section"></div>
<div class="username-section">
<h2>Hi there!</h2>
<form action="" class="username-form">
<label for="username-input">Enter your name: </label>
<input type="text" id="username-input">
<input type="submit" value="Start the quizz">
</form>
<template class="user-template"><h2>Hi there!</h2> </template>
</div>
<div class="subject-section">
<template class="subject-template">
<div class="subject-option">
<input class="subject-btn" type="button" value="lo">
</div>
</template>
<template class="pickedSubject-template"><h3>You picked this subject</h3> </template>
</div>
<div class="question-section">
<template class="question-template">
<div class="question-asked"><p>Question?</p></div>
<div class="question-options"></div>
</template>
</div>
</main>
JAVASCRIPT:
const contentHeaderSection = document.querySelector(".content-header-section");
const quizzSection = document.querySelector(".quizz-section");
const usernameSection = document.querySelector(".username-section");
const subjectSection = document.querySelector(".subject-section");
const usernameForm = document.querySelector(".username-form");
const userTemplate = document.querySelector(".user-template");
const subjectTemplate = document.querySelector(".subject-template");
const pickedSubjectTemplate = document.querySelector(".pickedSubject-template");
const questionTemplate = document.querySelector(".question-template");
subjects = ["History", "Music"];
let pickedSubject;
let quizz;
let currentQuestion;
let answerCounter;
let score;
//Check and act once the user enter its username
usernameForm.addEventListener('submit', e =>{
e.preventDefault();
const usernameVal = document.getElementById("username-input").value;
if(usernameVal=="" || usernameVal==undefined){
alert("Please enter your username.");
}else{
initializeValues();
updateUsernameSection(usernameVal);
createSubjectOption();
}
});
const initializeValues = ()=>{
pickedSubject="";
currentQuestion="";
score = 0;
answerCounter = 0;
};
//hide the form for username and replace it by a welcome text with the username
const updateUsernameSection = (name)=>{
usernameSection.style.display= "none";
const userCopy = userTemplate.content.cloneNode(true);
userCopy.querySelector("h2").textContent = `Hi there, ${name}!`;
contentHeaderSection.appendChild(userCopy);
};
//create a dispaly for each subject of quizz
const createSubjectOption = ()=>{
subjects.forEach(subject => {
const subjectCopy = subjectTemplate.content.cloneNode(true);
subjectCopy.querySelector(".subject-btn").value = subject;
subjectSection.appendChild(subjectCopy);
});
}
//When user pick a subject
const subjectButtonHandler = e=>{
pickedSubject = e.target.value;
displayPickedSubject();
quizzMaker();
}
//hide subject options and display the subject picked
const displayPickedSubject = ()=>{
subjectSection.style.display = "none";
const pickedSubjectCopy = pickedSubjectTemplate.content.cloneNode(true);
pickedSubjectCopy.querySelector("h3").textContent = `
You picked: ${pickedSubject}. Your current score is: ${score}.`;
contentHeaderSection.appendChild(pickedSubjectCopy);
}
//Makes the quizz, display the question, handle the answer
const quizzMaker = ()=>{
const condition = (element) => element.subject.toUpperCase() === pickedSubject.toUpperCase();
quizz = getQuestionsWithCondition(questions, condition, 3);
questionDisplay(quizz, answerCounter);
}
const questionDisplay = (arr, index)=>{
quizzSection.innerHTML="";
currentQuestion = arr[index];
const questionCopy = questionTemplate.content.cloneNode(true);
questionCopy.querySelector("p").textContent = currentQuestion.question;
createOptionButtons(questionCopy);
quizzSection.appendChild( questionCopy);
}
const createOptionButtons = (questionCopy)=>{
currentQuestion.options.forEach(option => {
const button = document.createElement("button");
button.textContent = option;
button.value = option;
questionCopy.querySelector(".question-options").appendChild(button);
});
}
const getQuestionsWithCondition = (arr, condition, count) => {
const res = [];
while (res.length<count){
const randomElement = arr[Math.floor(Math.random()*arr.length)];
if(condition(randomElement) && !res.includes(randomElement)){
res.push(randomElement);
}
}
return res;
};
const quizzHandler = (e)=>{
if(e.target.value == currentQuestion.answer){
++score;
}
++answerCounter;
if(answerCounter<3){
questionDisplay(quizz, answerCounter);
}
else{
alert(`Quizz is over! Here's your final score:${score}`);
window.location.reload();
}
};
subjectSection.addEventListener('click', e=> e.target.tagName==='INPUT' && subjectButtonHandler(e));
quizzSection.addEventListener('click', e=> e.target.tagName==='BUTTON' && quizzHandler(e));