skip to Main Content

I’m wondering how to adapt this further, when I don’t use All, it works for the first question. However, on the second question, the buttons don’t work. Using All for some reason doesn’t allow me to press the buttons at all. I do plan to add more questions to this.

I am very much a beginner at this as you can see.

document.addEventListener('DOMContentLoaded', function() {

  let correct = document.querySelector('.correct');
  correct.addEventListener('click', function(event) {
    correct.style.backgroundColor = 'green';
    document.querySelector('.feedback1').innerHTML = 'Correct!';
  });

  let incorrects = document.querySelectorAll('.incorrect');
  for (let i = 0; i < incorrects.length; i++) {
    incorrects[i].addEventListener('click', function(event) {
      incorrects[i].style.backgroundColor = 'red';
      document.querySelector('.feedback1').innerHTML = 'Incorrect';
    });
  }
});
.header {
  padding: 50px;
  text-align: center;
  background: #20b2aa;
  color: white;
  font-size: 30px;
}

h1 {
  padding-top: 20px;
  font-size: 50px;
  font-family: 'Marker Felt', fantasy;
  text-align: center;
}

.container {
  margin-left: auto;
  margin-right: auto;
  padding-left: 15px;
  padding-right: 15px;
}

.section {
  padding: 0.5rem 2rem 1rem 2rem;
}

.section:hover {
  background-color: #f5f5f5;
  transition: color 2s ease-in-out, background-color 0.15s ease-in-out;
}

.imgContainer {
  text-align: center;
}

.imgButton {
  padding: 20px;
  text-align: center;
}
<!-- Bootstrap-5 -->
<link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
<script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>


<!-- Body -->
<div class="header">
  <h1>Flag Quiz</h1>
</div>

<div class="container">
  <h2 style="padding-top: 20px;">Multiple Choice Quiz</h2>
  <hr>
  <div class="section">
    <h3>What country is this?</h3>
    <p style="font-size: 20px;">1.</p>
  </div>
  <div class="imgContainer">
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Flag_of_Lithuania.svg/640px-Flag_of_Lithuania.svg.png" width="40%">
  </div>
  <div class="imgButton">
    <button class="incorrect">Myanmar</button>
    <button class="incorrect">Latvia</button>
    <button class="correct">Lithuania</button>
    <button class="incorrect">Italy</button>
    <p class="feedback1"></p>
  </div>
</div>
<div class="container">
  <div class="section">
    <h3>What country is this?</h3>
    <p style="font-size: 20px;">2.</p>
  </div>
  <div class="imgContainer">
    <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Bandera_de_Espa%C3%B1a.svg/1200px-Bandera_de_Espa%C3%B1a.svg.png" width="40%">
  </div>
  <div class="imgButton">
    <button class="correct">Spain</button>
    <button class="incorrect">Portugal</button>
    <button class="incorrect">Mexico</button>
    <button class="incorrect">China</button>
    <p class="feedback1"></p>
  </div>

</div>

I tried changing the correct answer checkers into the same format as the incorrect ones, however, that didn’t work.

3

Answers


  1. Have you tried customizing the class names of the buttons belonging to the questions?
    Since the Spanish buttons have the same class name, they are included in the Lithuanian question.

    Login or Signup to reply.
  2. Since you do not apply styles ona button, you can simply use data-attributes. You also can select them in CSS with [data-answer="correct"]. Personally I would rename them instead of using correct and incorrect and use a boolean true/false.

    You also do not need to iterate over all the buttons but could simply use target to select the clicked element.

    window.addEventListener('DOMContentLoaded', function() {
      const BUTTONS = document.querySelectorAll('button');
      BUTTONS.forEach(button =>
        button.addEventListener('click', function(element) {
          /* reads out the data-attribute of the clicked button and returns a boolean */
          let answer = (element.target.dataset.answer === 'true');
          /* gets the output element that is within the same block group of the clicked button */
          let output = element.target.closest('.imgButton').querySelector('output');
          
          /* changes the text of the output element */
          output.textContent = (answer) ? 'Correct!' : 'Incorrect';
          /* applies the a different CSS class to color the background */
          element.target.classList.add(answer ? 'bg-green' : 'bg-red');
        })
      );
    });
    .header {
      padding: 50px;
      text-align: center;
      background: #20b2aa;
      color: white;
      font-size: 30px;
    }
    
    h1 {
      padding-top: 20px;
      font-size: 50px;
      font-family: 'Marker Felt', fantasy;
      text-align: center;
    }
    
    .container {
      margin-left: auto;
      margin-right: auto;
      padding-left: 15px;
      padding-right: 15px;
    }
    
    .section {
      padding: 0.5rem 2rem 1rem 2rem;
    }
    
    .section:hover {
      background-color: #f5f5f5;
      transition: color 2s ease-in-out, background-color 0.15s ease-in-out;
    }
    
    .imgContainer {
      text-align: center;
    }
    
    .imgButton {
      padding: 20px;
      text-align: center;
    }
    
    .bg-green {
      background-color: green;
    }
    
    .bg-red {
      background-color: red;
    }
    <!-- Bootstrap-5 -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
    
    
    <!-- Body -->
    <div class="header">
      <h1>Flag Quiz</h1>
    </div>
    
    <div class="container">
      <h2 style="padding-top: 20px;">Multiple Choice Quiz</h2>
      <hr>
      <div class="section">
        <h3>What country is this?</h3>
        <p style="font-size: 20px;">1.</p>
      </div>
      <div class="imgContainer">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Flag_of_Lithuania.svg/640px-Flag_of_Lithuania.svg.png" width="40%">
      </div>
      <div class="imgButton">
        <button data-answer="false">Myanmar</button>
        <button data-answer="false">Latvia</button>
        <button data-answer="true">Lithuania</button>
        <button data-answer="false">Italy</button>
        <output class="feedback"></output>
      </div>
    </div>
    <div class="container">
      <div class="section">
        <h3>What country is this?</h3>
        <p style="font-size: 20px;">2.</p>
      </div>
      <div class="imgContainer">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Bandera_de_Espa%C3%B1a.svg/1200px-Bandera_de_Espa%C3%B1a.svg.png" width="40%">
      </div>
      <div class="imgButton">
        <button data-answer="correct">Spain</button>
        <button data-answer="incorrect">Portugal</button>
        <button data-answer="incorrect">Mexico</button>
        <button data-answer="incorrect">China</button>
        <output class="feedback"></output>
      </div>
    
    </div>
    Login or Signup to reply.
  3. I would choose event-delegation where …

    • one initially does register the reference of a single handler-function to each container-/parent-element which contains all of a distinct question’s answer-options/buttons …

    • one, within the mentioned handler-function, does query the element of the closest matching selector of the targeted answer-button.

    The handler then changes all of the related answer-buttons states, like rendering the correct feedback-text and setting certain button states like a button’s background-color and even a button element’s disabled state.

    Note

    The presented implementation explicitly uses the OP’s correct/incorrect class-names by additionally classifying a final answer as answered and providing two additional rules to it …

    .correct.answered { background-color: green; }
    .incorrect.answered { background-color: red; }
    
    function handleAnswerValidation({ target, currentTarget }) {
      // - event delegation ... part II.
      // - query the element of the closest matching
      //   selector of the targeted answer-button.
      const elmButton = target.closest('button');
      if (elmButton) {
    
        // - access the buttons classList property.
        const { classList } = elmButton;
    
        // - compute the correct feedback text/value
        //   according to the related, existing class name.
        const feedback = (
          (classList.contains('incorrect') && 'Incorrect') ||
          (classList.contains('correct') && 'Correct') ||
          ''
        );
        // - render the feedback text into the related element.
        currentTarget
          .querySelector('.feedback1')
          .textContent = feedback;
    
        // - query all current question's buttons and disable each.
        currentTarget
          .querySelectorAll('button')
          .forEach(elmButton => elmButton.disabled = true);
    
        // mark the pressed/clicked button as "answered".
        classList.add('answered');
      }
    }
    
    document
      // - event delegation ... part I.
      .querySelectorAll('.imgButton')
      // - register the reference of a single handler-function
      //   to each container-/parent-element which contains all
      //   of a distinct question's answer-options/buttons.
      .forEach(rootNode =>
        rootNode.addEventListener('click', handleAnswerValidation)
      );
    h1 {
      padding-top: 20px;
      font-size: 50px;
      font-family: 'Marker Felt', fantasy;
      text-align: center;
    }
    
    .header {
      padding: 50px;
      text-align: center;
      background: #20b2aa;
      color: white;
      font-size: 30px;
    }
    .container {
      margin-left: auto;
      margin-right: auto;
      padding-left: 15px;
      padding-right: 15px;
    }
    
    .section {
      padding: 0.5rem 2rem 1rem 2rem;
    }
    .section:hover {
      background-color: #f5f5f5;
      transition: color 2s ease-in-out, background-color 0.15s ease-in-out;
    }
    
    .imgContainer {
      text-align: center;
    }
    .imgButton {
      padding: 20px;
      text-align: center;
    }
    
    .correct.answered { background-color: green; }
    .incorrect.answered { background-color: red; }
    <!-- Bootstrap-5 -->
    <link href="https://cdn.jsdelivr.net/npm/[email protected]/dist/css/bootstrap.min.css" rel="stylesheet" integrity="sha384-rbsA2VBKQhggwzxH7pPCaAqO46MgnOM80zW1RWuH61DGLwZJEdK2Kadq2F9CUG65" crossorigin="anonymous">
    <script src="https://cdn.jsdelivr.net/npm/[email protected]/dist/js/bootstrap.bundle.min.js" integrity="sha384-kenU1KFdBIe4zVF0s0G1M5b4hcpxyD9F7jL+jjXkk+Q2h455rYXK/7HAuoJl+0I4" crossorigin="anonymous"></script>
    
    
    
    <!-- Body -->
    <div class="header">
      <h1>Flag Quiz</h1>
    </div>
    
    <div class="container">
      <h2 style="padding-top: 20px;">Multiple Choice Quiz</h2>
      <hr>
      <div class="section">
        <h3>What country is this?</h3>
        <p style="font-size: 20px;">1.</p>
      </div>
      <div class="imgContainer">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/1/11/Flag_of_Lithuania.svg/640px-Flag_of_Lithuania.svg.png" width="40%">
      </div>
      <div class="imgButton">
        <button class="incorrect">Myanmar</button>
        <button class="incorrect">Latvia</button>
        <button class="correct">Lithuania</button>
        <button class="incorrect">Italy</button>
        <p class="feedback1"></p>
      </div>
    </div>
    
    <div class="container">
      <div class="section">
        <h3>What country is this?</h3>
        <p style="font-size: 20px;">2.</p>
      </div>
      <div class="imgContainer">
        <img src="https://upload.wikimedia.org/wikipedia/commons/thumb/8/89/Bandera_de_Espa%C3%B1a.svg/1200px-Bandera_de_Espa%C3%B1a.svg.png" width="40%">
      </div>
      <div class="imgButton">
        <button class="correct">Spain</button>
        <button class="incorrect">Portugal</button>
        <button class="incorrect">Mexico</button>
        <button class="incorrect">China</button>
        <p class="feedback1"></p>
      </div>
    </div>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search