I am creating a quiz web app with HTML, CSS AND JavaScript, every time a random question appears on the screen of my quiz the random answers that need to be used and selected, don't appear as well as my next and restart button. When I change anything the start button of my quiz goes away completely but I think my problem lies in my SelectAnswer section in my Script.js file. I'd like the answer options to show up every time there is a new quiz question as well as the next and restart button.
I've tried removing pieces of my code but nothing seems to change on the answers showing up side of my quiz. A point in the right direction would really be appreciated since I'm new to JavaScript.
This is my index.html file
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<link href="style.css" rel="stylesheet">
<script defer src="script.js"></script>
<title>Countries Quiz Web App</title>
</head>
<body>
<div >
<div id="question-container" >
<div id="question">Question</div>
<div id="answer-buttons" >
<button >Answer 1</button>
<button >Answer 2</button>
<button >Answer 3</button>
<button >Answer 4</button>
<button >Answer 5</button>
<button >Answer 6</button>
<button >Answer 7</button>
<button >Answer 8</button>
<button >Answer 9</button>
<button >Answer 10</button>
</div>
</div>
<div >
<button id="start-btn" >Start Quiz</button>
<button id="next-btn" >Next</button>
</div>
</body>
</html>
This is my style.css file
*, *::before, *::after {
box-sizing: border-box;
font-family: Cambria, Cochin, Georgia, Times, 'Times New Roman', serif;
}
:root {
--hue-neutral: 200;
--hue-wrong: 0;
--hue-correct: 145;
}
body {
--hue: var(--hue-neutral);
padding: 0;
margin: 0;
display: flex;
width: 100vw;
height: 100vh;
justify-content: center;
align-items: center;
background-image: url("image.jpg");
}
body.correct {
--hue: var(--hue-correct);
}
body.wrong {
--hue: var(--hue-wrong);
}
.container {
width: 500px;
max-width: 80%;
background-color: white;
border-radius: 5px;
padding: 10px;
box-shadow: 0 0 10px 2px;
}
.btn-grid {
display: grid;
grid-template-columns: repeat(2, auto);
gap: 10px;
margin: 20px 0;
}
.btn {
--hue: var(--hue-neutral);
display: inline-block;
border: 1px solid hsl(var(--hue), 100%, 30%);
background-color: hsl(var(--hue), 100%, 50%);
border-radius: 5px;
padding: 5px 10px;
color: white;
outline: none;
transition: all 0.5s;
cursor: pointer;
}
.btn:hover {
border-color: black;
padding-right: 25px;
}
.btn.span {
cursor: pointer;
display: inline-block;
position: relative;
transition: 00.5s;
}
.btn.span:after {
content: '\00bb';
position: absolute;
opacity: 0;
top: 0;
right: -20px;
transition: 0.5s;
}
.btn:hover.span{
padding-right: 25px;
}
.btn:hover span::after{
opacity: 1;
right: 0;
}
.btn.correct {
--hue: var(--hue-correct);
color: greenyellow;
}
.btn.wrong {
--hue: var(--hue-wrong);
}
.start-btn, .next-btn {
font-size: 1.5rem;
font-weight: bold;
padding: 10px 20px;
color: aquamarine;
}
.controls {
display: flex;
justify-content: center;
align-items: center;
}
.hide {
display: none;
}
And this is my script.js file
const startButton = document.getElementById("start-btn")
const nextButton = document.getElementById("next-btn")
const questionContainerElement = document.getElementById("question-container")
const questionElement = document.getElementById("question")
const answerButtonElement = document.getElementById("answer-buttons")
let shuffledQuestions, currentQuestionIndex
startButton.addEventListener("click", startGame)
function startGame() {
startButton.classList.add("hide")
shuffledQuestions = questions.sort(() => Math.random() - .5)
currentQuestionIndex = 0
questionContainerElement.classList.remove("hide")
setNextQuestion()
}
function setNextQuestion() {
showQuestion(shuffledQuestions[currentQuestionIndex])
}
function showQuestion(question) {
questionElement.innerText = question.question
question.answers.forEach(answer => {
const button = document.createElement("button")
button.innerText = answer.text
button.classList.add("btn")
if (answer.correct) {
button.dataset.correct = answer.correct
button.addEventListener("click", selectAnswer)
answerButtonsElement.appendChild(button)
}
})
}
function resetState() {
clearStatusClass(document.body)
nextButton.classList.add("hide")
while (answerButtonsElement.firstChild){
answerButtonsElements.removeChild
(answerButtonsElement.firstChild)
}
}
function selectAnswer(e) {
const selectButton = e.target
const correct = selectedButton.dataset.correctsetStatusClass(document.body, correct)
Array.from(answerButtonsElement.children).forEach(botton => {
setStatusClass(button, button.dataset.correct)
})
if(shuffledQuestions.length > currentQuestionIndex 1) {
nextButton.classList.remove("hide")
} else {
startButton.innerText = "Restart"
startButton.classList.remove('hide')
}
}
function setStatusClass(element, correct) {
clearStatusClass(element)
if (correct) {
element.classList.add("correct")
} else {
element.classList.add("wrong")
}
}
function clearStatusClass(element) {
element.classList.remove("correct")
element.classList.remove("wrong")
}
const questions = [
{
question: 'What language do they speak in Zimbabwe?',
answers: [
{ text: 'Shona', correct: true },
{ text: 'Spanish', correct: false }
]
},
{
question: 'Who is the President of Russia?',
answers: [
{ text: 'Juju', correct: false },
{ text: 'Putin', correct: true },
{ text: 'Hitler', correct: false },
{ text: 'Clint', correct: false }
]
},
{
question: 'What are the colours of the Jamaican flag?',
answers: [
{ text: 'Pink and White', correct: false },
{ text: 'Green, yellow, white and black', correct: true },
{ text: 'White, yellow and gold', correct: false },
{ text: 'Red', correct: false }
]
},
{
question: 'What is the Capital City of Germany ?',
answers: [
{ text: 'Belgium', correct: false },
{ text: 'Berlin', correct: true }
]
},
{
question: 'In which city is the Statue of Liberty?',
answers: [
{ text: 'Soweto', correct: false },
{ text: 'New York City', correct: true }
]
},
{
question: 'Which country has a unicorn as its national animal?',
answers: [
{ text: 'Finland', correct: false },
{ text: 'Scotland', correct: true },
{ text: 'Fairytopia', correct: false },
{ text: 'Narnia', correct: false }
]
},
{
question: 'Where is Nollywood?',
answers: [
{ text: 'Nairobi', correct: false },
{ text: 'Nigeria', correct: true },
{ text: 'Namibia', correct: false },
{ text: 'Nashville', correct: false }
]
},
{
question: 'Which country is home to the tallest building?',
answers: [
{ text: 'Singapore', correct: false },
{ text: 'UAE', correct: true },
{ text: 'China', correct: false },
{ text: 'France', correct: false }
]
},
{
question: 'Which is the largest country in the world?',
answers: [
{ text: 'China', correct: false },
{ text: 'Russia', correct: true },
{ text: 'Mexico', correct: false },
{ text: 'Nigeria', correct: false }
]
},
{
question: 'Who is the President of South Korea?',
answers: [
{ text: 'Son Heung-Min', correct: false },
{ text: 'Yoon Soek-Youl', correct: true },
{ text: 'Kim Nam-Joon', correct: false },
{ text: 'Kim Bok-Joo', correct: false }
]
},
]
CodePudding user response:
There are a lot of problems in your code. To mention a few of them;
- The name of the variable that holds the
answer-buttons
container isconst answerButtonElement
at the top but everywhere else its referenced asanswerButtonsElement
. That should be corrected.
Change
const answerButtonElement = document.getElementById("answer-buttons")
to
const answerButtonsElement = document.getElementById("answer-buttons")
- In the HTML you have 10 placeholder buttons that take up all the space allowed for answer buttons so even if the code works the buttons are not visible. No need for placeholder buttons The answer container can be empty
<div id="answer-buttons" ></div>
- You are referencing
correct
during declaration of the variable. This should be fixed first declare then reference it. This should be changed
var correct = selectButton.dataset.setStatusClass(document.body)
Array.from(answerButtonsElement.children).forEach(botton => {
setStatusClass(button, button.dataset.correct)
})
- As Josh mentioned you are only appending buttons for correct answers. I think the code should be;
function showQuestion(question) {
console.log(question);
questionElement.innerText = question.question
question.answers.forEach(answer => {
console.log(answer.text);
const button = document.createElement("button");
button.innerHTML = answer.text;
button.classList.add("btn");
if (answer.correct) {
button.dataset.correct = answer.correct;
button.addEventListener("click", selectAnswer);
answerButtonsElement.appendChild(button);
}
else{
answerButtonsElement.appendChild(button);
}
})
}
instead of
function showQuestion(question) {
questionElement.innerText = question.question
question.answers.forEach(answer => {
const button = document.createElement("button")
button.innerText = answer.text
button.classList.add("btn")
if (answer.correct) {
button.dataset.correct = answer.correct
button.addEventListener("click", selectAnswer)
answerButtonsElement.appendChild(button)
}
})
}
It should be straight forward from here onwards.
CodePudding user response:
I think (having briefly read your code) that in the showQuestion() subroutine you're only appending the button object to the container if that answer is correct. You need to move the "answerButtonsElement.appendChild(button)" outside of the if statement so that all answers are added to the container.