[How To] Add A Multi-Step Form 2.0


Userlevel 7
  • Former Unbouncer
  • 126 replies

When you’re building your landing pages in Unbounce, you want the conversion process to be as simple as possible. Nothing too distracting, and you certainly don’t want to scare your audience away with long, time-consuming forms.

We’ve built an easy solution for you because, hey, we’re marketers too! :unbounce:

Introducing Multi-Step Forms! 📈 🎉

No more scary, conversion killing forms!
Follow the steps below to implement this handy script into your landing page and try it for yourself! And, as always, remember to A/B test, and keep us posted on your results!

You can see this in action (built in Unbounce) here:


How to Install in Unbounce

Click Here for Instructions

🚨
This is not an official Unbounce feature. This functionality is based entirely on third party code, and has only been tested in limited applications. Since this isn’t a supported Unbounce feature, our support team will be unable to assist if things go awry. So if you are not comfortable with HTML, Javascript and CSS, please consider consulting an experienced developer.


Step 1.

Create your form in Unbounce.

Step 2.

Create a new button element for your ‘Next’ button and one for your ‘Previous’ button. Keep in mind when positioning these buttons (and your form submission button) that only one field will be shown at a time.

Step 3.

Copy this script and paste it into the Javascripts section of your page with placement ‘Before Body End Tag’:

<script type="text/javascript" src="https://rawgit.com/kimmobrunfeldt/progressbar.js/1.0.0/dist/progressbar.js"></script>

<script>
  (function() {
    // Update the following IDs with your own button IDs
    var backButton = document.getElementById('lp-pom-button-14');
    var nextButton = document.getElementById('lp-pom-button-13');
    var showProgressBar = false;

    var submitButton = document.querySelector('.lp-pom-form .lp-pom-button');
    var formContainer = document.querySelector('.lp-element .lp-pom-form');
    var currentField = 0;
    var allFields = document.getElementsByClassName('lp-pom-form-field');
    var errorSpan = document.createElement('span');

    for (i = 0; i < allFields.length; i++) {
      allFields[i].classList.add('hide');
      allFields[i].style.top = '0px';
    }

    backButton.classList.add('hide');
    submitButton.classList.add('hide');

    allFields[0].classList.remove('hide');

    if (allFields[0].querySelector('input')) {
      allFields[0].querySelector('input').focus();
    }

    errorSpan.classList.add('hide');
    errorSpan.style.color = 'red';
    errorSpan.style.position = 'absolute';
    var labelHeight;
    if (allFields[0].querySelector('label')) {
      labelHeight = allFields[0].querySelector('label').clientHeight;
    } else {
      labelHeight = 25;
    }
    errorSpan.style.top = '-' + labelHeight + 'px';
    formContainer.appendChild(errorSpan);

    if (showProgressBar) {
      var progressContainer = document.createElement('div');
      progressContainer.id = 'container';
      formContainer.appendChild(progressContainer);

      var bar = new ProgressBar.Line(container, {
        strokeWidth: 4,
        easing: 'easeInOut',
        duration: 1400,
        color: '#FFEA82',
        trailColor: '#eee',
        trailWidth: 1,
        svgStyle: { width: '100%', height: '100%' },
        from: { color: '#FFEA82' },
        to: { color: '#74D16A' },
        text: {
          style: {
            // Text color.
            // Default: same as stroke color (options.color)
            color: '#fff',
            position: 'absolute',
            right: '0',
            top: '30px',
            padding: 0,
            margin: 0,
            transform: null,
          },
          autoStyleContainer: false,
        },
        step: function(state, bar) {
          bar.setText(currentField + 1 + ' of ' + allFields.length);
          bar.path.setAttribute('stroke', state.color);
        },
      });
    }

    function nextEvent() {
      allFields[currentField].classList.add('hide');

      currentField += 1;
      allFields[currentField].classList.remove('hide');
      if (allFields[currentField].querySelector('input')) {
        allFields[currentField].querySelector('input').focus();
      }

      if (currentField > 0) {
        backButton.classList.remove('hide');
      }

      if (currentField === allFields.length - 1) {
        submitButton.classList.remove('hide');
        nextButton.classList.add('hide');
      }

      updateProgress();
    }

    function backEvent() {
      allFields[currentField].classList.add('hide');
      submitButton.classList.add('hide');

      currentField -= 1;
      allFields[currentField].classList.remove('hide');
      if (allFields[currentField].querySelector('input')) {
        allFields[currentField].querySelector('input').focus();
      }
      if (currentField === 0) {
        backButton.classList.add('hide');
        nextButton.classList.remove('hide');
      }
      if (currentField <= allFields.length - 1) {
        nextButton.classList.remove('hide');
      }

      updateProgress();
    }

    function currentFieldInvalid() {
      var invalidInput = allFields[currentField].querySelector(':invalid');

      if (invalidInput) {
        errorSpan.textContent = invalidInput.validationMessage;
      }

      return Boolean(invalidInput);
    }

    function updateProgress() {
      if (showProgressBar) {
        var barSize = (currentField + 1) / allFields.length;
        bar.animate(barSize); // Number from 0.0 to 1.0
      }
    }

    updateProgress();

    nextButton.addEventListener('click', function(e) {
      if (currentFieldInvalid()) {
        if (allFields[currentField].querySelector('input')) {
          allFields[currentField].querySelector('input').classList.add('hasError');
        } else {
          allFields[currentField].children[1].classList.add('hasError');
        }

        errorSpan.classList.remove('hide');
        e.preventDefault();
      } else {
        if (allFields[currentField].querySelector('input')) {
          allFields[currentField].querySelector('input').classList.remove('hasError');
        } else {
          allFields[currentField].children[1].classList.remove('hasError');
        }

        errorSpan.classList.add('hide');
        nextEvent();
      }
    });

    backButton.addEventListener('click', backEvent);

    submitButton.addEventListener('click', function(e) {
      if (currentFieldInvalid()) {
        if (allFields[currentField].querySelector('input')) {
          allFields[currentField].querySelector('input').classList.add('hasError');
        } else {
          allFields[currentField].children[1].classList.add('hasError');
        }

        errorSpan.classList.remove('hide');
        e.preventDefault();
      } else {
        if (allFields[currentField].querySelector('input')) {
          allFields[currentField].querySelector('input').classList.remove('hasError');
        } else {
          allFields[currentField].children[1].classList.remove('hasError');
        }

        errorSpan.classList.add('hide');
      }
    });

    document.body.addEventListener('keydown', function(e) {
      var keyCode = e.keyCode || e.which;

      // Enter key
      if (keyCode === 13 && currentField < allFields.length - 1) {
        if (currentFieldInvalid()) {
          if (allFields[currentField].querySelector('input')) {
            allFields[currentField].querySelector('input').classList.add('hasError');
          } else {
            allFields[currentField].children[1].classList.add('hasError');
          }

          errorSpan.classList.remove('hide');
          e.preventDefault();
        } else {
          if (allFields[currentField].querySelector('input')) {
            allFields[currentField].querySelector('input').classList.remove('hasError');
          } else {
            allFields[currentField].children[1].classList.remove('hasError');
          }

          errorSpan.classList.add('hide');
          e.preventDefault();
          nextEvent();
        }
      } else if (keyCode === 13 && currentField === allFields.length - 1) {
        if (currentFieldInvalid()) {
          if (allFields[currentField].querySelector('input')) {
            allFields[currentField].querySelector('input').classList.add('hasError');
          } else {
            allFields[currentField].children[1].classList.add('hasError');
          }

          errorSpan.classList.remove('hide');
          e.preventDefault();
        } else {
          if (allFields[currentField].querySelector('input')) {
            allFields[currentField].querySelector('input').classList.remove('hasError');
          } else {
            allFields[currentField].children[1].classList.remove('hasError');
          }

          errorSpan.classList.add('hide');
        }
      }

      if (keyCode === 37) {
        // Left key
        if (currentField > 0) {
          backEvent();
        }
      } else if (keyCode === 39) {
        // Right key
        if (currentField < allFields.length - 1) {
          if (currentFieldInvalid()) {
            if (allFields[currentField].querySelector('input')) {
              allFields[currentField].querySelector('input').classList.add('hasError');
            } else {
              allFields[currentField].children[1].classList.add('hasError');
            }

            errorSpan.classList.remove('hide');
            e.preventDefault();
          } else {
            if (allFields[currentField].querySelector('input')) {
              allFields[currentField].querySelector('input').classList.remove('hasError');
            } else {
              allFields[currentField].children[1].classList.remove('hasError');
            }

            errorSpan.classList.add('hide');
            nextEvent();
          }
        }
      }
    });
  })();

  /**
   * Do not remove this section; it allows our team to troubleshoot and track feature adoption.
   * TS:0002-03-062
   */
</script>

Step 4.

Update the script with the ID of your ‘Previous’ and ‘Next’ button elements. Tip: Make sure you exclude the ‘#’ in the ID.

Step 5.

Copy this script and paste it into the Stylesheets section of your page:

<style>
  #container {
    margin-top: -45px;
    width: 100%;
    height: 8px;
    position: relative;
  }
  .lp-form-errors {
    display: none !important;
  }
  .hasError {
    border: 1px solid tomato !important;
    box-shadow: 0px 0px 5px 1px tomato !important;
  }
  .hide {
    display: none !important;
  }
  .lp-pom-form-field,
  .lp-pom-button {
    -webkit-animation: KEYFRAME-NAME 2s;
    -moz-animation: KEYFRAME-NAME 2s;
    -o-animation: KEYFRAME-NAME 2s;
    animation: KEYFRAME-NAME 2s;
  }

  @-webkit-keyframes KEYFRAME-NAME {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @-moz-keyframes KEYFRAME-NAME {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @-o-keyframes KEYFRAME-NAME {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
  @keyframes KEYFRAME-NAME {
    0% {
      opacity: 0;
    }
    100% {
      opacity: 1;
    }
  }
</style>

You’re done!

Now sit back and let the conversions roll in… :gif_master:


Can’t see the instructions? Log in or Join the Community to get access immediately. 🚀


Want to take your Unbounce landing pages + Convertables™ to the next level?
:spinbounce: Check out the Ultimate List of Unbounce Tips, Scripts & Hacks


224 replies

@Eliot_Sell, can you point to where I would change the max height? I think it’s in the below section somewhere.

// Replicate Unbounce’s field spacing
var height = parseInt( this.fields.eq(0).css(‘height’), 10);
var top = parseInt( this.fields.eq(1).css(‘top’), 10);
this.fields.css(‘margin-bottom’, (top - height) + ‘px’);
this.progressBar.css(‘margin-bottom’, (top - height) + ‘px’);

@Marissa_Rustici

You can add it in the CSS. Just pick an appropriate height.

16%20AM

I’m having an issue where it will not let me select radio buttons when it’s live.

Userlevel 5
Badge +2

Haven’t heard of that one before @ian-idplans - Feel free to message me for more assistance.

Hello @Noah
I have downloaded your lastest version of the script and i am still getting stuck at the drop down menu.
http://audibel.it/campaign/batterie-gratis/
Can you please help? What am i doing wrong? Thanks!

Is it possible to mix and match checkboxes, text-fields and drop-down menus with this code? Because I’m trying to do just that, and I can’t get it to work.

Right now the script won’t allow the business email only script at the same time. I have to remove the business script and uncheck “validate as an email address”

It will give this error: https://pasteboard.co/HA4JEpL.png

Any work around for this?

hello,

someone could please share me a template, i have some pb to create a form with several steps
thx

Awesome! Is there by any chance a way to automatically jump to next question without clicking “next” button? sthing like this: https://audimagnet.com/comparador/?v=1&adsid=_19630420300699590 That’d be an extra-awe

Userlevel 2
Badge

Hi All Community Members,
I see that has been an issue for many people using unbounce here. Each and every requirement is different here so we can’t probably jump to a fixed conclusion for now.

I have found a way to alter the script and show as many fields you need in any number of steps.

So if you need any help with the form: you can reach out to me through my email: reckless.sam@gmail.com

with subject: Unbounce Community - Multi Step Form Help

I will get back to you within shortest time possible and update your scripts at a genuine price.

If ii find a solution that could be used for all then i will post it here for all the members surely.

Looking forward to help you out with the forms! 🙂

Thanks!

Hi,

Thanks for this how-to. I implemented it, but stumbled upon a mistake: when testing the ‘Back’ button, the form is submitted, which of course shouldn’t be the case. Anyone else experiencing this problem? Is there a solution for this?

Regards,

Matteo

Have you made sure the back button & the form button are away from each other or are not layered on top of each other?

I would try dragging your back button well away from the form submit button and trying that to see if the problem persists.

Hi,

In the guide I found, nothing was said about creating a back button. This appears to be automatically generated. Can I get you some script screenshots to make this easier?

Regards,

Ahhh. I see. No, you create the back and next buttons yourself. You can style them however you like.

When you create the two buttons you have to find their ID’s & make sure that is what’s in your script.

So here’s my back button :

back%20button
back button.PNG966x305 86.8 KB

Here’s my next button:

next%20button
next button.PNG848x274 47.6 KB

And you can see I’ve put those in the script here:

multi-step%20script
multi-step script.PNG977x127 7.61 KB

This is what it looks like when it’s up and running:
multi-step%20styling

I’ve just pointed out a couple of other things I’ve done.

I’ve but a box around the progress bar and I’ve changed the colour of the step counter to match the styling of my page. The box is as simple as creating it and arranging it behind the form in the right spot.

Changing the colour is in the script. It’s here:step%20counter%20text

In that picture you can see that you can also change the progress bar colour (the from: & the to: values).

Hi,

Thanks for this info!

I added a button and looked in the code for lines saying ‘Var backButton =…’ and 'var nextButton =…" so that I can add the ID like you showed, but they are not there. Is this something I can add myself without ‘breaking’ the script? Where should I add it exactly?

Regards,

Hi Matteo.
I’m afraid we are talking about two different scripts. My script is the original one of this thread & yours is the one posted by Caroline right?

I’m afraid I don’t use the multi-step form you are trying to set up so I can’t help you!

P.S. I do recommend using the multi-step form (the one this thread is supposed to be about!).
It’s brilliant & easy to set up.

Scroll all the way to the top and try it out.

I actuallly totally agree with @mike22rtn. Even though this script is already totally awesome, it would be great if you could 2-3 questions at a time instead of only 1, so that to the user it “feels” like only 2-3 pages of a survey, even if it’s the same amount of questions.

Also @Noah do you know if there’s a way to track individual fb pixel standard events for each question? This would be IMMENSELY valuable and is a gaping hole in the entire survey/quiz/funnel software industry. None of the dynamic survey tools allow for tracking conversions INSIDE the survey, they only track the start and end. But for example, to better optimize fb campaigns, I want to be able to put a ViewContent pixel on the first question, an AddToCart pixel on the second question, a Lead pixel on the 3rd question, etc. etc.

I’m also very interested in where to set the height/max @Eliot_Sell!

I’m having the same exact problem.

Userlevel 5
Badge +4

Be careful with this script, with the removal of Jquery in the form you need the following par in the JS of otherwise you’ll have two errors messages.

//add error span
errorSpan.classList.add('hide');
errorSpan.style.color = '#FFFFFF';
errorSpan.style.position = 'absolute';
var labelHeight;
if(allFields[0].querySelector('label')){
labelHeight = allFields[0].querySelector('label').clientHeight;
}else {
labelHeight = 35;
}
errorSpan.style.top = '-'+labelHeight+'px';  
formContainer.appendChild(errorSpan);

Maybe @Noah can confirm this as i’m not a JS expert ?

Hi,
First of all, I would like to send a massive high five for job well done with this script. Working like a charm.

One thing that I would love to change (any ideas how?) is that if you press left or right direction button it takes u back or forward respectively in the form. It proved to be counter productive as a lot of people use direction buttons to navigate through text.

Anyone knows how to fix that?

Thanks a lot in advance 🙂

Badge

Hello @Noah ,
i used this script to build a multistep form and works fine for me. I just want to ask, is it possible to validate a textarea with character limit. I user to write at least 100 character. Before use the multistep form script, i used a script to validate the textarea. But it is not working after use multistep form script.
Kind Regards

Hi there,

I’m trying to reduce an existing multi-form script that has 3 steps down to 2 steps. I’m not a developer, and I’ve found myself a bit stuck! I have a feeling it’s a matter of changing a minor element of the script.

Any help would be much appreciated!

Here’s the existing script:

<script>
  function UnbounceMultiStep(form, options) {

  // Validate arguments
  if ( !form.is('.lp-pom-form form') )
    return console.error('jQuery.unbounceMultiStep must be called on an Unbounce form.');

  if ( typeof options !== 'object' )
    return console.error('No options were passed to jQuery.unbounceMultiStep');

  this.options = options;

  // Store DOM elements
  this.form = form;
  this.formContainer = this.form.closest('.lp-pom-form');
  this.fields = this.form.find('div.lp-pom-form-field');
  this.fieldsByStep = [];
  this.currentStep = 0;
  this.forwardButton = this.formContainer.find('.lp-pom-button').eq(0);
  //this.validationError = $('.lp-form-errors');
  
  // Verbiage
  this.text = {};  
  this.text.next = this.options.nextButton;
  this.text.showSteps = this.options.showSteps;
  this.text.back = this.options.backButton;
  this.text.submit = this.forwardButton.children('span').html();

  // Call constructor method
  this.init();
}

UnbounceMultiStep.prototype.init = function() {
  var _this = this;

  this.formContainer.addClass('multistep initial');
  this.form.attr('id', 'fields');

  // Add progress bar
  this.formContainer.prepend('<div id="progress-bar"></div>');
  this.progressBar = lp.jQuery('#progress-bar');

  // Replicate Unbounce's field spacing
  var height = parseInt( this.fields.eq(0).css('height'), 10);
  var top = parseInt( this.fields.eq(1).css('top'), 10);
  this.fields.css('margin-bottom', (top - height) + 'px');
  this.progressBar.css('margin-bottom', (top - height) + 'px');

  // Set up fieldset elements for each step
  for ( var i = 0 ; i < this.options.steps.length ; i ++ ) {
    console.log('Adding new fieldset.');
    this.form.append('<fieldset></fieldset>');
  }
  this.steps = this.form.find('fieldset');
  this.steps.addClass('step');

  // Sort fields into new steps
  var currentField = 0;
  for ( currentStep = 0 ; currentStep < this.options.steps.length ; currentStep ++ ) {
    this.progressBar.append('<div class="step">' +
                            '<span class="num">'+ (currentStep + 1) +'</span>' +
                            '<span class="title">'+ this.options.steps[currentStep].title +'</span>' +
                            '</div>');
    this.fieldsByStep[currentStep] = [];
    for ( i = 0 ; i < this.options.steps[currentStep].fields ; i ++ ) {
      console.log('Field ' + currentField + ' -> step ' + currentStep );
      this.fields.eq( currentField ).appendTo( this.steps.eq( currentStep ) );
      this.fieldsByStep[ currentStep ].push( this.fields.eq( currentField ) );
      currentField ++;
    }
  }

  // Add any remaining fields to last step
  if ( currentField < this.fields.length ) {
    currentStep --;
    for ( i = currentField ; i < this.fields.length ; i ++ ) {
      console.log('Field ' + currentField + ' -> step ' + currentStep );
      this.fields.eq( currentField ).appendTo( this.steps.last() );
      this.fieldsByStep[ currentStep ].push( this.fields.eq( currentField) );
      currentField ++;
    }
  }
  console.log(this.fieldsByStep);

  this.progressBarItems = lp.jQuery('#progress-bar .step');

  // Add a back button
  this.backButton = this.forwardButton.clone().insertBefore(this.forwardButton);
  this.backButton.addClass('back-button');
  this.backButton.children('span').html(this.text.back);

  // Only validate fields that are in current step
  $.each(window.module.lp.form.data.validationRules, function() {
    if ( this.required === true ) { this.required = {
      depends: function () { return $(this).is('.active :input')}
    };
  }
  });

  // Add event listeners
  $(function() {
   _this.backButton.unbind('click touchstart').bind('click.unbounceMultiStep', function(e) {
      _this.backHandler();
    });
    
    //_this.backButton.removeAttr('href');	
    _this.backButton.attr('href','#request');

    _this.forwardButton.unbind('click touchstart').bind('click.unbounceMultiStep', function() {
      _this.forwardHandler();
    });
    
    //_this.forwardButton.removeAttr('href');
    _this.forwardButton.attr('href','#request');
  });

  // Show first step
  this.goToStep(0);
};

UnbounceMultiStep.prototype.goToStep = function ( newStep ) {
  // Make sure we aren't going to a steΩp that doesn't exist
  if ( newStep < 0 || newStep >= this.steps.length ) return false;

  this.steps.eq( this.currentStep ).removeClass('active').hide();
  this.steps.eq( newStep ).addClass('active').fadeIn();

  this.progressBarItems.eq( this.currentStep ).removeClass('active');
  this.progressBarItems.eq( newStep ).addClass('active');

  this.formContainer.toggleClass('initial', newStep === 0);

  // Update the label of the forward button
  var current = parseInt(newStep) + 2;
  var total = this.steps.length;
  var nextText = this.text.showSteps ? this.text.next + ' (Step ' + current + ' of ' + total + ")" : this.text.next;
  var submitText = this.text.submit;
  
  var forwardButtonLabel = ( newStep === this.steps.length - 1 ) ? submitText : nextText;
  console.log(forwardButtonLabel);
  this.forwardButton.children('span').html(forwardButtonLabel);

  this.currentStep = newStep;
};

UnbounceMultiStep.prototype.validate = function () {
  return this.form.valid();
};

UnbounceMultiStep.prototype.forwardHandler = function () {

  // Prevent going to next step or submitting if step isn't valid
  if ( !this.validate() )
  {$('.lp-form-errors').appendTo( '#' + window.module.lp.form.data.formContainerId );
    return false;}
  
  
  if ( this.currentStep === this.steps.length - 1 ) {
    this.form.submit();
    this.goToStep(0);
  }else{
    //$('#reg_nurse_disclaimer').hide();	
    this.goToStep( this.currentStep + 1 );
  }
};

UnbounceMultiStep.prototype.backHandler = function () {
  this.goToStep( this.currentStep -1 );

  // Refresh the validation status
  this.validate();
};

//jQuery plugin
lp.jQuery.fn.unbounceMultiStep = function(options) {
  window.ms = new UnbounceMultiStep(this, options);
  return this;
};
</script>

Did a bit more testing and I think I cracked the code (pun intended):

<script>
  function UnbounceMultiStep(form, options) {

  // Validate arguments
  if ( !form.is('.lp-pom-form form') )
return console.error('jQuery.unbounceMultiStep must be called on an Unbounce form.');

  if ( typeof options !== 'object' )
return console.error('No options were passed to jQuery.unbounceMultiStep');

  this.options = options;

  // Store DOM elements
  this.form = form;
  this.formContainer = this.form.closest('.lp-pom-form');
  this.fields = this.form.find('div.lp-pom-form-field');
  this.fieldsByStep = [];
  this.currentStep = 0;
  this.forwardButton = this.formContainer.find('.lp-pom-button').eq(0);
  //this.validationError = $('.lp-form-errors');
  
  // Verbiage
  this.text = {};  
  this.text.next = this.options.nextButton;
  this.text.showSteps = this.options.showSteps;
  this.text.back = this.options.backButton;
  this.text.submit = this.forwardButton.children('span').html();

  // Call constructor method
  this.init();
}

UnbounceMultiStep.prototype.init = function() {
  var _this = this;

  this.formContainer.addClass('multistep initial');
  this.form.attr('id', 'fields');

  // Add progress bar
  this.formContainer.prepend('<div id="progress-bar"></div>');
  this.progressBar = lp.jQuery('#progress-bar');

  // Replicate Unbounce's field spacing
  var height = parseInt( this.fields.eq(0).css('height'), 10);
  var top = parseInt( this.fields.eq(1).css('top'), 10);
  this.fields.css('margin-bottom', (top - height) + 'px');
  this.progressBar.css('margin-bottom', (top - height) + 'px');

  // Set up fieldset elements for each step
  for ( var i = 0 ; i < this.options.steps.length ; i ++ ) {
console.log('Adding new fieldset.');
this.form.append('<fieldset></fieldset>');
  }
  this.steps = this.form.find('fieldset');
  this.steps.addClass('step');

  // Sort fields into new steps
  var currentField = 0;
  for ( currentStep = 0 ; currentStep < this.options.steps.length ; currentStep ++ ) {
this.progressBar.append('<div class="step">' +
                        '<span class="num">'+ (currentStep + 1) +'</span>' +
                        '<span class="title">'+ this.options.steps[currentStep].title +'</span>' +
                        '</div>');
this.fieldsByStep[currentStep] = [];
for ( i = 0 ; i < this.options.steps[currentStep].fields ; i ++ ) {
  console.log('Field ' + currentField + ' -> step ' + currentStep );
  this.fields.eq( currentField ).appendTo( this.steps.eq( currentStep ) );
  this.fieldsByStep[ currentStep ].push( this.fields.eq( currentField ) );
  currentField ++;
}
  }

  // Add any remaining fields to last step
  if ( currentField < this.fields.length ) {
currentStep --;
for ( i = currentField ; i < this.fields.length ; i ++ ) {
  console.log('Field ' + currentField + ' -> step ' + currentStep );
  this.fields.eq( currentField ).appendTo( this.steps.last() );
  this.fieldsByStep[ currentStep ].push( this.fields.eq( currentField) );
  currentField ++;
}
  }
  console.log(this.fieldsByStep);

  this.progressBarItems = lp.jQuery('#progress-bar .step');

  // Add a back button
  this.backButton = this.forwardButton.clone().insertBefore(this.forwardButton);
  this.backButton.addClass('back-button');
  this.backButton.children('span').html(this.text.back);

  // Only validate fields that are in current step
  $.each(window.module.lp.form.data.validationRules, function() {
if ( this.required === true ) { this.required = {
  depends: function () { return $(this).is('.active :input')}
};
  }
  });

  // Add event listeners
  $(function() {
   _this.backButton.unbind('click touchstart').bind('click.unbounceMultiStep', function(e) {
  _this.backHandler();
});

//_this.backButton.removeAttr('href');	
_this.backButton.attr('href','#request');

_this.forwardButton.unbind('click touchstart').bind('click.unbounceMultiStep', function() {
  _this.forwardHandler();
});

//_this.forwardButton.removeAttr('href');
_this.forwardButton.attr('href','#request');
  });

  // Show first step
  this.goToStep(0);
};

UnbounceMultiStep.prototype.goToStep = function ( newStep ) {
  // Make sure we aren't going to a steΩp that doesn't exist
  if ( newStep < 0 || newStep >= this.steps.length ) return false;

  this.steps.eq( this.currentStep ).removeClass('active').hide();
  this.steps.eq( newStep ).addClass('active').fadeIn();

  this.progressBarItems.eq( this.currentStep ).removeClass('active');
  this.progressBarItems.eq( newStep ).addClass('active');

  this.formContainer.toggleClass('initial', newStep === 0);

  // Update the label of the forward button
  var current = parseInt(newStep) + 0;
  var total = this.steps.length;
  var nextText = this.text.showSteps ? this.text.next + ' (Step ' + current + ' of ' + total + ")" : this.text.next;
  var submitText = this.text.submit;
  
  var forwardButtonLabel = ( newStep === this.steps.length - 2 ) ? submitText : nextText;
  console.log(forwardButtonLabel);
  this.forwardButton.children('span').html(forwardButtonLabel);

  this.currentStep = newStep;
};

UnbounceMultiStep.prototype.validate = function () {
  return this.form.valid();
};

UnbounceMultiStep.prototype.forwardHandler = function () {

  // Prevent going to next step or submitting if step isn't valid
  if ( !this.validate() )
  {$('.lp-form-errors').appendTo( '#' + window.module.lp.form.data.formContainerId );
return false;}
  
  
  if ( this.currentStep === this.steps.length - 2 ) {
this.form.submit();
this.goToStep(0);
  }else{
//$('#reg_nurse_disclaimer').hide();	
this.goToStep( this.currentStep + 1 );
  }
};

UnbounceMultiStep.prototype.backHandler = function () {
  this.goToStep( this.currentStep -1 );

  // Refresh the validation status
  this.validate();
};

//jQuery plugin
lp.jQuery.fn.unbounceMultiStep = function(options) {
  window.ms = new UnbounceMultiStep(this, options);
  return this;
};
</script>

image

Hey I keep getting the error above with all fields overlapping. Any chance of a quick fix?

Reply