2

I am making a small quiz application using javascript and html. The quiz is set up so that the user can only see one question on the page. When they press the previous and next buttons, it shows the user the previous and next question respectively.

What I am trying to do is, loop through an array of elements returned by getElementByClassName and display the next item each time the user presses the "next" button. The problem that I currently have is, when the "next" button is pressed, every single element that comes after the first one is displayed onto the page. There is also a "previous" button on the page that shows the user the immediate previous element, however it removes the very first element in the array, shows an "Cannot set property 'display' of undefined" error and the rest of the div elements are still shown on the page.

This is the current code HTML:

const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.getElementsByClassName('quiz');
//show and hide divs when user presses next
nextBtn.addEventListener('click', function() {
  for (i = 0; i < quizes.length; i++) {
    quizes[i].style.display = "block";
  }
})

prevBtn.addEventListener('click', function() {
  if (quizes.length > 1) {
    for (i = 0; quizes.length > 1; i--) {
      if (quizes[i].display = "block") {
        quizes[i].style.display = "none";
      }
    }
  } else {
    alert('no more previous questions!')
  }
})
<div class="quiz">
  <p>Question 1</p>
  <input type="radio" name="answer" value="1">
  <input type="radio" name="answer" value="2">
  <input type="radio" name="answer" value="3">
</div>

<div class="quiz" style="display: none">
  <p>Question 2</p>
  <input type="radio" name="answer" value="1">
  <input type="radio" name="answer" value="2">
  <input type="radio" name="answer" value="3">
</div>
<button id="prev">Prev</button>
<button id="next">Next</button>

Any explanation on the error and any hints to the right direction is greatly appreciated. Thank you.

3
  • 3
    if(quizes[i].display="block"){ you're missing two equal signs here. === Commented Feb 5, 2021 at 14:57
  • 1
    You don't want to use a loop. You should keep track of the visible question. When the user clicks "Next", hide the current one and display the next. Commented Feb 5, 2021 at 15:00
  • 2
    quizes[i].*style*.display in your if Commented Feb 5, 2021 at 15:02

1 Answer 1

5

I think what you should do is to keep a track of which question is currently visible, then toggle all other questions before you make the active one visible.

I've made a quick example below I hope you can understand the thought behind, let me know otherwise.

const nextBtn = document.getElementById('next');
const prevBtn = document.getElementById('prev');
const quizes = document.querySelectorAll('.quiz');
const total = quizes.length;
let count = 0;

const hideAll = () => quizes.forEach( q => q.style.display = 'none' );

const showNext = () => {
    if(count < total-1) count++;
  else {
    alert('no more questions');
    return;
  }
  
  hideAll();
  quizes[count].style.display = 'block';
}

const showPrev = () => {
    if(count > 0) count--;
  else {
    alert('no more previous questions');
    return;
  }
  
  hideAll();
  quizes[count].style.display = 'block';
}



//show and hide divs when user presses next
nextBtn.addEventListener('click',function(){
  showNext();
})


prevBtn.addEventListener('click',function(){
  showPrev();
})
<div class="quiz">
        <p>Question 1</p>
        <input type="radio" name="answer" value="1">
        <input type="radio" name="answer" value="2">
        <input type="radio" name="answer" value="3">
        </div>

        <div class="quiz" style="display: none">
        <p>Question 2</p>
        <input type="radio"  name="answer" value="1">
        <input type="radio"  name="answer" value="2">
        <input type="radio"  name="answer" value="3">
        </div>

<div class="quiz" style="display: none">
        <p>Question 3</p>
        <input type="radio"  name="answer" value="1">
        <input type="radio"  name="answer" value="2">
        <input type="radio"  name="answer" value="3">
        </div>
        
        <div class="quiz" style="display: none">
        <p>Question 4</p>
        <input type="radio"  name="answer" value="1">
        <input type="radio"  name="answer" value="2">
        <input type="radio"  name="answer" value="3">
        </div>
        
<button id="prev">Prev</button>
<button id="next">Next</button>

Sign up to request clarification or add additional context in comments.

1 Comment

Additionally, instead of using the inline style="display: none" I would use a class like active-question. So your css would target .quiz and have display none, but then .quiz.active-question would have display block. Then you just need to add/remove the class active-question instead of changing inline styles.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.