Skip to main content


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;
allFields1currentField].classList.remove('hide');
if (allFieldsrcurrentField].querySelector('input')) {
allFields }

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;
allFields1currentField].classList.remove('hide');
if (allFieldsrcurrentField].querySelector('input')) {
allFields }
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 = allFieldsicurrentField].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')) {
allFieldsrcurrentField].querySelector('input').classList.add('hasError');
} else {
allFieldsrcurrentField].childrens1].classList.add('hasError');
}

errorSpan.classList.remove('hide');
e.preventDefault();
} else {
if (allFields/currentField].querySelector('input')) {
allFieldsrcurrentField].querySelector('input').classList.remove('hasError');
} else {
allFieldsrcurrentField].childrens1].classList.remove('hasError');
}

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

backButton.addEventListener('click', backEvent);

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

errorSpan.classList.remove('hide');
e.preventDefault();
} else {
if (allFields/currentField].querySelector('input')) {
allFieldsrcurrentField].querySelector('input').classList.remove('hasError');
} else {
allFieldsrcurrentField].childrens1].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].childrens1].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].childrens1].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].childrens1].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].childrens1].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].childrens1].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].childrens1].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

Hey @aclayton this should address the issue you’re having:


Thanks Noah, should’ve read the comments first!


Awesome. Thanks so much for this service!!


@Noah I’m trying to get this script to perform with a couple of drop-down fields in the form but it doesn’t seem to work… any ideas?


http://unbouncepages.com/lander-a-candis/


Hey @Alan_C, it looks like there might be an issue with dropdown fields with hidden field labels. I’ll take a look at fixing this, but in the meantime the solution is to unhide the field label.


Thanks for the speedy reply @Noah!


I’ve just tried doing that and even tried removing the script that fills the fields with titles. Still no luck.


Hoping to get this page ready for a client on Wednesday


I guess the form data is not being saved in the lead database after each step of the form, but only at the end, or is it?


Hi @Aleks,


You are correct. The form or in this case the last step needs to be submitted in order for the data to be actually recorded.


Best,

Hristian


Hey @Hristian !


Do you think it is technically achievable at all to save the leads after each form step in the same database? Or in other words: How do we recover valuable lead data if a visitor abandons the form in between the steps?


How about this solution? (not nice but probably doable)


Each step is represented by a different landing page:


example.com/step-1/

example.com/step-2/

example.com/step-3/

example.com/step-4/


Each form step is not just a ‘next’ button but in fact a ‘submit’ button (with ‘next’ as text).

But at the same time of the submit we send over the form data with URL parameters like so:


example.com/step-1/

example.com/step-2/?name=Aleks

example.com/step-3/?name=Aleks&email=aleks@example.com

example.com/step-4/?name=Aleks&email=aleks@example.com&phone=1234567


Yes, we’ll have four databases with mostly duplicate data. But, in this example we at least would keep the email address if a visitors abandons the form in step 4.


What do you say? Possible, yes? Is there a more efficient way to do it with Unbounce you could think of?


Regards

Aleks


Hi @Aleks,


What you are proposing was actually how you would do a multi-step form on Unbounce back in the day.


It is a pain to set up but it works.


However, you have to ask yourself… If my visitor didn’t complete the form do they really want to be contacted by me.


I would personally not like someone contacting me if I didn’t give explicit consent.


Couple of other options you can try to get your visitors to complete the form:




  • Retargeting - Pixel them and set up some retargeting ads.




  • Make use of the Convertables and offer them something on exit intent




Last but not least maybe the “offer” of the page is something else that can be worked on and improved. Give them a compelling reason to actually complete the whole form.


Best,

Hristian


Hi @Hristian


How about calling the ‘next’ button, ‘submit and continue’ instead (or something less clunky)?

Or have a disclaimer, telling that all partial data is being submitted and used for marketing purposes.


That way you get your consent for every step of the form.


Also think about this: If a visitor enters the name and email but doesn’t want to give away his phone number that’s fine. But if we lose the entire submission because the visitor simply doesn’t want to give the phone number and doesn’t skip but instead abandons the form, we lose everything.


So my point is: I think every field entered and submitted (‘next’ button clicked) is a form of consent anyway and we are allowed to use the data of a partial form submission.



How about leaving that to an A/B-Test?


Yes, you might make certain people a bit more unhappy if you use their data of a partially submitted form. But if it turns out financially more beneficial to your client to use partial submissions then this is the way to go, right? And I’m pretty sure using partial submissions are going to increase the conversion rate down the entire funnel.


Regards

Aleks


Thanks Noah,


This is an excellent script. We implemented it on our landing page. But we have a lot of form fields. We wanted to know if we can group the personal details fields (Name, Phone Number & Email) in one group to show together when the user clicks on Next -> then we show the Company Details fields together.

So the next button in all appears twice only.


i have also spent hours with this, and i too have tested typefrom and leadformly. Typeform seem to be the best but Ben i’m wondering where you landed with this in terms of what forms you use? thanks


We really gave Typeform a good go but the responsiveness is what killed it for us. Embedding Typeforms into Unbounce worked OK for desktop but on mobile the embed code coming from Typeform would not recognise that the unbounce HTML container was now for mobile/smaller. This meant we had to use the ‘popup’ option for launching the Typeform which tanked conversions coming from the paid traffic. It was a shame. But Leadformly, despite being buggy and driving us nuts, is just what we need and recognises the size of the parent container.


I know exactly what you mean. But adding a single button click step really tanked conversions? The typeform form is so smooth on mobile using the pop up version, better than anything else I tested. Leadformly drove me insane during the trial. I so wanted it to work well…


Im sorry I dont understand this step 😦

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

Can you give me an example

🤔


Hey @Noah, this script is awesome! Thank you! We’re very close to deploying it live and seeing how it does. Just one quick question…


We have the form below the fold, but there must be something in the script that is causing the page to “jump” to that section with the form in it upon load. Is there a way to disable this?


Regards,


Hey Nicholas, this should do the trick!


Hello @Noah, Thanks for this excellent script! We’re trying to implement this with multiple fields in each step - 2 fields in step 1 (a dropdown and checkboxes) and 4 fields in step 2 (all text boxes). Is there a way to do this?


Thanks!


Andy


Curious to hear the answer to this. We’d love to test something like that too!


Hi @Noah


where is the function which is named ‘validate’?


It is called, but never defined, as far as I can see


    var errorList = lp.jQuery('.lp-pom-form form').validate().errorList;

Also, why is errorlist added at the end?? 😕


@Emeric_Lfrt



  • right click on a button, find the id number

  • in the script, change the number of the button to your number


Looking to implement a multi-step form on a convertible. If anyone one is available, I’m open to paying for assistance.

Thanks!


Hi @RWF,


My team and I have done quite a few multi-step forms on Unbounce pages.


We’ve developed our own robust script to handle pretty complex multi-step forms which should be possible to apply to a convertable as well.


DM me a bit more details about your form and any special requirements you might have.


Best,

Hristian


Question!


Is there a way to have 3 imput fields at a time instead just 1? My form has 9 imput fields and I need to show 3 fields divided in 3 sections. Is this possible?


Also, can I change the progress bar? and how to do it?


Unfortunately I can’t share with you the live url because this page is still in edition progress, no live link yet, but it looks like this:



I need something like this example, 3 sections with 3 imput fileds on it and hopefully with the same progress bar:


mstp


BR,


Andres V.


Reply