Turning a form into a multistep process with jQuery

Byron asks:

jQuery question that I can't get my head around. I have a form with about 20 questions. The client want to show one question "per page". So instead of 20 cfm files, I thought I'd try jQuery to hide/show the questions so I'd have only one cfm page. I put "Next" buttons to proceed to next question.


Excerpt of form:

<div id="q2">
<p>2.) Question 2 <input name="Age" type="text"></p>
<input type="button" name="Next" value="Next" id="Next2" />
</div>


<div id="q3">
<p>2.) Question 3 <input name="Birthplace" type="text"></p>
<input type="button" name="Next" value="Next" id="Next3" />
</div>

My jQuery is like so:

$('#Next2').click(function(){
$('#q2').hide();
$('#q3').show();
})
$('#Next3').click(function(){
$('#q3').hide();
$('#q4').show();
})

Works like I want it to. Now the question. Is there way to create a function for this so I don't have to do 20 functions. I tried some ways using .parentNode and .nextSibling with no avail.

Before I had a chance to answer, Bryon came back with a partial solution:

I was able to clean the code up a bit like so:

$('#Next2,#Next3').click(function(){
$(this).parent().hide();
$(this).parent().next().show();
})

So now I would need to list each ID selector (Next2-Next20) in the selector. Would there be a way to clean that up?

I decided to try to tackle this solution a different way. First, I decided that I did not want to have to add buttons to each question. I thought this would make the form a bit simpler and give us more control over the "pagination":

<form id="mainform" method="post"> <div class="question"> 1) Why do you rock, Raymond? <input type="text" name="whyrock"> </div> <div class="question"> 2) A radio question:<br/> <input type="radio" name="q2" value="a">Apples<br/> <input type="radio" name="q2" value="b">Bananas<br/> </div> <div class="question"> 3) Another dumb question: <input type="text" name="q3"> </div> <div class="question"> 4) A textarea question:<br/> <textarea name="foo"></textarea> </div> </form>

Note that I've made use of a class on each div called question. To help create a pagination effect, I then added this style:

<style> .question { display:none; } </style>

Now let's look at the jQuery I ended up with:

$(document).ready(function() { //add the Next button $('.question').append("<br/><input type='button' value='Next' class='questionBtn'>") //show q1 $('.question:first').show() $('.questionBtn').click(function(){ //new logic here - am i the last one? if($(this).parent().is(":last-child")) { $("#mainform").submit() } $(this).parent().hide(); $(this).parent().next().show(); }) })

I begin by finding all my question divs and appending a Next button to them. This saves me some work right there. Since I previously hid all my questions, I now show the first one. Finally, I've modified Bryon's code a bit to handle the buttons. His code actually worked perfectly fine - but I wanted to make sure that the last button would perform a form submit. (In fact, it occurs to me I could also make the last button label read 'Submit' instead of 'Next' if I wanted to as well.) I use the is() function to compare the node to the last one - and if they match - perform a submit. (Thank you, StackOverflow: How to check for DOM equality with jQuery?)

How well does it work? Check the demo yourself:

You can view source to see the complete HTML there. Anyone else done something like this? I'll note that I wrote this in like five minutes so I'm sure there are things that can be improved.

Raymond Camden's Picture

About Raymond Camden

Raymond is a developer advocate for Extend by Auth0. He focuses on serverless and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support.

Lafayette, LA https://www.raymondcamden.com

Comments