Cory O'Daniel – These are just words Software development, thoughts, and randomness

22Aug/0878

BabySteps – jQuery Step-by-Step Forms

Just finished up my first jQuery plugin 'BabySteps' (yes, its Bill Murray reference). BabySteps helps in breaking up long or complicated web forms into smaller steps without multiple page requests. In the past when doing a multi-step form I'd generally have two or three pages that a user would have to go through, or I'd chalk up a bunch of javascript to shuffle divs around.

BabySteps takes the thinking out of breaking up forms. Simply break your steps up into divs (or your container of choice) and hide them.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
<style type="text/css">
  .step{display: none;}
</style>
<script type="text/javascript" language="javascript">
  var step1 = $('#step1');
  var step2 = $('#step2');
  var step3 = $('#step3');
 
  step1.bindStep(step2);
  step2.bindStep(step3);
 
  $('#step1').show();
</script>
}
</style>
<form method="post" action="http://example.com/some/far/away/place">
  <div id="step1" class="step">
    <!-- STEP 1 stuff here -->
  </div>
  <div id="step2" class="step">
    <!-- STEP 2 stuff here. -->
  </div>
  <div id="step3" class="step">
    <!-- STEP 3 stuff here. -->
    <input type="submit" id="frm_submit_btn" />
  </div>
</form>

And thats it. When your page loads 'step 1' will show. At the bottom a 'next' button will be appended. Click the next button and 'step 2' appears with a 'next' and 'previous' button.

Ok maybe you are thinking, well that's great, but I'd really like to customize what my form transitions look like.

Ok, cool. I can deal with that. BabySteps has a number of configurable parameters (globally or individually configurable):

  • nextBtn - path to your next button
  • prevBtn - path to your previous button
  • bindPrev - Do you want a previous button on the next page?
  • transition - how you want to transition from one step to the next
  • layoutButton - how you want to lay your button out over/in your step
  • generateMarkup - the markup you want to use to create your button
  • nextValidator - callback that runs a validator on next buttons 'onclick' should return boolean
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//These are each globally or individually configurable... :)
$.fn.bindStep.default.nextBtn = '/images/path/to/my/next.gif';
$.fn.bindStep.default.prevBtn = '/images/path/to/my/prev.gif';
 
var step1 = $('#step1');
var step2 = $('#step2');
 
//Dont like the default hide/show?
step1.bindStep(step2,{
  transition: function(currStep,nextStep){
    currStep.slideUp();
    nextStep.slideDown();
  }
});
 
//Dont like the <img> wrapped in <div>?
$.fn.bindStep.defaults.generateMarkup = function(id1,id2,img){
  //id1 is the id the events are bound to (default DIV)
  //id2 is an extra id for the inner element (default img), if you dont have an inner, just ignore it
  return(
  [
    '<img ',
      'src="' + img + '" ',
      'id="' + id1 + '" ',
    '/>'
  ].join('');
  );
}

Woot, pretty much everything is a callback, so you can modify the way the buttons are laid out, how their markup is generated and even how they transition. Of course there are also defaults, so now, it's up to you whether or not you want to just do the bare minimum. Well, like Brian, for example, has 37 cool transitions.

Here is a SIMPLE example of using the nextValidator.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
$(function(){
  //get references to my 4 steps
  var s1 = $('#step1');
  var s2 = $('#step2');
  var s3 = $('#step3');
  var s4 = $('#step4');
 
  s1.bindStep(s2,{
    nextValidator: step1_validator
  });
 
  s2.bindStep(s3);
  s3.bindStep(s4);
});
 
/* The nextValidator doesn't care what goes on
 * inside the validation method/closure as long
 * as it returns true|false.  If it gets true, the
 * next button works, if it gets false, it doesn't
 * All error reporting/validation is up to you or
 * your validation plugin.
 *
 * Simple example of validation that a username,
 * password, and password confirmation are entered
 * before moving on to the rest of the sign up form.
 *
**/
function step1_validator(){
  if(!$('#username').val()) return false;
  if(!$('#password').val()) return false;
  if(!$('#password_confirm').val()) return false;
 
  return true;
}

You may be saying, 'where can I get this swell tool?' Well from jQuery's plugins page of course.

UPDATE:
Here's a demo!

Post to Twitter Post to Digg Post to Facebook Post to Reddit Post to StumbleUpon

Comments (78) Trackbacks (3)
  1. A demo would be very nice to have….

  2. Yes – we really want to see a demo!

  3. I love the plugin. The only thing missing is a validation plugin to decide whether or not a transition can be made between steps.

  4. JBLAND, Actually I just added that in version 0.2 last night, ha!

  5. How does the validation work? I’ve got the latest version 0.2.1 and I’m not sure how to validate a field, thus keeping the user on the existing panel before allowing them to move to the next. Is there a plugin that works with this that I can use? I need basic validation such as req fields, email field, etc..

    Any help you can offer would be fantastic. Btw – I love your plugin, it works just awesome!

  6. Wonderful tool…I’m looking to include in my current project, but I do am wondering about validation. If you could drop me an email regarding implementation/execution, that would be dandy. Thanks. And thanks for this great tool.

  7. The validation callback is pretty simple, it just wants to see true to enable the next button to show the next step container.

    So you can use whatever validator you want, I suggest this one. As long as it returns true, it’ll move on to the next step.

  8. Thanks Cory, but I’m still having trouble. I’ve already implemented that validator plugin, and it works great. However it doesn’t seem to stop your script. I can just happily click next next next.. no problem.

    I know it’s a lot to ask, but could you email me or possibly post an example? I’m oh-so close, but this is the dealbreaker if I can’t get it to validate before moving to the next section.

    (I know my validation is working, because I’ve got it implemented with another step-by-step form using the accordian plugin – but I’d rather use yours!)

    Thanks again…

  9. Cool plugin. I’m trying to use this on a local Drupal site. My later fieldsets are hidden correctly on the first step so I know the plugin has loaded but nothing happens when I hit the Next button. Any tips?

  10. Do you have an example of using the validation hookups? I’d love to see it out there somewhere.

    Thanks,

    Eric-

  11. I updated the post with an example of validation with nextValidator. Hope this helps!

  12. Very nice… Thank you Cory, thats a big help.

  13. Very nice.

    With the demo – clicking stepify more than once causes the plugin to stepify the stepified forms…

  14. Great work.

    Would be perfect if I could manage step switching based on keypress (ie: ENTER) and not only on mouse click. Will you add this?

    Even better would be the possibility to move to the prevoius/next step with left/right arrow.

    m.

  15. What is nextValidator and where can I get it from? you said you updated the example but your example only loads jquery and your own script…?

  16. I couldn’t figure this out, It would be awesome if you could please update your demo to what your post is showing. Thanks!

  17. Hi Cory,

    As a new JQUERY user, I am sure I am doing something wrong probably somewhere. I have tried your example and no matter what I put for the validator, it ALWAYS allows for the next button.

    Can you post an example with the validation plugin that you suggested previously?

    Thanks!

  18. Sam try hard refreshing my blog post, maybe your browser cached it? I added an example of using the validator to the end of the post.

  19. Cory:
    Please take a look at your demo again, there’s no use of the validator at all. This is what your demo page shows: http://www.pastie.org/288296

  20. Thanks Cory,

    I did see the validator at the end of the example. And this is what I did…

    I changed this:

    function step1_validator(){
    if(!$(‘#username’).val()) return false;
    if(!$(‘#password’).val()) return false;
    if(!$(‘#password_confirm’).val()) return false;

    return true;
    }

    To this,

    function step1_validator(){
    return false;
    }

    And if I understood it right, the validator should not work correct? Since it is returning false. And the next button should not be active correct?

    But it is and I could click next no matter what. Even if I use the exact same code you have here on the example.

    Thank you again for taking the time to explain it. I really appreciate it.

  21. I can’t get it to work either. It either stops everything completely – so you can’t get past step 1 or it zooms right through with no checking.

    I’m using the jquery validator from here: http://bassistance.de/jquery-plugins/jquery-plugin-validation/

  22. Hmm, Im not sure, I updated the example at: http://vokle.com/open-source/examples/babysteps/index.html

    On the third step you need to input something into the “Something Else” field or it wont let you to the fourth step.

    Make sure you have the most up-to-date version of BabySteps (v 0.2.1) . . . and as long as the closure returns true it’ll allow you to continue, false it will halt.

  23. Thanks Cory!

    I really appreciate all your help, I think I got it working properly now as shown in your example.

    Now on to using the Validation plugin :)

    Thanks again!

  24. I can’t seem to get this plugin working at all. Using jquery 1.2.6 and followed the examples to the letter but it does nothing. The first div never shows. No errors or messages that I can see in FireBug.

    I tried changing the buttons using one of your more advanced options too, but I get the message “$.fn.bindStep.default is undefined”. Something does not seem to be getting initialised somewhere, but I’ve been trawling it for hours and can’t find it.

    The js file is loading OK, and I’ve tried reloading from your site.

    Any ideas where I could look next?

    Thx,
    David

  25. Sorry, the error I get when I try to use the plugin is “nextStep.each is not a function”.

    Nothing appears to work. Using jquery 1.2.6, and supposedly 0.2.1 of your plugin, though the file identifies itself as 0.1 in the header…

  26. And, to draw my own story to a close, I corrected this by changing the plugin: The line that reads

    nextStep.each(function(){

    Becomes

    $(nextStep).each(function(){

    and everything works as expected…

  27. I’m still having trouble.. Trying to get this to work with the jquery validation plugin…

    Trying to do something like:

    function step1_validator(){
    if(!$(“#formname”).validate({
    rules : {
    date1 :{ required :true, minlength : 2
    }
    }
    })) return false;
    return true;
    }

    This does not work. Any help for us validation plugin users? Thanks Cory!

  28. Hey Todd,

    I’m doing this right now actually for one of our own forms. You set up the BabySteps validation callback (this is in the context of the rest of the BabySteps setup code):

    s1.bindStep(s2,{
      nextValidator: step1_validator
    });

    “nextValidator” is the option BabySteps takes if you want it to do step validation and “step1_validator” is the name of the function you want BabySteps to call when it’s checking if it should move from step to step (in this case step1 to step2). Note the function name is arbitrary, you could name it “my_validator” if you wanted. Whatever function you write, it needs to return true or false so BabySteps knows whether to advance or not.

    Make sure you’re correctly setting up the jquery validation plugin:

    $("#my_form").validate();

    and you have set your validation options on your form’s input fields.

    And if you’re using the jquery validation plugin you can do something like:

    function step1_validator(){
      if($("#name").valid() && $("#email").valid()){
         return true;
      }else{
       return false;
      }
    }

    Where “name” is the id of the field you want to validate using the jquery validation plugin. Just check that all the fields for that step are valid using .valid() and return true from your function if they are, false otherwise and BabySteps will either allow you to move to the next step or not.

    It’s awesome you guys have such an interest! Thanks for checking us out.

    Ian Serlin
    Project Manager – Vokle

  29. That worked great, thank you very much guys!

  30. Is it possible to “de-stepify”? This would be useful once the form is filled out in entirety as a full form preview.

  31. WhiteWaterBug – I was thinking of adding something like that but it becomes difficult to do with everything being customizable (ie the generateMarkup method which changes the HTML around the buttons). It should be easy to do it in any specific instance.

    Grab all of your step buttons either by their IDs or a class if you assigned on and delete them. Then use $() to grab the class name that made your steps hidden and call show() on them.

  32. Could you provide some example code to de-stepify? thanks!!

  33. Hello!
    I appreciate this code and it works great, i have two quick questions.
    Would it be possible to make the transition slide from one stage to the next?

    Also, I want to add a big button that says START THE FORM NOW and it transitions to step2 which would actually be the first time the form is seen. Would that be possible?

    Thanks!

  34. Kyle, Im actually adding that feature into the next release (we need it for one of our forms), but I’m swamped, so I won’t have time to work on it until after the 19th of December!

  35. okay so my main question is 0.2.x an official release yet, as in all the bugs are worked out… ?

    The jQuery site still shows official being 0.1 that is why I ask.

    This looks very cool,
    Thanks,
    Don

  36. Hello ,
    Nice script !!
    So i you’d like understand how i can make an autostart on the first div or question. without clik on the simplify button.

    Thank’s
    Laurent.

  37. okay… not so sure why this seems to happen a lot in these plugin pages documentation. Examples are posted that alone do not fully work…

    ie… example 1 on this page will not work unless you add the following lines..\

    #
    # $(function(){
    # $(‘#step1′).bindStep(‘#step2′);
    # $(‘#step2′).bindStep(‘#step3′);
    #
    # $(‘#step1′).show();
    # });
    #

    which makes it a non working example… on the other side, the demo is great.. but the “stepify” code functionality convolutes the example as it is not normally something that would be in a form.
    Other than that, very cool. Thanks for posting it.

  38. Hello, your babystep it’s great.
    But I’have some problem to use a jquery validate (http://bassistance.de/jquery-plugins/jquery-plugin-validation/)
    I do this :
    function step2_validator(){
    $(“#InfoClient”).validate({
    rules: {
    Nom : “required”
    },
    messages: {
    Nom : “Pouvez vous rentrez votre nom !!”
    }
    });
    }
    function stepify(){
    $(‘fieldset’).hide();
    $(“#step1″).show();

    var step1 = $(‘#step1′);
    var step2 = $(‘#step2′);

    $.fn.bindStep.defaults.prevBtn = “/Front/image/prev.png”;
    $.fn.bindStep.defaults.nextBtn = “/Front/image/next.png”;
    $.fn.bindStep.defaults.generateMarkup = function(id1,id2,img){
    return([
    '',
    ].join(”));
    }

    step1.bindStep(step2,{
    nextValidator: step2_validator
    });
    }

    this doesn’t work.
    Can you help me ??
    thanks

  39. I may be missing something but the demo appears not to work on a Mac, Firefox or Safari

  40. Doesn’t work for me either in any browser… Even using your stepify just makes it go straight to the full form.

  41. Sorry, but this plugin don’t work in IE! why?
    do you know this? can you help me?

  42. Well, I tried to use it too… but it doesn’t work! :( is anybody that can helps me please..?

  43. I’m on a mac using OS X 10.4.11 – does not work in latest versions of Safari or FF. Stepify goes to first pane, filled in the fields, hit return … reverts to full form.

  44. Too bad. The demo doesn’t work on IE7 or Firefox. I get errors on the page.

  45. Demo seems to be down.

  46. Roman, Jeff: Sorry we moved some stuff around and the babystep.js file wasn’t where the demo page thought it was, its all fixed now ;)

  47. Oh, there were more than just two people that visited while the file was in the wrong place, sorry all ;) Its up now!

    Ellen: Sure it works, “enter” submits a form. The demo page doesn’t submit to anywhere, so it just refreshes the page. In your own code, you’ll want to disable the ‘enter’ key if your forms validation fails.

  48. @laurent the ’stepify’ button is just demonstrating how the long form becomes short, you wouldn’t actually use it in production. All of your form steps should be hidden by default except for the first one.

  49. @David the bindStep function takes a jQuery object not a jQuery selector!


Leave a comment