croninja
croninja

Reputation: 13

Switch classes on click next or back

I'm trying to setup multiple-step form in which the first step is visible by default and rest of the steps are hidden with class "hide". I'd like to switch the class with Next and Back button so only one step is visible at a time. Could you please help with this (Already spent an hour on this)

<div class="steps">
        <div class="step1">step1</div>
        <div class="step2 hide">step2</div>
        <div class="step3 hide">step3</div>
        <div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>
$('.next').click(function(){
    $('div:not(.hide)').next().removeClass('hide');
    $('.hide').prev().removeClass('hide')

})

Upvotes: 0

Views: 79

Answers (4)

Sorix
Sorix

Reputation: 918

Try combining the 2 actions into one, like so:

$('.next').click(function(){
    $('.steps div:not(.hide)').addClass('hide').next().removeClass('hide');
})

That way, you add the .hide class on your current div and then remove it on the next one.

You can use something similar for the Back button, by replacing .next() with .previous()

Upvotes: 1

Mr. Polywhirl
Mr. Polywhirl

Reputation: 48630

I converted Taplar's answer to a jQuery plugin.

You are essentially navigating left or right by one, using the previous and next functions. These functions navigate through the sibling elements.

(function() {
  $.fn.moveRight = function(className) {
    var $curr = this.find('div:not(.' + className + ')');
    if ($curr.next().length) $curr.next().removeClass(className);
    else this.find('div:first-child').removeClass(className);
    $curr.addClass(className);
    return this;
  };
  $.fn.moveLeft = function(className) {
    var $curr = this.find('div:not(.' + className + ')');
    if ($curr.prev().length) $curr.prev().removeClass(className);
    else this.find('div:last-child').removeClass(className);
    $curr.addClass(className);
    return this;
  };
})(jQuery);

$('.next').on('click', (e) => $('.steps').moveRight('hide'));
$('.back').on('click', (e) => $('.steps').moveLeft('hide'));
.hide {
  display: none;
}
.nav {
  width: 260px;
  text-align: center;
}
.nav .nav-btn::selection { background: transparent; }
.nav .nav-btn::-moz-selection { background: transparent; }
.nav .nav-btn {
  display: inline-block;
  cursor: pointer;
}
.steps {
  width: 260px;
  height: 165px;
  border: thin solid black;
  text-align: center;
  line-height: 165px;
  font-size: 3em;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
  <div class="step1">step1</div>
  <div class="step2 hide">step2</div>
  <div class="step3 hide">step3</div>
  <div class="step4 hide">step4</div>
</div>
<div class="nav">
<div class="nav-btn back">&#91;&nbsp;&#60;&#60;&nbsp;Back&nbsp;&#93;</div>
<div class="nav-btn next">&#91;&nbsp;Next&nbsp;&#62;&#62;&nbsp;&#93;</div>
</div>

Upvotes: 0

Aness
Aness

Reputation: 670

You can add a current step variable to track the currently displayed step and two css for styling and showing your content.

jQuery(function($) {
  let currentstep = 1;
  let maxsteps = 4;

  function showstep(step) {
    let step_c = '.step' + step;
    for (i = 1; i <= maxsteps; i++) {
      var step_selector = '.step' + i;
      $(step_selector).removeClass('show');
      $(step_selector).addClass('hide');
    }
    $(step_c).removeClass('hide');
    $(step_c).addClass('show');
  };

  $('.next').click(function() {
    
    currentstep = currentstep + 1;
    currentstep = (currentstep % (maxsteps + 1));
    if (currentstep == 0) currentstep = 1;
    showstep(currentstep);
  });
  $('.back').click(function() {
    
    currentstep = currentstep - 1;
    currentstep = (currentstep % (maxsteps + 1));
    if (currentstep == 0) currentstep = 4;
    showstep(currentstep);
  });
});
.hide {
  display: none;
}

.show {
  display: block;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
  <div class="step1 show">step1</div>
  <div class="step2 hide">step2</div>
  <div class="step3 hide">step3</div>
  <div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>

Upvotes: 0

Taplar
Taplar

Reputation: 24965

$('.next').click(function() {
  // find the div that is not hidden
  var $current = $('.steps div:not(.hide)');
  
  // only perform logic if there is a proceeding div
  if ($current.next().length) {
    // show the next div
    $current.next().removeClass('hide');
    // hide the old current div
    $current.addClass('hide')
  }
});

$('.back').click(function() {
  // find the div that is not hidden
  var $current = $('.steps div:not(.hide)');
  
  // only perform logic if there is a preceeding div
  if ($current.prev().length) {
    // show the previous div
    $current.prev().removeClass('hide');
    // hide the old current div
    $current.addClass('hide')
  }
});
.hide { display: none; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="steps">
  <div class="step1">step1</div>
  <div class="step2 hide">step2</div>
  <div class="step3 hide">step3</div>
  <div class="step4 hide">step4</div>
</div>
<div class="back">Back</div>
<div class="next">Next</div>

Upvotes: 0

Related Questions