[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

Userlevel 5
Badge +4

Hello @Noah,

is it possible that you add a different version of the latest script, but without the inline error ?
Since the removal of the jquery dependance, Unbounce use the standard html5 error message and i would like to used it with the Multi-step 2.0.
I tried to remove the code myself but with no success.

thanks !

This is great! Is there a way to modify the script so I can display more than one form field at a time? I worry that for much longer forms (even with the progress bar) users might become frustrated if there is a seemingly never ending list of questions…especially since the form doesn’t store each response in the event it isn’t completed…

Userlevel 5
Badge +4

I tried both and at them moment the one with a field by field is converting much better than the one with 3x3. Like 30% higher 🙂

This works perfectly until I get to a drop-down field. Then the next button stops moving to the next question. Any ideas?

I’m trying to get this to work in a pop-up.

It looks fine but it won’t go past the first question. Will the form work inside a pop-up?

If someone drops out on the 2nd step before hitting submit does the above method still record the details that were on the first page/step? I want to capture data at each step. Thanks

Userlevel 5
Badge +4

Hello Nick,

No it does not record anything.
You would have to modify the script or use an other way to achieve this.

Can this be used to capture info at each step? Everytime someone clicks next the data is recorded so if someone drops out on the 2nd step before hitting submit it still records the details that were on the first page/step? Thanks

This scripted worked great…thank you! Is there a way to also conditionally display form fields based upon the users selections?

This script is amazing…thank you! I am having an issue, however. In the final step of my form the fields are being displayed horizontally vs. vertically. Columns are set to 1. Any thoughts on what could be causing this?

hey, could you help me? I want to create a form like this
https://www.webistry.com/#step-1
How do I make visible 2-3-4 items in each steps in this code?
thanks!

hey!
do you know how can I make a form link this?
https://www.webistry.com/#step-1
I mean to apear 2-3-4 items by step
thanks!

hey!
can you help me? I want to maje a form like this
https://www.webistry.com/#step-1
a 2-3-4 item form.
thanks!

Userlevel 7
Badge +4

Hi there! We can help, we built it 😀

There are two aspects that I would like to edit but can’t seem to figure out.

  1. How can I increase the space between the bottom of the form question to the top of the back/submit buttons?

  2. How can I center the text “Book a FREE Consultation” within the button?

button%20challenges

I am hoping someone can point me in the right direction. Thank you!

Rookie query - I can’t get the submit button to display at the end. What am I missing?

I tried the steps above with the latest codes from https://gist.github.com/noahub/b8c6d63abb50048d42ee721c900450df but somehow it doesn’t work for me. It wouldn’t allow me to click the “next button” in the first step. Would anyone know how to solve this, please? Thanks!

Badge

Great work! Is there any way to show more then one field at a time?

Userlevel 5
Badge +4

Yes you can by using a different script (multistep form 3.0):

Multi-Field, Multi-Step Form 🔥

Progress Bar

Fantastic script.
It’s possible to have an “autoclick” function?

For example:
In question 1 we ask abou age groups.
if person select 30 to 40 it would go automatically to question 2 without clicking the next button.

Any way to do this?

Thank you

Thank you so much for this!! As a new User to Unbounce and to Coding in general, this was not only easy and concise to follow, but i felt accomplished when it worked. This will increase our conversions 10 fold.

Hi @Noah, this works perfectly for me, however is it possible to make the steps show more than 1 field? how do we edit the code to show the number of fields we want? Like instead of just 1 field, we can decide if its going to be 2,3 or more fields? Appreciate all the help! thanks!

Userlevel 5
Badge +4

Hello @remo,

There is another Multi-step script where you can chose the number of fields your want per steps:

Hey would you be free to help me?

Reply