How to hide current element and show next on button click?

7.5k Views Asked by At

I have a JQuery questionnaire website on mobile. Most of the website users use Opera Mini, and the current JQuery mobile animations are not fully supported.

I then decided to implement a bootstrap based website, rather than JQuery mobile. This time I want to implement so that one question appears at a time, and when a user wants to go to the next question, they just press next.

How can I implement this?

I currently have something like this:

$('#next').click(function(){
    $('#question1').hide();
    $('#question2').show();

});

But I have 30 some-odd questions, so, how can I set it up dynamically with as simple of a code as possible?

Your help would be greatly appreciated.

3

There are 3 best solutions below

9
Wesley Smith On BEST ANSWER

In general, you shouldnt use ids for something like this, it's just more trouble than it's worth. Instead, just use classes. A simple implementation might look like this:

$('#next').click(function(){
    var $current = $('.question.active');
    // use $current here to test if the question was answered if needed 
    // maybe something like if($current.find('.answer').val().trim() == ''){ return;}
    $('.question').removeClass('active');
    $current.next().addClass('active');
});
.question:not(.active){
  display:none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div id="questions">
  <div class="question active">Some question 1</div>
  <div class="question">Some question 2</div>
  <div class="question">Some question 3</div>
  <div class="question">Some question 4</div>
  <div class="question">Some question 5</div>
  <div class="question">Some question 6</div>
  <div class="question">Some question 7</div>
  <div class="question">Some question 8</div>
</div>
<button type="button" id="next">Next</button>

2
natejms On

If we're to use jQuery as in the example you gave in the question, the program could look something along the lines of the following.

It looks like you are wrapping each element in an element that has the ID of "question", followed by the question number. If each question follows this rule, we can declare a variable and give it a value of one (we'll call this variable q). To select the current question, use $("#question" + q). Each time the #next button is clicked, hide the current question, add 1 to q and open the next. For an example:

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

<form action="#">
  <div id="question1" class="questions">
    <input type="text" placeholder="Question 1">
  </div>
  <div id="question2" class="questions">
    <input type="text" placeholder="Question 2">
  </div>
  <div id="question3" class="questions">
    <input type="text" placeholder="Question 3">
  </div>
  <div id="question4" class="questions">
    <input type="text" placeholder="Question 4">
  </div>
  <div id="question5" class="questions">
    <input type="text" placeholder="Question 5">
  </div>
  <button id="next">Next</button>
</form>

<script>
  var q = 1

  $(document).ready(function() {
    $(".questions").hide();
    $("#question1").show();
  
    $("#next").click(function() {
    
      $("#question" + q).hide();
       q = q + 1;
      if(q > 5) {
        $("#next").remove();
        $("body").append("<input type='submit' value='Submit'>");
      } else {
        $("#question" + q).show();
      }
    });
  });
</script>

Here, each time you click the #next button, one digit gets added to the q variable. If all 5 questions have been passed, the submit button appears, thus allowing you to submit your answers. Otherwise, the next question gets displayed.

If you wanted to add any animations, you could simply swap out .hide() and .show() with things like .fadeIn(), .slideDown(), etc cetera.

Edit - Back button

If we're using classes instead of ID's as done by @DelightedD0D (since it is infact more manageble), you could create a back button buy using the .prev() method in order to select the previous element.

$('#previous').click(function(){
    var $current = $('.question.active');
    $('.question').removeClass('active');
    $current.prev().addClass('active');
});

If you're using ID's, it would look something like this:

$("#previous").click(function() {
    if((q - 1) == 1) {
      $("#previous").hide();
    }
    $("#question" + q).hide();
    q = q - 1;
    $("#question" + q).show();

});

With the following modifications to the rest of the script:

$(".questions").hide();
$("#previous").hide();
$("#question1").show();

$("#next").click(function() {
    $("#question" + q).hide();
    q = q + 1;
    if(!$("#previous").is(":visible")) {
      $("#previous").show();
    }
    if(q > 5) {
      $("#next,#previous").remove();
      $("body").append("<input type='submit' value='Submit'>");
    } else {
      $("#question" + q).show();
    }
});
0
mbaluta On

Basically each JavaScript interaction in Opera Mini requires a round-trip - when a user clicks "Next", it's browser sends a click event to Opera Mini servers. The JavaScript is executed on those servers and rendered page is sent back to client. Definitely a waste of time!

Users will definitely appreciate if they can simply answer all questions at once and then send a complete form.