How to show the next div and hide the previous one?

Viewed 82

New to Javascript, I'm working on a quiz like solution that uses divs and buttons to cycle through the questions. I have written some code in Javascipt but for some reason It doesn't go through the last question where it should stop. Any help will be appreciated on why the next doesn't go to the last question.

var question = document.querySelectorAll('.question');
var next = document.getElementById("next");

next.addEventListener("click", function() {
  var question = document.querySelectorAll(".question");

  for (var i = 0; i < question.length; i++) {
    if (question[i].style.display != "none") {
      question[i].style.display = "none";
      //resets to original questions
      if (i == question.length - 1) {
        question[0].style.display = "block";
      } else {
        question[i + 1].style.display = "block";
      }
      break;
    }
  }
});
.question {
  margin: 50px;
  width: 300px;
  height: 300px;
  border-radius: 10px;
  padding: 50px;
  text-align: center;
  color: white;
  background: #333;
  position: relative;
  display: none;
}

.visible {
  display: block;
}

.q-input,
.move {
  margin: 10px;
  border: none;
  padding: 10px;
}

.move {
  display: flex;
  justify-content: space-between;
}

.move button {
  padding: 5px;
  font-size: 16px;
  width: 60px;
  border-radius: 5px;
  border: none;
  cursor: pointer;
  transition: 0.4s;
}

.move button:hover {
  box-shadow: -2px -2px 20px #fff;
}

.move button:focus {
  outline: none;
}
<div class="question visible">
  <h1>Question <span class="one">1</span></h1>
  <p>What is your Name</p>
  <input type='text' class="q-input">
  <div class="move">
    <button id="prev">Prev</button>
    <button id="next">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 2</h1>
  <p>What is your Age</p>
  <input type="text" class="q-input">
  <div class="move">
    <button id="prev">Prev</button>
    <button id="next">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 3</h1>
  <p>What is your Sex</p>
  <input type="text" class="q-input">
  <div class="move">
    <button id="prev">Prev</button>
    <button id="next">Next</button>
  </div>
</div>

2 Answers

You are using document.getElementById("next") which only returns the first button with an ID of next, so only that button gets the click listener added to it.

IDs are meant to be just one unique element, so you should use class instead - change it to <button class="next">Next</button>


In your JS you should select all these next button elements, and use forEach to add a listener to all of them.

Then within that listener, you can get the connected question divs to show/hide by using parentElement and nextElementSibling, and check the next element is a question before changing the visibilities.

Also adding/removing the visible class is neater and easier to debug than trying to edit the style property manually.


All together that looks like:

var nextButtons = document.querySelectorAll('.next');

nextButtons.forEach(nextButton =>
  nextButton.addEventListener("click", function() {
    var currentQuestion = nextButton.parentElement.parentElement;
    var nextElement = currentQuestion.nextElementSibling;
    if (nextElement.classList.contains("question")) {
      nextElement.classList.add("visible");
      currentQuestion.classList.remove("visible");
    }
  }));
.question {
  margin: 50px;
  width: 300px;
  height: 300px;
  border-radius: 10px;
  padding: 50px;
  text-align: center;
  color: white;
  background: #333;
  position: relative;
  display: none;
}

.visible {
  display: block;
}

.q-input,
.move {
  margin: 10px;
  border: none;
  padding: 10px;
}

.move {
  display: flex;
  justify-content: space-between;
}

.move button {
  padding: 5px;
  font-size: 16px;
  width: 60px;
  border-radius: 5px;
  border: none;
  cursor: pointer;
  transition: 0.4s;
}

.move button:hover {
  box-shadow: -2px -2px 20px #fff;
}

.move button:focus {
  outline: none;
}
<div class="question visible">
  <h1>Question <span class="one">1</span></h1>
  <p>What is your Name</p>
  <input type='text' class="q-input">
  <div class="move">
    <button class="prev">Prev</button>
    <button class="next">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 2</h1>
  <p>What is your Age</p>
  <input type="text" class="q-input">
  <div class="move">
    <button class="prev">Prev</button>
    <button class="next">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 3</h1>
  <p>What is your Sex</p>
  <input type="text" class="q-input">
  <div class="move">
    <button class="prev">Prev</button>
    <button class="next">Next</button>
  </div>
</div>

It's not possible that more than 1 element has the same id (button next + prev), so changed to class='next' or use unique id's. You need forEach of your button an eventListener. You can use forEach to iterate over it.

var question = document.querySelectorAll('.question');
var next = document.querySelectorAll(".next");

next.forEach(n => {n.addEventListener("click", function() {
  var question = document.querySelectorAll(".question");

  for (var i = 0; i < question.length; i++) {
    if (question[i].style.display != "none") {
      question[i].style.display = "none";
      //resets to original questions
      if (i == question.length - 1) {
        question[0].style.display = "block";
      } else {
        question[i + 1].style.display = "block";
      }
      break;
    }
  }
})});
.question {
  margin: 50px;
  width: 300px;
  height: 300px;
  border-radius: 10px;
  padding: 50px;
  text-align: center;
  color: white;
  background: #333;
  position: relative;
  display: none;
}

.visible {
  display: block;
}

.q-input,
.move {
  margin: 10px;
  border: none;
  padding: 10px;
}

.move {
  display: flex;
  justify-content: space-between;
}

.move button {
  padding: 5px;
  font-size: 16px;
  width: 60px;
  border-radius: 5px;
  border: none;
  cursor: pointer;
  transition: 0.4s;
}

.move button:hover {
  box-shadow: -2px -2px 20px #fff;
}

.move button:focus {
  outline: none;
}
<div class="question visible">
  <h1>Question <span class="one">1</span></h1>
  <p>What is your Name</p>
  <input type='text' class="q-input">
  <div class="move">
    <button id="prev1">Prev</button>
    <button class="next" id="next1">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 2</h1>
  <p>What is your Age</p>
  <input type="text" class="q-input">
  <div class="move">
    <button id="prev2">Prev</button>
    <button class="next" id="next2">Next</button>
  </div>
</div>
<div class="question">
  <h1>Question 3</h1>
  <p>What is your Sex</p>
  <input type="text" class="q-input">
  <div class="move">
    <button id="prev3">Prev</button>
    <button class="next" id="next3">Next</button>
  </div>
</div>

Related