Turn any webform into a powerful wizard with jQuery (FormToWizard plugin)

This detailed tutorial will show you how to turn long webform into a wizard with "steps left" information. A plugin is also available for download.

Download plugin with example  View demo

What is our task?

If you would, for whatever reason, have a large webform all fields shoud be semantically divided into fieldsets. Each fieldset would clearly describe each group of fields. Although many examples on the web today look different, this is how it should be.

 

So, we can say that each group of fields represent a sub task of a larger task - filling the entire web form. Thus, each sub task can become a step with a description, input fields and navigation that is common for wizard forms - back and next.The entire process can be done in several simple steps.

1. Create "steps"

The code should look like the example below.

<form id="SignupForm" action="">
    <fieldset>
        <-- input fields -->
    </fieldset>
    <fieldset>
        <-- input fields -->
    </fieldset>
    <fieldset>
        <-- input fields -->
    </fieldset>
</form> 

Let's explain the following code. In order to determine how much steps there will be, we need to select all fieldsets and get the size of this wrapped set. Next, we iterate through this wrapped set (that returned all fieldsets), wrap each fieldset into a div and append a paragraph that will hold "back" and "next" buttons.

Now comes the funny part. If this is a first fieldset in wrapped set, we'll create "next" button only and make this step visible. If it is the last fieldset in wrapped set, we'll create only "back" button. In all other cases we'll create both buttons. Methods for creating buttons will be explained later in this tutorial.

var steps = $("#SignupForm fieldset");
var count = steps.size();
steps.each(function(i) {     $(this).wrap("<div id='step" + i + "'></div>");     $(this).append("<p id='step" + i + "commands'></p>");
    if (i == 0) {         createNextButton(i);        // to do         selectStep(i);                  // to do     }     else if (i == count - 1) {         $("#step" + i).hide();         createPrevButton(i);       // to do     }     else {         $("#step" + i).hide();         createPrevButton(i);       // to do         createNextButton(i);       // to do } }

Now let's explain how to create buttons and how users will actually move through the wizard.

2. Create next and back buttons and add interatcion

Creating the buttons isn't that hard. Each button will have a unique name (e.g. step1next, or step3prev) and will be appended to their panels created in previous step. In order to add some interaction, and that is to enable moving between steps, we need to bind click event to each button. This is how they will work:

  • When user presses back button it will hide the current step, show the previous one and call selectStep() method which will mark it as current.
  • When user presses next button it will hide the current step, show the next one and call selectStep() method which will mark it as current.
function createPrevButton(i) {
    var stepName = "step" + i;
    $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Prev' class='prev'>< Back</a>");
    $("#" + stepName + "Prev").bind("click", function(e) {         $("#" + stepName).hide();         $("#step" + (i - 1)).show();         selectStep(i - 1);     }); }
function createNextButton(i) {     var stepName = "step" + i;     $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next'>Next ></a>");     $("#" + stepName + "Next").bind("click", function(e) {         $("#" + stepName).hide();         $("#step" + (i + 1)).show();         selectStep(i + 1);     }); }

Function selectStep() that I mentioned before removes CSS class "current" from all steps and assign it only to the currently selected.

function selectStep(i) {
    $("#steps li").removeClass("current");
    $("#stepDesc" + i).addClass("current");
}

At this moment wizard is functional. But that's not all. Let's apply Steps left UI design pattern here.

3. Create "steps left" information

This is easier than it might look like at the first sight. At the very beginning of our code we have to add unordered list that will be a container for steps left information. In addition to this we will hide signup button. We want it to be visible only in the last step.

var steps = $("#SignupForm fieldset");
var count = steps.size();
           
$("#SaveAccount").hide();
$("#SignupForm").before("<ul id='steps'></ul>");

We also need to extend each() function and add information about steps for each fieldset in wrapped set. Each step will have it's natural number, starting with 1. Below the step number we'll add a description that is extracted from <legend> element.

steps.each(function(i) {
    var name = $(this).find("legend").html();
    $("#steps").append("<li id='stepDesc" + i + "'>Step " + (i + 1) + "<span>" + name + "</span></li>");
    ...
});

Let's do just one more thing. Since submit button should be visible only in the last step, we'll hide it every time user presses next. Only if user comes to the last step, it should be visible.

$("#" + stepName + "Prev").bind("click", function(e) {
    $("#SaveAccount").hide();
});
$("#" + stepName + "Next").bind("click", function(e) {
    if (i + 2 == count)
        $("#SaveAccount").show();
});

If you want to see the full source code, download it or check out the demo.

Plugin for easier use

It would be a pity not to create a plugin that will enable all of this in just one line of code. I called it FormToWizard. I guess it's clear what it does :) In order to apply the plugin you will have to add a reference to script file and apply it to y <form> element.

<script type="text/javascript" src="formToWizard.js"></script>
$("#SignupForm").formToWizard();

If you want to hide a submit button (or placeholder for multiple buttons) you can add a parameter sumbitButton with the name of element you wish to be hidden.

$("#SignupForm").formToWizard({ submitButton: 'SaveAccount' }) 

Lightweight and Cross Browser compatible

This plugin has only 2,3KB and with compression it can be even smaller. It is compatible with all major browsers: FireFox, Google Chrome, Safari, Opera, Internet Explorer 8, 7 and 6. The latter is collateral, I was surprised it actually works there :)

If you, however, find any bug or have some suggestion on how to improve this or extend it, please share!

This work is published under Creative Commons Attribution 3.0 Unported License.

More articles in Blog archive or elsewhere
Advertisement

102 Comment(s)

Marco

Marco 29 Sep 2009 #

Just like your "Generate a table of contents" example, this one is very, VERY cool (and useful)! Can't understand why nobody else came up with this before.

Also, thanks for converting this into a plugin - it makes it even more usable.

Keep up the great work Janko!

webmasterdubai

webmasterdubai 29 Sep 2009 #

really nice work  it will make life easy to end user to fill lengthy forms in steps is there possibility to add validation with steps.

sky_mender

sky_mender 29 Sep 2009 #

Really nice work, very essential and useful! Thanks for sharing it.
The demo does not work in IE 7.

Denis Ivanov

Denis Ivanov 29 Sep 2009 #

Interesting indeed! My love for gracefully degrading frontend sugar just keeps increasing...

Kornelije Sajler

Kornelije Sajler 29 Sep 2009 #

Great tutorial and great idea also, I will try to it implement in my ASP.NET MVC2 Project.
Great job, Janko!

grimen

grimen 29 Sep 2009 #

Very useful and cool - thanks!

Masoud

Masoud 29 Sep 2009 #

nice job.

real use full.

i think its better see this in a plugin.

;)

Peter

Peter 29 Sep 2009 #

You just saved me loads of time! Thanks for all your hard work too.

Soh Tanaka

Soh Tanaka 29 Sep 2009 #

Awesome job Janko Smile This will def come in handy~

Yigit Ozdamar

Yigit Ozdamar 29 Sep 2009 #

Great work! Thanx mate!

Janko

Janko 29 Sep 2009 #

Thanks everyone! Yes, I forgot to mention that it degrades gracefully if JavaScript is disabled Smile

Nanda

Nanda 30 Sep 2009 #

Thanks Janko, I can put it use right away. Smile

Steffen J&#248;rgensen

Steffen Jørgensen 30 Sep 2009 #

Hi Janko!
A very nice post, with a very useful method of making large forms easier to consume.

Keep up the great work!

Fredrik

Fredrik 30 Sep 2009 #

Thanks for a very good articel!

Love your blog.

Yasser El-Sherif

Yasser El-Sherif 30 Sep 2009 #

Awsome ..

Max

Max 30 Sep 2009 #

Very nice tutorial, like a lot of your tutorials!!!
Thanks

Tigrish

Tigrish 30 Sep 2009 #

Hey Janko, some great stuff here!

Do you have any suggestion on how to add validation to the form? I suppose each fieldset would need to be validated every time the "next" button is clicked so that users can't move on to the following step if they have entered incorrect data.

mDesign

mDesign 30 Sep 2009 #

This is simply awesome, well done! And thanks for sharing.

@ Tigrish, someone else wrote a great script for that. bassistance.de/.../ Implenting this script shouldn't be that hard. Good luck Smile

Andrea

Andrea 30 Sep 2009 #

Is it possible to have the "step X" text to be clickable to go directly to that section?

Sarah

Sarah 30 Sep 2009 #

Hi mDesign, thanks for the heads up on bassistance validation implementation. i have tried integrating with this great execution for forms created by janko but there seems to be a conflict. the next buttons fail to trigger a validation per 'form' basis. has anyone managed to successfully integrate this? i will carry on trying and post back if i get it working Smile

mDesign

mDesign 30 Sep 2009 #

If I got some spare time tomorrow at work I'll take a quick look at it Smile

Janko

Janko 30 Sep 2009 #

Thanks everyone!

mDesign: yep, bassistance can do the work.

Tigrish, Sarah: If you have problems with bassistance, why don't use inline validation? http://livevalidation.com/ and http://code.google.com/p/javascriptformvalidation/

Andrea: You can do it simply by wrapping each step info into the same link as buttons.

Erwin Heiser

Erwin Heiser 01 Oct 2009 #

Nice one this! Would also like to add jquery-tinyvalidate by Karl Swedberg from learningjquery.com as a possible form validation script. It's on github http://github.com/kswedberg/jquery-tinyvalidate

William

William 01 Oct 2009 #

Wow..impressive!! great trick, simple and powerful..

thanks for sharing

Jahufar

Jahufar 01 Oct 2009 #

Nice job!

However, this breaks the browser's back button - any way to avoid that - .i.e. clicking the browser's back button takes you the the previous step and vice versa?

FoO Iskandar

FoO Iskandar 01 Oct 2009 #

Nice job!

Thank's for sharing

Yoosuf

Yoosuf 01 Oct 2009 #

Awesome work,


its seems like not working in Apple Safari Browser

Janko

Janko 01 Oct 2009 #

Thanks, everyone!

Erwin: I guess Karl's plugin would also be great solution, thanks!

Jahufar: Excellent point, I didn't think of that at all. I guess the good solution would be to add step number in anchors, so you'd have:

www.mysite.com/signup/#1 for Step 1 and so on. Thanks for this suggestion!

Yoosuf: Can you give me some details, what bug do you get? I just tested it again and works for me.

noel

noel 01 Oct 2009 #

chhers, great work, great tutorial

Roberto Xite Studio Magazine

Roberto Xite Studio Magazine 01 Oct 2009 #

Very cool! Thanks!

Jason

Jason 01 Oct 2009 #

Very nice, I'm going to check this out and try it later tonight!

James

James 01 Oct 2009 #

First off, thanks for the (hopefully) awesome script - I too am running into an error with Safari 4 (WinXP), latest version, and JQuery 1.3.2 (I have tried 1.2.6 as well):

In Safari 4, nothing happens - the fieldset tags don't get processed into a Wizard, and using the JS debugger in Safari (if the Develop menu is enabled) tells me:

syntax error, unrecognized expression: #

And stepping through the functions, it hits on where the script initiates the formToWizard function where the hash sign (#) is used to reference the ID of the form.

Any help/advice is appreciated. I'd really like to get this working as it's a great way to save screen real estate on large multipart forms.

James

James 01 Oct 2009 #

Oh, and I should add that your demo DOES work, so i'm guessing it's my code (obviously, lol) - do I have to have the elements the script creates styled out in an inline CSS style tag for it to work? I don't have that currently (just figured getting it working first, then style it afterwards).

James

James 01 Oct 2009 #

IE6/WinXP (I know, I know...) JS debugger says that the "Object doesn't support this property or method". Hope the info I supply helps.

Jack

Jack 02 Oct 2009 #

Your CSS forces the labels on radio buttons and check boxes to show above or below the actual checkboxes.  Any suggestions/solutions for getting the text to preced or follow the checkboxes instead?

Janko

Janko 02 Oct 2009 #

Jahufar, James: I will try that idea with URLs as soon as I find some free time. Adding step numbers can help you show the right step if users want to come to a specific step by tying URL, but not sure it will work for back button. Have to check it.

Jack: You have a plenty of choices. For instance, wrap label and input field in, let's say, paragraph and float them to left.

James

James 02 Oct 2009 #

@Jack:

I can help there with that - after the content of the label tag (the readable part that shows as the label's text), put a br tag followed by the radio input, and make sure your labels are set to display inline rather than block. this will force the label's text to line up before the input on the same line.

Bobby

Bobby 02 Oct 2009 #

There is one jquery plugin that does this quite well already, it's called form wizard plugin. See http://plugins.jquery.com/project/formwizard or http://home.aland.net/sundman/ . Just a heads up.

Janko

Janko 02 Oct 2009 #

Bobby: Looks very similar, but I'll check that one thoroughly. Thanks!

Martin

Martin 03 Oct 2009 #

Love it. Simple and straightforward.

This encourages me to start writing my own JQ plugins.

Janko

Janko 03 Oct 2009 #

Martin: Then do it! The best thing about this is that it is really fun to experiment and write about it .

Nikola

Nikola 05 Oct 2009 #

Odlichno!

Micael Estr&#225;zulas

Micael Estrázulas 05 Oct 2009 #

Hi,

Im changed your plugin to more accessible for other languages.

I added 3 new options: title, prevLabel, nextLabel.


[code]
/* Created by jankoatwarpspeed.com */

(functionMoney {
    $.fn.formToWizard = function(options) {
        options = $.extend({  
            submitButton: '',
      title: "Step",
      nextLabel: "Next",
      prevLabel: "Back"
        }, options);
        
        var element = this;

        var steps = $(element).find("fieldset");
        var count = steps.size();
        var submmitButtonName = "#" + options.submitButton;
        $(submmitButtonName).hide();

        // 2
        $(element).before("<ul id='steps'></ul>");

        steps.each(function(i) {
            $(this).wrap("<div id='step" + i + "'></div>");
            $(this).append("<p id='step" + i + "commands'></p>");

            // 2
            var name = $(this).find("legend").html();
            $("#steps").append("<li id='stepDesc" + i + "'>"+options.title+" " + (i + 1) + "<span>" + name + "</span></li>");

            if (i == 0) {
                createNextButton(i);
                selectStep(i);
            }
            else if (i == count - 1) {
                $("#step" + i).hide();
                createPrevButton(i);
            }
            else {
                $("#step" + i).hide();
                createPrevButton(i);
                createNextButton(i);
            }
        });

        function createPrevButton(i) {
            var stepName = "step" + i;
            $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Prev' class='prev'>< "+options.prevLabel+"</a>");

            $("#" + stepName + "Prev").bind("click", function(e) {
                $("#" + stepName).hide();
                $("#step" + (i - 1)).show();
                $(submmitButtonName).hide();
                selectStep(i - 1);
            });
        }

        function createNextButton(i) {
            var stepName = "step" + i;
            $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next'>"+options.nextLabel+" ></a>");

            $("#" + stepName + "Next").bind("click", function(e) {
                $("#" + stepName).hide();
                $("#step" + (i + 1)).show();
                if (i + 2 == count)
                    $(submmitButtonName).show();
                selectStep(i + 1);
            });
        }

        function selectStep(i) {
            $("#steps li").removeClass("current");
            $("#stepDesc" + i).addClass("current");
        }

    }
})(jQuery);
[/code]

Thanks for your plugin

Janko

Janko 05 Oct 2009 #

Micael: Good ideas, thanks for extending and sharing it!

Derek Pennycuff

Derek Pennycuff 06 Oct 2009 #

I'll have to experiment with this one to see if it plays nice with PEAR.HTML.QuickForms.Renderer.Tableless. If not, I've been considering trying to write my own renderer anyway.

My biggest fear with this one is I've put so much energy into arguing for streamlined, simple forms this could encourage people to request more and more fields.

I also wonder about impact on completion rates. From my observations with using SurveyMonkey (which is sorta like a big form, right?) lots of people complete the first page with significant losses on each subsequent page. Putting it all on a single long page seems to get a higher return rate, or at lest cut down on the partial submissions. That's far from scientific, and could be a topic ripe for some A/B testing.

Janko

Janko 06 Oct 2009 #

Derek: Thanks for mentioning this! As far as I am concerned adding additional fields should be something that brings value to customers and should be agreed with them. This should be the same for both cases.

Regarding completion rates, I think it depends on context, but it would be really interesting to see the results from A/B testing.

killy

killy 06 Oct 2009 #

wow, great script. thanks Laughing

Louis

Louis 08 Oct 2009 #

Hi great code

Russell

Russell 15 Oct 2009 #

Hi,
Great piece of script, quite simple to use and works really well. One question, i've added in the livevalidation code as suggested above but how can i stop the user going to step 2 if the fields don't validate?

File Horse

File Horse 16 Oct 2009 #

Great work! Thanx mate! CHEARS!

Daniel

Daniel 18 Oct 2009 #

Odlican plugin Smile

Greg

Greg 21 Oct 2009 #

Thanks for the code.  this can be very useful especially if the wizard can be turned on and off much like in Google Adsense.

Mohamed Amine

Mohamed Amine 22 Oct 2009 #

Really interesting. I was wondering for awhile how to do this. Thanks.

M&#243;nica Baquerizo

Mónica Baquerizo 24 Oct 2009 #

Good job, Excellent !. I will do in my thesis
Thanks

Andy Walpole

Andy Walpole 24 Oct 2009 #

Excellent tutorial. Bookmarked. I'm going to use this on a forthcoming project....

Andrew

Andrew 25 Oct 2009 #

Hey.. love the code, except it breaks in IE7 for me! :-(

Dirty Bird

Dirty Bird 27 Oct 2009 #

Great plug in, works so easy in FF, Opera and Safari. I keep getting the "Object doesn't support this property or method" error in IE. I see some others had this issue as well, is there a fix? Please help!
thanks!

Dirty Bird

Dirty Bird 27 Oct 2009 #

Here is what Im using to call the Wizard, it works in all browsers but IE
<script type="text/javascript">
$(document).ready(function() {
  $("#signUp").formToWizard({ submitButton: 'submitButton' });
});
</script>

I changed it from the demo, as it needs to fire on page load not an onclick.
Please help!

Janko

Janko 27 Oct 2009 #

The reason why this won't work in IE is a comma character that has been left by my mistake. Remove it from this line at the very beginning of the plugin.

        options = $.extend({  
            submitButton: ""  < this line should be without comma character at the end
        }, options);

Thanks everyone who noticed this!

josemrb

josemrb 29 Oct 2009 #

Hi, nice plugin, I've added some functionality and want to share my changes but I don't know under what license You've published the code, thanks.

Karl

Karl 29 Oct 2009 #

Nice plugin, I like the design pattern used.

Somewhere on my HDD I think I was working on similar using tabs (divs) instead which got me around a problem I experienced with this plugin - if you nest fieldsets it all goes horribly wrong... maybe if it looks for a user-defined class on a fieldset to act upon that would solve it?

Thanks for sharing Smile

Dirty Bird

Dirty Bird 29 Oct 2009 #

Thanks for that Janko. I had to copy your script through your url to get it to work. Phew! Very glad to be able to use it. Very nice.
Thanks again.

Josh

Josh 31 Oct 2009 #

Thanks for the awesome plugin, I have successfully got it working. I do have a question though, is there a way to go to a specific page... I need to apply some validation server side, and would like it to return to one of the pages.

Jesse

Jesse 12 Nov 2009 #

Hi! Love this plugin - I have a long, long form (over 300 fields) and this thing is a godsend. I'd also love to use it with the jQuery validation plugin - does anyone know how to validate one fieldset at a time using the Next buttons, instead of waiting at the end for the Submit button? Thanks for any assistance you can provide.

Maicon Sobczak

Maicon Sobczak 17 Nov 2009 #

Great solution for extensive forms!  An create a plugin from it turn our work much better. Thank you.

Jasper

Jasper 18 Nov 2009 #

I would also be interested in combining this with steps validation.

Jos&#233; Alfredo

José Alfredo 19 Nov 2009 #

primo, dejame decirte que esta vaina esta la verga!!, now in english, dude this shit is wack!!, great job and pretty efficient

awake

awake 19 Nov 2009 #

Janko... ur a mad man!  Luv This!

Dave Blencowe

Dave Blencowe 04 Dec 2009 #

Hi there Janko,

Firstly I would like to say great plugin,
Unfortunately when using the latest version of the jQuery javascript library your plugin dies with the following error:
uncaught exception: Syntax error, unrecognized expression: #
anonymous()js.js (line 11)
anonymous()jquery-1....2.min.js (line 19)
anonymous([function(), function(), function(), 1 more...], function(), Object name=F)jquery-1....2.min.js (line 12)
anonymous()jquery-1....2.min.js (line 19)
anonymous()


I hope you have some ideas on how this can be fixed and I'll take a look myself now.
Dave,

sabbir

sabbir 06 Dec 2009 #

Nice work ! thanks !

Themba Ntleki

Themba Ntleki 08 Dec 2009 #

Thank for a great plugin, I really love this, but I have noticed that someone mentioned that , this does not work on IE7, can this be fixed please please and is there way to write into a cookie which step you are currently on...so that when you refresh the page, you are not back to step1?

Thank you.

Janko

Janko 09 Dec 2009 #

Dave: I'm not sure why this happens, I couldn't get that error

Dave

Dave 10 Dec 2009 #

Hi Janko,

I really like your plug-in. I'm pretty new with jquery and gather I am doing something wrong. I have your plug-in working with a bunch of validation I created. For my validation I added a var required = 1 if the validation failed or 0 if it passes. What I am trying to do is have a message next to the Next > button that says Oops! You need to fix some fields. I also want the next button to be disabled until the user has made the required changes. What I attempted to do is the following...


$(a.next).bind(click, (function(){
  if((required) == 1){
    $(a.next).prepend("<span>Oops!</span>");
  }
  else{
    
  };
  
}));


Basically this just broke the functionality of your plug-in. Could you please give me a hand?

Thanks!

Dave

Menno

Menno 15 Dec 2009 #

Hey janko,

Just wanted to say i stumbled upon your plugin, used it, and i find it really satisfying.
You posted it, its expandable, it isnt hard to read, easy to style with css, no problem to use in combination with php (or any language for that matter, as far as i can see)

So yeah, thanks, and keep up the good work (:

Menno

Joe

Joe 15 Dec 2009 #

Hey Janko, nice work!! Keep it up!!

Michael

Michael 18 Dec 2009 #

Wow that is very nice. Let's see if someone is porting this to go MOO ;)

Brian Wangila

Brian Wangila 25 Dec 2009 #

Hey Janko

Thanks for the great script. I am currently integrating this into my PHP Web Application. I will post how successful it is.

Tommy

Tommy 25 Dec 2009 #

Hi, Janko this is great concept and plugin.

I've added bassistance support, these are two simple snippets to add:

options reading:

options = $.extend( {
  submitButton : "submit",
  validationEnabled : true
}, options);

createNextButton function:

$("#" + stepName + "Next").bind("click", function(e) {
  if (options.validationEnabled) {
    if (!element.valid()) {
      element.validate().focusInvalid();
      return false;
    }
  };

  $("#" + stepName).hide();

Hope it helps someone.

Tommy

Tommy 25 Dec 2009 #

Fix for my prevoius comment. This is the correct version of createNextButton snippet:

if (options.validationEnabled) {
    var stepIsValid = true;
    $("#" + stepName + " :input").each( function(index) {
         stepIsValid = !element.validate().element($(this)) && stepIsValid;
    });
    if (!stepIsValid) {
         return false;
    }
}

... still experimenting with code formatting on your blog

Dave

Dave 28 Dec 2009 #

As a follow up to my earlier problem. I was able to disable the button when my validation did not pass.

It's not pretty but it works...

function createNextButton(i) {
            var stepName = "step" + i;
             $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next'>Next ></a>");  
            $("#" + stepName + "Next").bind("click", function(e) {
if ($("#reqValue").val() == 0 && $("#req1Value").val() == 0 && $("#req2Value").val() == 0 && $("#req3Value").val() == 0 && $("#req4Value").val() == 0){
    $("#" + stepName).hide();
                $("#step" + (i + 1)).show();
                if (i + 2 == count)
                    $(submmitButtonName).show();
                    selectStep(i + 1);
    }  else {};      
      });
        }

seman

seman 30 Dec 2009 #

wow, great script. thanks

huge

huge 06 Jan 2010 #

I don't understand why the submit button doesn't work?
have set post on the form, but still will not submit.
Trying to send the form detail off for processing to database, obviously missing something obvious.

huge

huge 06 Jan 2010 #

Also.. are name=" " and id=" " interchangeable?
will be sending variables via php to a database, will this work?
thanks

huge

huge 06 Jan 2010 #

soooory, got it, it has been 5 years since i touched this stuff!
thanks a mil!

Sasha

Sasha 09 Jan 2010 #

Hi Janko, this plugin is great, thanks.

I modified your code for allowing 'StepName' can be clicked, as user may need go back to step2 from step 8.

Code is simply and is working.  code below add in steps.each(function(i)

$("#steps").append("<li id='stepDesc" + i + "' Class='Stepsname'>Step " + (i + 1) + "<span>" + name + "</span></li>");

//add Class to <li> for CSS

$("#stepDesc" + i).bind("click", function(e) {
                for (var f=0;f<=count;f++){
        $("#step" + f).hide();
        }
        $("#step" + i).show();
        if (i + 1 == count)
                    $(submmitButtonName).show();
        selectStep(i);
            });

Alfrek

Alfrek 11 Jan 2010 #

Thanks for your script, it has helped me so much, btw I trasnlated it to spanish and added a Link to each step, for accesing a given step without having to go back and forward. I hope you like it!

/* Created by jankoatwarpspeed.com */

(functionMoney {
    $.fn.formToWizard = function(options) {
        options = $.extend({  
            submitButton: ''
        }, options);
        
        var element = this;

        var steps = $(element).find("fieldset");
    var actual = 0;
        var count = steps.size();
        var submmitButtonName = "#" + options.submitButton;
        $(submmitButtonName).hide();

        // 2
        $(element).before("<ul id='steps'></ul>");

        steps.each(function(i) {
            $(this).wrap("<div id='step" + i + "'></div>");
            $(this).append("<p id='step" + i + "commands'></p>");

            // 2
            var name = $(this).find("legend").html();
            $("#steps").append("<li id='stepDesc" + i + "'><a href='#' id='goto"+i+"'>Paso " + (i + 1) + "<span>" + name + "</span></a></li>");
      
      $("#goto" + i).bind("click", function(e) {
                $("#step" + actual).hide();
                $("#step" + (i)).show();
                $(submmitButtonName).hide();
                selectStep(i);
        actual = i;
            });

            if (i == 0) {
                createNextButton(i);
                selectStep(i);
            }
            else if (i == count - 1) {
                $("#step" + i).hide();
                createPrevButton(i);
            }
            else {
                $("#step" + i).hide();
                createPrevButton(i);
                createNextButton(i);
            }
        });

        function createPrevButton(i) {
            var stepName = "step" + i;
            $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Prev' class='prev'>< Atras</a>");

            $("#" + stepName + "Prev").bind("click", function(e) {
                $("#" + stepName).hide();
                $("#step" + (i - 1)).show();
                $(submmitButtonName).hide();
                selectStep(i - 1);
        actual = i-1;
            });
        }

        function createNextButton(i) {
            var stepName = "step" + i;
            $("#" + stepName + "commands").append("<a href='#' id='" + stepName + "Next' class='next'>Siguiente ></a>");

            $("#" + stepName + "Next").bind("click", function(e) {
                $("#" + stepName).hide();
                $("#step" + (i + 1)).show();
                if (i + 2 == count)
                    $(submmitButtonName).show();
                selectStep(i + 1);
        actual = i+1;
            });
        }

        function selectStep(i) {
            $("#steps li").removeClass("current");
            $("#stepDesc" + i).addClass("current");
        }

    }
})(jQuery);

Alfrek

Alfrek 11 Jan 2010 #

And here is the css rules, for the <a>'s

#steps li a
{
  color: #999;
}

#steps li.current a
{
  color: #036;
}

Leanne

Leanne 12 Jan 2010 #

@Tommy, I'm trying to implement the bassistance validation plugin, using your code, which shows the fields which are required, BUT the next button dies (you click on it and nothing happens at all whether all fields are filled in or not)..

Did anyone get it working with bassistance?

Great script by the way!! Smile

Tommy

Tommy 19 Feb 2010 #

Hi Leanne, check messages posted by me and/or Paolo. There is some mistake in my code.

Kyle Fox

Kyle Fox 12 Jan 2010 #

Nice script.  You should post it on Github so that people can report issues and submit patches without having to litter your blog with ugly, unformatted code in the comments.

fb

fb 06 Mar 2010 #

I second this, please post on github, give your work the honor it deserves, share it on a broader spectrum, just my 2 cents

isbkch

isbkch 26 Jan 2010 #

Nice work man...
This plugin display just 5 steps, and i want to go above this, is it possible  ?

isbkch

isbkch 26 Jan 2010 #

I wrote the comment above, because im fetching the questions and the fields from a mysql DB and it displays me only the five first questions...

Paolo

Paolo 04 Feb 2010 #

Thank for this nice script!

@Tommy: Based on you code I was able to integrate jQuery's validation plugin to have a step-by-step validation, but I needed to change the condition you're using to check if each single input is valid

from
stepIsValid = !element.validate().element($(this)) && stepIsValid;

to
stepIsValid = element.validate().element($(this)) && stepIsValid;

Now it seems to work as expected

jagang

jagang 18 Feb 2010 #

@Tommy and Paolo

Sometimes you could get an undefined instead of true or false! I don´t know why but this code should fix the problem and now the formToWizard combined with jQuey´s Validation plugin should work in every case!

             if (options.validationEnabled) {
                  var stepIsValid = true;
                  $("#" + stepName + " :input").each( function(index) {
                    var xy = element.validate().element($(this));
                    if(xy == undefined) xy = true;
                       stepIsValid = xy && stepIsValid;
                  });
                  if (!stepIsValid) {
                       return false;
                  };
              };

Tommy

Tommy 18 Feb 2010 #

Paolo, thanx for the correction. It was my mistake of course. I fixed my local code and didn't fixed post I wrote

Draw

Draw 04 Feb 2010 #

Hey Janko, great code.
I'm wondering if I can get rid of the "steps" part and just show the legends.

Thanks for you time.

Richard

Richard 19 Feb 2010 #

Hey Janko,

This is a great plugin that I've used several times. I did run into this problem a couple of times, mainly through typos and being an idiot:

uncaught exception: Syntax error, unrecognized expression: #

There's no other information available - no line number or anything (which is amazingly unhelpful). However, it boils down to not having fieldsets or legends in place (or in my case have not spelt them correctly).  This might help other people out Smile

Sam Sweeney

Sam Sweeney 26 Feb 2010 #

Nice plugin, Janko.

I did change a few things though:

1) The next > and < Back buttons text was changed to make the symbols html character codes.
2) The link is #, this can potentially still follow the link(this was the case for me). so I replaced '#' with 'javascript:void(0);'.
3) I added a live event to the steps, so if a user clicks on a step it will take them there.

Thanks!

Paolo

Paolo 26 Feb 2010 #

@jagang

Thanks for your piece of advice.
I never got 'undefined' as value so far, but if I will I'll apply your code.

ilyas bakouch

ilyas bakouch 26 Feb 2010 #

this plugin helped me to create my quizz on www.isbkch.com/quiz
just want to say thank you Smile

Glenn Coomans

Glenn Coomans 09 Mar 2010 #

Hi all

I'm new into JQuery, but when I use this script and I add other JQuery UI (datepicker or slider), then the FormWizard is not working: the form is displayed on one 'page', not in 'steps'. It must be something with the references to the other JS libraries.
A hint?

THX

Comments are closed
via Ad Packs
9006