How to Add a Multi-Step Form to a Classic Builder Page

Follow

A multi-step form shows one field at a time, with Next and Previous buttons to move between them. Breaking a long form into steps can make it feel shorter and easier to complete.

Unbounce logo icon in blue circle

Unbounce landing page with a multi-step form showing a Name field and Next button on a blue background.

This is community code, not an official Unbounce feature. Unbounce Support can't troubleshoot custom code. Test it on a published page before relying on it, and work with a developer if you aren't comfortable editing HTML, JavaScript, and CSS.

Add the multi-step form to your page

  1. Create your form in the Classic Builder.
  2. Add two button elements, one for Next and one for Previous. Only one field shows at a time, so position these buttons and the submit button with that in mind.
  3. In the JavaScripts section, add the following script with placement set to Before Body End Tag:
<script type="text/javascript" src="https://cdn.jsdelivr.net/npm/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>
  1. In the script, replace the button IDs with the IDs of your Previous and Next buttons. Leave out the #.
  2. Add the following CSS to the Stylesheets section:
<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>
  1. Save and republish the page.

Test the change

Run an A/B test with a small share of traffic to compare the multi-step form against your original form.