osmar
osmar

Reputation: 16

How to create a link to a tab using jQuery Multi Step Form Wizard Plugin

I need to use a jQuery Multi Step Form Wizard to View/Update a record to validate information per tab as requirements. So I need to create a link to specific tabs using this form wizard. For example, a tab with "Personal Information", another tab for "Contact Information", etc. I need that when the user click on the tab name, the script validate the inputs and when the inputs are ok, the user can move without a specific order.

How I can do that?

I am using this Form Wizard plugin https://www.tutsmake.com/Demos/jquery-multi-step-form-with-validation/

multi-form.js

(function ( $ ) {
  $.fn.multiStepForm = function(args) {
      if(args === null || typeof args !== 'object' || $.isArray(args))
        throw  " : Called with Invalid argument";
      var form = this;
      var tabs = form.find('.tab');
      var steps = form.find('.step');
      steps.each(function(i, e){
        $(e).on('click', function(ev){
        });
      });
      form.navigateTo = function (i) {/*index*/
        /*Mark the current section with the class 'current'*/
        tabs.removeClass('current').eq(i).addClass('current');
        // Show only the navigation buttons that make sense for the current section:
        form.find('.previous').toggle(i > 0);
        atTheEnd = i >= tabs.length - 1;
        form.find('.next').toggle(!atTheEnd);
        // console.log('atTheEnd='+atTheEnd);
        form.find('.submit').toggle(atTheEnd);
        fixStepIndicator(curIndex());
        return form;
      }
      function curIndex() {
        /*Return the current index by looking at which section has the class 'current'*/
        return tabs.index(tabs.filter('.current'));
      }
      function fixStepIndicator(n) {
        steps.each(function(i, e){
          i == n ? $(e).addClass('active') : $(e).removeClass('active');
        });
      }
      /* Previous button is easy, just go back */
      form.find('.previous').click(function() {
        form.navigateTo(curIndex() - 1);
      });

      /* Next button goes forward iff current block validates */
      form.find('.next').click(function() {
        if('validations' in args && typeof args.validations === 'object' && !$.isArray(args.validations)){
          if(!('noValidate' in args) || (typeof args.noValidate === 'boolean' && !args.noValidate)){
            form.validate(args.validations);
            if(form.valid() == true){
              form.navigateTo(curIndex() + 1);
              return true;
            }
            return false;
          }
        }
        form.navigateTo(curIndex() + 1);
      });
      form.find('.submit').on('click', function(e){
        if(typeof args.beforeSubmit !== 'undefined' && typeof args.beforeSubmit !== 'function')
          args.beforeSubmit(form, this);
        /*check if args.submit is set false if not then form.submit is not gonna run, if not set then will run by default*/        
        if(typeof args.submit === 'undefined' || (typeof args.submit === 'boolean' && args.submit)){
          form.submit();
        }
        return form;
      });
      /*By default navigate to the tab 0, if it is being set using defaultStep property*/
      typeof args.defaultStep === 'number' ? form.navigateTo(args.defaultStep) : null;

      form.noValidate = function() {
        
      }
      return form;
  };
}( jQuery ));

The HTML form is:

<form id="myForm" action="#" method="POST">
	  <h1>Registration Form</h1>
	  <!-- One "tab" for each step in the form: -->
	  <div class="tab">Name:
	    <p><input placeholder="First name..." name="fname"></p>
	    <p><input placeholder="Last name..." name="lname"></p>
	  </div>
	  <div class="tab">Contact Info:
	    <p><input placeholder="E-mail..." name="email"></p>
	    <p><input placeholder="Phone..." name="phone"></p>
	  </div>
	  <div class="tab">Birthday:
	    <p><input placeholder="dd" name="date"></p>
	    <p><input placeholder="mm" name="month"></p>
	    <p><input placeholder="yyyy" name="year"></p>
	  </div>
	  <div class="tab">Login Info:
	    <p><input placeholder="Username..." name="username"></p>
	    <p><input placeholder="Password..." name="password" type="password"></p>
	  </div>
	  <div style="overflow:auto;">
	    <div style="float:right; margin-top: 5px;">
	      	<button type="button" class="previous">Previous</button>
	      	<button type="button" class="next">Next</button>
			<button type="button" class="submit">Submit</button>
	    </div>
	  </div>
	  <!-- Circles which indicates the steps of the form: -->
	  <div style="text-align:center;margin-top:40px;">
	    <span class="step">1</span>
	    <span class="step">2</span>
	    <span class="step">3</span>
	    <span class="step">4</span>
	  </div>
	</form>

I tried to use this HTML code for link to direct tab but this doesn't work for me.

   

 <button onchange="navigateTo(0);">Go to First Tab after Validate</button>
    <button onchange="navigateTo(1);">Go to Second Tab after Validate</button>
    <button onchange="navigateTo(2);">Go to Third Tab after Validate</button>
    <button onchange="Submit();">Save</button>

Thanks in advance.

Upvotes: 0

Views: 1201

Answers (1)

skobaljic
skobaljic

Reputation: 9614

You just need a form jQuery element to navigate, check the end of the script below:

$.fn.multiStepForm = function(args) {
  if (args === null || typeof args !== 'object' || $.isArray(args))
    throw " : Called with Invalid argument";
  var form = this;
  var tabs = form.find('.tab');
  var steps = form.find('.step');
  steps.each(function(i, e) {
    $(e).on('click', function(ev) {});
  });
  form.navigateTo = function(i) {
    /*index*/
    /*Mark the current section with the class 'current'*/
    tabs.removeClass('current').eq(i).addClass('current');
    // Show only the navigation buttons that make sense for the current section:
    form.find('.previous').toggle(i > 0);
    atTheEnd = i >= tabs.length - 1;
    form.find('.next').toggle(!atTheEnd);
    // console.log('atTheEnd='+atTheEnd);
    form.find('.submit').toggle(atTheEnd);
    fixStepIndicator(curIndex());
    return form;
  }

  function curIndex() {
    /*Return the current index by looking at which section has the class 'current'*/
    return tabs.index(tabs.filter('.current'));
  }

  function fixStepIndicator(n) {
    steps.each(function(i, e) {
      i == n ? $(e).addClass('active') : $(e).removeClass('active');
    });
  }
  /* Previous button is easy, just go back */
  form.find('.previous').click(function() {
    form.navigateTo(curIndex() - 1);
  });

  /* Next button goes forward iff current block validates */
  form.find('.next').click(function() {
    if ('validations' in args && typeof args.validations === 'object' && !$.isArray(args.validations)) {
      if (!('noValidate' in args) || (typeof args.noValidate === 'boolean' && !args.noValidate)) {
        form.validate(args.validations);
        if (form.valid() == true) {
          form.navigateTo(curIndex() + 1);
          return true;
        }
        return false;
      }
    }
    form.navigateTo(curIndex() + 1);
  });
  form.find('.submit').on('click', function(e) {
    if (typeof args.beforeSubmit !== 'undefined' && typeof args.beforeSubmit !== 'function')
      args.beforeSubmit(form, this);
    /*check if args.submit is set false if not then form.submit is not gonna run, if not set then will run by default*/
    if (typeof args.submit === 'undefined' || (typeof args.submit === 'boolean' && args.submit)) {
      form.submit();
    }
    return form;
  });
  /*By default navigate to the tab 0, if it is being set using defaultStep property*/
  typeof args.defaultStep === 'number' ? form.navigateTo(args.defaultStep) : null;

  form.noValidate = function() {

  }
  return form;
};
var myForm = $('#myForm');
myForm.multiStepForm({
  // defaultStep:0,
  callback: function() {
    console.log("save");
  }
});
myForm.navigateTo(0);
$('[data-nav]').each(function(i) {
	var thisButton = $(this);
	var ind = thisButton.data('nav')*1;
	thisButton.on('click', function(e) {
		myForm.navigateTo(ind);
	});
});
* {box-sizing: border-box;}
.tab{display: none; width: 100%; height: 50%;margin: 0px auto;}
.current{display: block;}

body {background-color: #f1f1f1;}

form {background-color: #ffffff; font-family: Raleway; padding: 40px; min-width: 300px; }

h1 {text-align: center; }

input {padding: 10px; width: 100%; font-size: 17px; font-family: Raleway; border: 1px solid #aaaaaa; }

button {background-color: #4CAF50; color: #ffffff; border: none; padding: 10px 20px; font-size: 17px; font-family: Raleway; cursor: pointer; }

button:hover {opacity: 0.8; }

.previous {background-color: #bbbbbb; }

/* Make circles that indicate the steps of the form: */
.step {height: 30px; width: 30px; cursor: pointer; margin: 0 2px; color: #fff; background-color: #bbbbbb; border: none; border-radius: 50%; display: inline-block; opacity: 0.8; padding: 5px}

.step.active {opacity: 1; background-color: #69c769;}

.step.finish {background-color: #4CAF50; }

.error {color: #f00; }
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<p>Go quick: 
	<button data-nav="0">First Tab</button>
    <button data-nav="1">Second</button>
    <button data-nav="2">Third</button>
    <button data-nav="3">4.</button>
</p>
<form id="myForm" action="#" method="POST">
  <h1>Registration Form</h1>
  <!-- One "tab" for each step in the form: -->
  <div class="tab">Name:
    <p><input placeholder="First name..." name="fname"></p>
    <p><input placeholder="Last name..." name="lname"></p>
  </div>
  <div class="tab">Contact Info:
    <p><input placeholder="E-mail..." name="email"></p>
    <p><input placeholder="Phone..." name="phone"></p>
  </div>
  <div class="tab">Birthday:
    <p><input placeholder="dd" name="date"></p>
    <p><input placeholder="mm" name="month"></p>
    <p><input placeholder="yyyy" name="year"></p>
  </div>
  <div class="tab">Login Info:
    <p><input placeholder="Username..." name="username"></p>
    <p><input placeholder="Password..." name="password" type="password"></p>
  </div>
  <div style="overflow:auto;">
    <div style="float:right; margin-top: 5px;">
      <button type="button" class="previous">Previous</button>
      <button type="button" class="next">Next</button>
      <button type="button" class="submit">Submit</button>
    </div>
  </div>
  <!-- Circles which indicates the steps of the form: -->
  <div style="text-align:center;margin-top:40px;">
    <span class="step">1</span>
    <span class="step">2</span>
    <span class="step">3</span>
    <span class="step">4</span>
  </div>
</form>

For docs, please visit jQuery multiStepForm plugin page and download it.

You can find this code on JSFiddle

Upvotes: 1

Related Questions