Jump to content

Stuck on my next step for quiz app


Go to solution Solved by kicken,

Recommended Posts

Hey guys,

I've been developing this app for over a month now and I just sort of built it as I went along with no real design or specifications (apart from an ERD). I knew what I wanted but sort of used an ad-hoc manner in development. Now I have got to a stage where I'm not sure what my next step is.

The app I am building is a quiz, loosely based on this quiz: https://www.bbc.co.uk/news/world-64825206

What I want is when the URL is loaded, to show the quiz Container with a "Start" Button. So a blank grey box with a "Start" Button. When the start button is pressed, then the first question comes up. Then if you visit the link above you will understand the next part. 

You see there is 3 choices, but mine will be 4 and you get the DOM scripting effect when You choose the correct answer and it goes green. Then you get green tick with a "Correct!". But I don't want the extra text underneath  to explain why the answer was right (or wrong) 

But if you choose the wrong answer, you get a red X with "Wrong!" and then the correct answer goes green. But I don't want the percentages of how many people chose the choice. And then if you get the answer right or wrong, it will display a "Next" button to move onto the next question. I want the Next button done in AJAX so it loads in the quiz container without reloading the page. 

Then you get 1 point for one correct answer and at the end of the quiz you get your total amount based on how many you got right. 

That's about it. 

My home page looks like this at the moment: (e.g www.domain.com/index.php) 

homepage.thumb.png.32c74813d1dd00215eb82130fe14ff5b.png

Now obviously it says "Question does not exist" because I changed the quiz to use GET to scroll through the questions. obviously if I add 

?question=1

to the end of the URL it will display question 1.

Here is what the questions look like:

quiz_ss.thumb.jpg.cc3e05287545476d67540e898027702e.jpg

 

Sorry for the long post but I'm really stuck on my next move. I have a bad feeling I've been developing the app the wrong way round.

Many thanks

Link to comment
https://forums.phpfreaks.com/topic/316159-stuck-on-my-next-step-for-quiz-app/
Share on other sites

I have been developing another JavaScript game though I have a Trivia game that is what you are looking for?  If you look at the JavaScript either by using inspect or viewing the source code it might give an idea in what direction to take?

https://www.fanoflego.com/trivia.php

This is the game I have been developing -> https://www.phototechguru.com/hangman/can_you_solve.php that might also help?

 

This GitHub Repository might also help? https://github.com/Strider64/phototechguru though the Trivia game is an older version of it.

Edited by Strider64

If you're not interested in storing results for the quiz, then probably the easiest approach would be to just dump out all the questions when the initial page loads, then use some JavaScript to display them one at a time.  That removes the complexity of dynamically loading the questions.

Either way though, step 1 is just getting your JavaScript sorted out for marking your correct/incorrect answers and showing the next button.  That's the same whether you load the questions dynamically or all at once.  You need a way in your HTML to indicate which answer is correct, then attach some on click handlers to your answer divs that checks if the one they clicked is correct or not and updates the display accordingly.

Here's an example of loading all the questions at once, then displaying them one at a time.

HTML:

<div id="quiz">
  <div class="question active">
    <p>
      In the movie "Father of the Bride", George Banks played by Steve Martin goes to jail for opening up what food in the supermarket?
    </p>
    <ul class="answers">
      <li>Burger buns</li>
      <li data-correct>Hot dog rolls</li>
      <li>Sausages</li>
      <li>Twinkies</li>
    </ul>
  </div>
  <div class="question">
    <p>
      Some second example question
    </p>
    <ul class="answers">
      <li>Answer 1</li>
      <li>Answer 2</li>
      <li>Answer 3</li>
      <li data-correct>Answer 4</li>
    </ul>
  </div>
  <div class="buttons">
    <button type="button" id="next-question">
      Next question
    </button>
  </div>
</div>

JS:

window.addEventListener('DOMContentLoaded', () => {
	const quiz = document.getElementById('quiz');
  
  document.getElementById('next-question').addEventListener('click', nextQuestion);
	for (let question of document.querySelectorAll('.question')){
  	setupQuestion(question);
  }
  
  function setupQuestion(question){
  	const answers = question.querySelector('.answers');
    answers.addEventListener('click', (e) => {
    	if (e.target.nodeName!=='LI' || quiz.classList.contains('answered')){
      	return;
      }
      
      e.target.classList.add('selected');
      quiz.classList.add('answered');
    });
  }
  
  function nextQuestion(){
  	const activeQuestion = document.querySelector('.question.active');
    const nextQuestion = activeQuestion.nextElementSibling;
    if (nextQuestion.classList.contains('question')){
    	activeQuestion.classList.remove('active');
    	nextQuestion.classList.add('active');
      quiz.classList.remove('answered');
    }
  }
});

CSS:

/** Base styles */
.buttons {
  visibility: hidden;
  text-align: center;
}

.question {
  display: none;
}

.question.active {
  display: block;
}

.answers {
  list-style-type: none;
  display: grid;
  grid-template-columns: auto auto;
  grid-gap: 20px;
}

.answers > li {
  border: 2px solid black;
  text-align: center;
  padding: 10px 0;
}

.answers > li:hover {
  background-color: #888;
}

/** Styles for when the question has been answered */
.answered .buttons {
  visibility: visible;
}

.answered .answers .selected {
  background: #f88;
}

.answered .answers .selected::before {
  display: inline-block;
  content: '\274c';
}

.answered .answers [data-correct] {
  background-color: #8f8;
}

.answered .answers [data-correct]::before {
  display: inline-block;
  content: '\2705';
}

 

18 hours ago, Strider64 said:

though I have a Trivia game that is what you are looking for? 

That's a really good trivia game Strider. I want something very similar to that.

18 hours ago, kicken said:

That removes the complexity of dynamically loading the questions.

If I did want to load them dynamically, would I be able to reuse the below code?

 <?php

include 'includes/db.php';

//Assume no results.
$results = [];
$questionId = $_GET['question'] ?? '';
if ($questionId){
    //Only run the query if we have an id.
    $sql = "SELECT q.question, o.choice, q.image 
        FROM questions q 
        JOIN quiz_options o 
          ON q.qid = o.qid 
        WHERE q.qid = :id;";
    $stmt = $pdo->prepare($sql);
    $stmt->execute(['id' => $questionId]);

    //Fetch all the result rows
    $results = $stmt->fetchAll(PDO::FETCH_NUM);
}

//If we have any results
if ($results){
    //Display them
    $last_q = 'x';    // a non-existent value
    $choice_num = 0;
    foreach ($results as [$q, $c, $i]){
        if ($q <> $last_q) // starting a new question so close the last div and begin a new one
        {
            if ($last_q <> 'x') // is this the first question? If not, close the last question's box
            {
                echo "</div>";
            }
            echo "<div class='quizContent'>";  // start the new question box
            echo "<p>$q</p>"; // show the question  - figure out later how to prevent repetition (which I did earlier)

            $pathx = "images/db_images/";

            echo '<img class="picture" src="' . $pathx . $i . '">';

            $choice_num = 0;  // new question; new choice count
        }

        $choice_class = 'choice' . $choice_num; // setup the appropriate choice class
        $last_q = $q;   // remember the current question
        //echo "<p>$q</p>"; // show the question  - figure out later how to prevent repetition (which I did earlier)
        echo "<div class='$choice_class'>";   // a box for this choice
        echo "<p>$c</p>";
        echo "</div>";    // close this choice's box
        $choice_num++;    // bump the choice cnt
    }
    echo "</div>";    // close the last question box
} else {
    //Display an error
    $errorAnswer = 'Question does not exist';
}

?>


<?php 
if (isset($errorAnswer)) {
     
    echo "<p class='quizError'>$errorAnswer</p>";
    
}
?>

Or would it be a matter of writing new code that generates a HTML document that looks like the html in your fiddle?

18 hours ago, kicken said:

step 1 is just getting your JavaScript sorted out for marking your correct/incorrect answers and showing the next button

Yes, I thought the next step was the "Next" button and I was going to do something like create a button, put 1 in there related to question number 1 and then increment it inside the link go to the question 2.

But I had a bad feeling that if I did that it would just be a waste of time because of all the JS involved

Thanks kicken

Edited by webdeveloper123
  • Solution
1 hour ago, webdeveloper123 said:

If I did want to load them dynamically, would I be able to reuse the below code?

Or would it be a matter of writing new code that generates a HTML document that looks like the html in your fiddle?

You can generate whatever HTML you want and swap it out using the JS code.  The HTML structure in my example is how I'd probably code it, but nothing about it is required.  You'd need to adjust the JS to match up with whatever your final HTML is with regards to the classes/IDs etc.

 

1 hour ago, webdeveloper123 said:

Yes, I thought the next step was the "Next" button and I was going to do something like create a button, put 1 in there related to question number 1 and then increment it inside the link go to the question 2.

There are a variety of ways to handle the next question bit. You could include a link to the next question when loading the current question.  You could load a list of question IDs when the page first loads and use JS to walk the list.  You could load the questions by a display number (1, 2, 3, ...) and just keep incrementing it until you get a 'No more questions' response.

Since you already have code to load a question by it's ID, one of the first two options might be easiest to implement.  The first option would keep you coding mostly in PHP by just returning a link for the JS to follow.  The second involves a little more JS work to walk the list of question IDs.

 

Hey Kicken,

I went with your HTML solution. Loaded all the questions and added images. Now I am only a basic JS programmer, made things like calculators and Rock, Paper & scissor games (using Math.Random) but I want to extend your JS.

First of all to have a feature where scores are kept track off. So If I get the first question right it will say 1/1 (one point from one question) and so on.  So if I get to question 5 and have 3 correct answers it will say (3/5). With the text "Score 3/5"

And I want to remove the "Next Question" button when it gets to the last question.

Could you help me with the logic.

So for the scores would I have to track each click (if its correct add to array) then loop round the array and add all the scores?

And the "Next question" part would I have to recognise when on the last question and say "I'm on the last question so nextbutton.remove or something? (pseudo code)

Thanks

1 hour ago, webdeveloper123 said:

First of all to have a feature where scores are kept track off. So If I get the first question right it will say 1/1 (one point from one question) and so on.  So if I get to question 5 and have 3 correct answers it will say (3/5). With the text "Score 3/5"

Add two counter variables to the code, one for total questions answered and one for total correct.  In the click handler for the answers, increment the total questions variable, and if the answer was correct, increment the total correct variable.  Update some elements on the page with the new values.

1 hour ago, webdeveloper123 said:

And I want to remove the "Next Question" button when it gets to the last question.

In the existing code, if you move these lines outside of the if condition, then it'll show a blank screen when hitting next question at the end.

quiz.classList.remove('answered');
activeQuestion.classList.remove('active');

If you want to do more than just a blank screen, then add additional code as an else branch on the conditional.  If you wanted to have a "Finished" screen for example, you could and another class on the quiz, quiz.classList.add('finished').   Update the CSS to show some another div with your quiz finished content when that class has been applied.

 

 

14 minutes ago, kicken said:

if you move these lines outside of the if condition, then it'll show a blank screen

Thanks, I did that, works nicely.

Trying to implement your other advice at the moment.

Oh and I wanted a "Progress Text". As in If I am on question 4, it will display 4/15 so the user knows how many questions are left

Hey Kicken,

I've been trying to implement your logic but only got some of it done.

The total questions variable is fine, it increments as it goes along which is great.

The problem is the total correct variable. 

On 4/21/2023 at 4:54 PM, kicken said:

Add two counter variables to the code, one for total questions answered and one for total correct

Done that.

 

On 4/21/2023 at 4:54 PM, kicken said:

In the click handler for the answers, increment the total questions variable,

Done that, works fine.

On 4/21/2023 at 4:54 PM, kicken said:

and if the answer was correct, increment the total correct variable

Having problems with this bit. I have got it to the stage where it does increment the variable for the correct answer, but also increments it for an incorrect answer as well. Could you help?

Here is the new HTML:

<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="css/quizstyle.css">
	 <script src="js/question.js"></script>
<meta charset="UTF-8">
<title> Document </title>
</head>
<body>

<div id="quiz">
  <p id="score"></p>
  <div class="question active">
    <p>
     Who plays Nicky Santoro in the film "Casino"?
    </p>
    <img class="picture" src="images/db_images/de_niro.jpg">
    <ul class="answers">
      <li data-correct>Joe Pesci</li>
      <li>Anthony Hopkins</li>
      <li>Robert De Niro</li>
      <li>Christian Bale</li>
    </ul>
  </div>
  <div class="question">
    <p>
      What year was Titanic released?
    </p>
    <img class="picture" src="images/db_images/titanic3d.webp">
    <ul class="answers">
      <li>1995</li>
      <li data-correct>1997</li>
      <li>2000</li>
      <li>2002</li>
    </ul>
  </div>
  <div class="question">
    <p>
      In Romeo & Juliet, what house is Romeo from?
    </p>
    <img class="picture" src="images/db_images/romeo.jpg">
    <ul class="answers">
      <li>Capulet</li>
      <li>Patels</li>
      <li>Jones</li>
      <li data-correct>Montague</li>
    </ul>
  </div>
    <div class="question">
    <p>
      Who plays Gregory Focker in the Meet the Parents movies?
    </p>
    <img class="picture" src="images/db_images/owen_wilson.jpg">
    <ul class="answers">
      <li>Seth Rogen</li>
      <li>Johnny Depp</li>
      <li data-correct>Ben Stiller</li>
      <li>Vin Diesel</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In Home Alone 2, Kevin is lost in which city?
    </p>
    <img class="picture" src="images/db_images/home_alone.jpg">
    <ul class="answers">
      <li>Paris</li>
      <li>Chicago</li>
      <li>Rajkot</li>
      <li data-correct>New York</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In the movie "Father of the Bride", George Banks played by Steve Martin goes to jail for opening what food in the supermarket?
    </p>
    <img class="picture" src="images/db_images/father_bride.webp">
    <ul class="answers">
      <li>Burger Buns</li>
      <li data-correct>Hot dog Rolls</li>
      <li>Sausages</li>
      <li>Twinkies</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the Movie Troy, Brad Pitt is known by which name?
    </p>
    <img class="picture" src="images/db_images/troy4.jpg">
    <ul class="answers">
      <li>Agamemnon</li>
      <li data-correct>Achilles</li>
      <li>Patroclus</li>
      <li>Menelaus</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In the movie Top Gun, what planes are flown by the US Navy?
    </p>
    <img class="picture" src="images/db_images/top_gun.jpg">
    <ul class="answers">
      <li>F-16</li>
      <li>Mig</li>
      <li data-correct>F-14</li>
      <li>F-5 Tiger</li>
    </ul>
  </div>
      <div class="question">
    <p>
      Marlon Brando plays which character in the movie Godfather?
    </p>
    <img class="picture" src="images/db_images/godfather.jpg">
    <ul class="answers">
      <li data-correct>Vito Corleone</li>
      <li>Michael Corleone</li>
      <li>Sonny Corleone</li>
      <li>Fredo Corleone</li>
    </ul>
  </div>
     <div class="question">
    <p>
      Russel Crowe is known by what name in Gladiator?
    </p>
    <img class="picture" src="images/db_images/gladiator.webp">
    <ul class="answers">
      <li>The Italian</li>
      <li>The Hammer</li>
      <li data-correct>The Spaniard</li>
      <li>Lion Killer</li>
    </ul>
  </div>
       <div class="question">
    <p>
      Which other movie did the character "Hector" played by Eric Bana in Troy appear in?
    </p>
    <img class="picture" src="images/db_images/black_hawk.jpg">
    <ul class="answers">
      <li data-correct>Black Hawk Down</li>
      <li>Goodfellas</li>
      <li>The Wedding Singer</li>
      <li>Lock, Stock & 2 Smoking Barrels</li>
    </ul>
  </div>
       <div class="question">
    <p>
      Rowan Atkinson appears in the movie "Rat Race", but what disorder does he suffer from?
    </p>
    <img class="picture" src="images/db_images/rat_race.jpg">
    <ul class="answers">
      <li>Personality Disorder</li>
      <li>Autism</li>
      <li>Dementia</li>
      <li data-correct>Narcolepsy</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the movie "Snatch", all of the underworld characters are trying to steal what from each other?
    </p>
    <img class="picture" src="images/db_images/snatch.jpg">
    <ul class="answers">
      <li>Gold Bar</li>
      <li data-correct>Diamond</li>
      <li>£1million in a breifcase</li>
      <li>Sapphire</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the movie "Layer Cake", Daniel Craig plays which character?
    </p>
    <img class="picture" src="images/db_images/layer_cake.jpg">
    <ul class="answers">
      <li>Dodgy Dave</li>
      <li>Brick Top</li>
      <li>Bullet Tooth Tony</li>
      <li data-correct>**** (Name is not revealed)</li>
    </ul>
  </div>
      <div class="question">
    <p>
      For how many years has the movie "Dilwale Dulhania Le Jayenge" been running for in cinemas in India?
    </p>
    <img class="picture" src="images/db_images/ddlj.webp">
    <ul class="answers">
      <li>25 Years</li>
      <li>26 Years</li>
      <li data-correct>27 Years</li>
      <li>28 Years</li>
    </ul>
  </div>
  <div class="buttons">
    <button type="button" id="next-question">
      Next question
    </button>
  </div>
</div>



</body>
</html>

And here is the extended Javascript:

window.addEventListener('DOMContentLoaded', () => {
	const quiz = document.getElementById('quiz');

     let totalanswered = 0;
          let totalcorrect = 0;
        const list = document.querySelector('li');

  document.getElementById('next-question').addEventListener('click', nextQuestion);
	for (let question of document.querySelectorAll('.question')){
  	setupQuestion(question);
  }
  
  function setupQuestion(question){
  	const answers = question.querySelector('.answers');
    answers.addEventListener('click', (e) => {

      totalanswered++;

        if (list.hasAttribute("data-correct")) {
                totalcorrect++;
        }

          document.getElementById("score").innerHTML =  `${totalcorrect } correct out of ${totalanswered}`;

         

    	if (e.target.nodeName!=='LI' || quiz.classList.contains('answered')){
       
      	return;

      }
      
      e.target.classList.add('selected');
      quiz.classList.add('answered');

    });
  }
  
  function nextQuestion(){
  	const activeQuestion = document.querySelector('.question.active');
    const nextQuestion = activeQuestion.nextElementSibling;
    if (nextQuestion.classList.contains('question')){
    
    	nextQuestion.classList.add('active');
      
    }
    quiz.classList.remove('answered');
  activeQuestion.classList.remove('active');
  }
});

Many thanks 

2 hours ago, webdeveloper123 said:
const list = document.querySelector('li');

This is setting your list variable to whatever the first <li> element is in the document.  That would be the first choice of the first question, which you happen to have marked as correct.  There's no need for this variable, so remove it.

What you need to be doing instead is check if the element that was clicked has the data-correct attribute.  You already have code that applies the "selected" class to the element that was clicked so expand on that.

I did it. I added the code:

  let correct = e.target;
       
        if (correct.hasAttribute("data-correct")) {
                totalcorrect++;
        }

And its fine now. Only problem is that when I click on an answer, if its correct the totalcorrect will increment, as will the totalanswered, which is great but it allows me to continue clicking on answers and keeps incrementing the totalanswered , even if I have chosen an answer. Do I have to put  totalanswered in an if statement and say something like "Once an answer is chosen , only increment once for that screen and when you get to the next question you can increment that too"

1 hour ago, webdeveloper123 said:

Once an answer is chosen

This condition already exists in the code.  Notice that once you have selected an answer, you cannot change it.

All you need to do is re-arrange your code so that you increment your totals after this condition has been checked.

 

1 hour ago, webdeveloper123 said:

are you referring to this condition?

Yes.

19 minutes ago, webdeveloper123 said:

did you mean both totals or just totalanswered?

Both. 

Essentially you want your click handler to do nothing if the question is already answered.  That's what that if condition does, makes the function return (stop) if you click a non-li element or the quiz is answered.

 

This is what I did and it still doesn't work:

  function setupQuestion(question){
  	const answers = question.querySelector('.answers');
    answers.addEventListener('click', (e) => {

        document.getElementById("score").innerHTML =  `${totalcorrect } correct out of ${totalanswered}`;

    	if (e.target.nodeName!=='LI' || quiz.classList.contains('answered')){
 
      	return;

      }
      let correct = e.target;
		totalanswered++;

           if (correct.hasAttribute("data-correct")) {
                totalcorrect++;
        }

      e.target.classList.add('selected');
      quiz.classList.add('answered');

    });
  }
  

 

ah ha! I had a feeling it was that!

4 minutes ago, kicken said:

The update delay is because you're doing the display update before you update the totals.

I thought why display the score before you incremented them. But because the score was showing I didn't investigate further

Thanks for your help!

 

Hey,

I am trying to add a finished screen to the end of the quiz. I added an else on the conditional which is:

quiz.classList.add('finished');

It shows at the end, but it shows at the start of the quiz because I added this to the HTML:

<div class="finished">
    <p>You have reached the end of the quiz!</p>
    </div>

So I added this to the JS:

if (nextQuestion.classList.contains('question')){
    
    	nextQuestion.classList.add('active');
      quiz.classList.remove('finished');

      
    }

Here is my added css:

.finished {
  background-color: red;
}

But it still shows at the start of the quiz, all the way through and at the end. I'm starting to think it's only showing at the end because of the HTML, not the JS. Is this more to do with toggling classes? Or do I have to have a "hide" class as well to hide it during the quiz. e.g:

.hide {
display: none;
}

In there somewhere in the JS?

Here is my full HTML:
 

<!DOCTYPE html>
<html>
<head>
	<link rel="stylesheet" href="css/quizstyle.css">
	 <script src="js/question.js"></script>
<meta charset="UTF-8">
<title> Document </title>
</head>
<body>

<div id="quiz">
  <p id="score"></p>
  <p id="demo"></p>
  <div class="question active">
    <p>
     Who plays Nicky Santoro in the film "Casino"?
    </p>
    <img class="picture" src="images/db_images/de_niro.jpg">
    <ul class="answers">
      <li data-correct>Joe Pesci</li>
      <li>Anthony Hopkins</li>
      <li>Robert De Niro</li>
      <li>Christian Bale</li>
    </ul>
  </div>
  <div class="question">
    <p>
      What year was Titanic released?
    </p>
    <img class="picture" src="images/db_images/titanic3d.webp">
    <ul class="answers">
      <li>1995</li>
      <li data-correct>1997</li>
      <li>2000</li>
      <li>2002</li>
    </ul>
  </div>
  <div class="question">
    <p>
      In Romeo & Juliet, what house is Romeo from?
    </p>
    <img class="picture" src="images/db_images/romeo.jpg">
    <ul class="answers">
      <li>Capulet</li>
      <li>Patels</li>
      <li>Jones</li>
      <li data-correct>Montague</li>
    </ul>
  </div>
    <div class="question">
    <p>
      Who plays Gregory Focker in the Meet the Parents movies?
    </p>
    <img class="picture" src="images/db_images/owen_wilson.jpg">
    <ul class="answers">
      <li>Seth Rogen</li>
      <li>Johnny Depp</li>
      <li data-correct>Ben Stiller</li>
      <li>Vin Diesel</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In Home Alone 2, Kevin is lost in which city?
    </p>
    <img class="picture" src="images/db_images/home_alone.jpg">
    <ul class="answers">
      <li>Paris</li>
      <li>Chicago</li>
      <li>Rajkot</li>
      <li data-correct>New York</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In the movie "Father of the Bride", George Banks played by Steve Martin goes to jail for opening what food in the supermarket?
    </p>
    <img class="picture" src="images/db_images/father_bride.webp">
    <ul class="answers">
      <li>Burger Buns</li>
      <li data-correct>Hot dog Rolls</li>
      <li>Sausages</li>
      <li>Twinkies</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the Movie Troy, Brad Pitt is known by which name?
    </p>
    <img class="picture" src="images/db_images/troy4.jpg">
    <ul class="answers">
      <li>Agamemnon</li>
      <li data-correct>Achilles</li>
      <li>Patroclus</li>
      <li>Menelaus</li>
    </ul>
  </div>
      <div class="question">
    <p>
      In the movie Top Gun, what planes are flown by the US Navy?
    </p>
    <img class="picture" src="images/db_images/top_gun.jpg">
    <ul class="answers">
      <li>F-16</li>
      <li>Mig</li>
      <li data-correct>F-14</li>
      <li>F-5 Tiger</li>
    </ul>
  </div>
      <div class="question">
    <p>
      Marlon Brando plays which character in the movie Godfather?
    </p>
    <img class="picture" src="images/db_images/godfather.jpg">
    <ul class="answers">
      <li data-correct>Vito Corleone</li>
      <li>Michael Corleone</li>
      <li>Sonny Corleone</li>
      <li>Fredo Corleone</li>
    </ul>
  </div>
     <div class="question">
    <p>
      Russel Crowe is known by what name in Gladiator?
    </p>
    <img class="picture" src="images/db_images/gladiator.webp">
    <ul class="answers">
      <li>The Italian</li>
      <li>The Hammer</li>
      <li data-correct>The Spaniard</li>
      <li>Lion Killer</li>
    </ul>
  </div>
       <div class="question">
    <p>
      Which other movie did the character "Hector" played by Eric Bana in Troy appear in?
    </p>
    <img class="picture" src="images/db_images/black_hawk.jpg">
    <ul class="answers">
      <li data-correct>Black Hawk Down</li>
      <li>Goodfellas</li>
      <li>The Wedding Singer</li>
      <li>Lock, Stock & 2 Smoking Barrels</li>
    </ul>
  </div>
       <div class="question">
    <p>
      Rowan Atkinson appears in the movie "Rat Race", but what disorder does he suffer from?
    </p>
    <img class="picture" src="images/db_images/rat_race.jpg">
    <ul class="answers">
      <li>Personality Disorder</li>
      <li>Autism</li>
      <li>Dementia</li>
      <li data-correct>Narcolepsy</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the movie "Snatch", all of the underworld characters are trying to steal what from each other?
    </p>
    <img class="picture" src="images/db_images/snatch.jpg">
    <ul class="answers">
      <li>Gold Bar</li>
      <li data-correct>Diamond</li>
      <li>£1million in a breifcase</li>
      <li>Sapphire</li>
    </ul>
  </div>
    <div class="question">
    <p>
      In the movie "Layer Cake", Daniel Craig plays which character?
    </p>
    <img class="picture" src="images/db_images/layer_cake.jpg">
    <ul class="answers">
      <li>Dodgy Dave</li>
      <li>Brick Top</li>
      <li>Bullet Tooth Tony</li>
      <li data-correct>**** (Name is not revealed)</li>
    </ul>
  </div>
      <div class="question">
    <p>
      For how many years has the movie "Dilwale Dulhania Le Jayenge" been running for in cinemas in India?
    </p>
    <img class="picture" src="images/db_images/ddlj.webp">
    <ul class="answers">
      <li>25 Years</li>
      <li>26 Years</li>
      <li data-correct>27 Years</li>
      <li>28 Years</li>
    </ul>
  </div>
  <div class="buttons">
    <button type="button" id="next-question">
      Next question
    </button>
  </div>
  <div class="finished">
    <p>You have reached the end of the quiz!</p>
    </div>
</div>



</body>
</html>

Here is the full JS:

window.addEventListener('DOMContentLoaded', () => {
	const quiz = document.getElementById('quiz');

     let totalanswered = 0;
     let totalcorrect = 0;

  document.getElementById('next-question').addEventListener('click', nextQuestion);
	for (let question of document.querySelectorAll('.question')){
  	setupQuestion(question);
  }
  
  function setupQuestion(question){
  	const answers = question.querySelector('.answers');
    answers.addEventListener('click', (e) => {

    	if (e.target.nodeName!=='LI' || quiz.classList.contains('answered')){

      	return;
      }

      let correct = e.target;

        totalanswered++;

                 if (correct.hasAttribute("data-correct")) {
                totalcorrect++;
        }

                  document.getElementById("score").innerHTML =  `${totalcorrect } correct out of ${totalanswered}`;
      e.target.classList.add('selected');
      quiz.classList.add('answered');


    });


  }
  
  function nextQuestion(){
  	const activeQuestion = document.querySelector('.question.active');
    const nextQuestion = activeQuestion.nextElementSibling;
    if (nextQuestion.classList.contains('question')){
    
    	nextQuestion.classList.add('active');
      quiz.classList.remove('finished');

      
    } else {
              quiz.classList.add('finished');


    }
    quiz.classList.remove('answered');
  activeQuestion.classList.remove('active');
  }
});

and the full CSS:

/** Base styles */
.buttons {
  visibility: hidden;
  text-align: center;
}

.question {
  display: none;
  text-align: center;
}

.question.active {
  display: block;
}

.answers {
  list-style-type: none;
  display: grid;
  grid-template-columns: auto auto;
  grid-gap: 20px;
}

.answers > li {
  border: 2px solid black;
  text-align: center;
  padding: 10px 0;
}

.answers > li:hover {
  background-color: #888;
}

/** Styles for when the question has been answered */
.answered .buttons {
  visibility: visible;
}

.answered .answers .selected {
  background: #f88;
}

.answered .answers .selected::before {
  display: inline-block;
  content: '\274c';
}

.answered .answers [data-correct] {
  background-color: #8f8;
}

.answered .answers [data-correct]::before {
  display: inline-block;
  content: '\2705';
}

.picture{
 height: 300px;
  width: 480px;
   object-fit: contain;
 
}
.finished {
  background-color: red;
}

Many thanks

Edited by webdeveloper123

You need to use the same type of trick as with the questions.  Note the CSS for those:

.question {
  display: none;
  text-align: center;
}

.question.active {
  display: block;
}

 

Elements with .question are hidden by default (display: none) then shown when given the active class (.question.active selector).

So you create your finished screen and make it hidden by default, then add CSS that will show it when you've added the finished class to your quiz element (.quiz.finished).  It'd probably be best to not use the same class name for both your finish screen and your finished marker on the quiz, which is what you are doing currently.

 

 

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.