Breaking Drupal 7 Webforms into Multiple Steps the Easy Way

I recently played the role of Information Architect on a site remodel. We were charged with the task of doing a brand new build to replace an existing Flash site. One of the priorities of the client was to retain the elaborate Request for Quote form. There were many, many form fields that comprised this web form so I began to ponder if we should break the form up into a multiple step form, to improve the overall user experience. After careful consideration, I decided that we should definitely split the form up (for more on this matter check out Pagination in Web Forms | Evaluating the Effectiveness of Web Forms on UXmatter.com). Since there was no logic needed in the progression of the form, I felt that Javascript would be an acceptable solution, over using an actual server-side wizard. Thanks to Janko and his Turn any webform into a powerful wizard with jQuery blog, I found his JQuery plugin very easy to implement. This tutorial assumes that you have some basic working knowledge of the Webform module and how to create a custom module of your own.

Module or Theme?

I feel like I ask myself that question at least 10 times a day. This solution could be implemented using either method, but after careful consideration, I felt like this was more of a function feature than just appearance, so I decided that the modular level was the way to go. Our demonstration module will be called Wizardify. Let’s get started.

Set up the webform

The first thing we need to do is make sure the Webform module is enabled, and create a Weform node. The wizardify plugin that we will be using splits the form up by fieldsets, so we need to create some fieldsets, each with a few fields inside. Here’s what it looks like:

Download the plugin

Next we’re going to download the FormToWizard plugin. Create a folder inside your module called js, and place the formToWizard.js file in that folder.

Include the plugin

In your wizardify.module file, we are going to use the drupal_add_js function inside the hook_preprocess_page to include the FormToWizard plugin.

[php]/**
* Implements hook_preprocess_page
*/
function wizardify_preprocess_page(&$variables) {
// define base path for our module
$base = drupal_get_path(‘module’, ‘wizardify’);
// add the wizardifying javascripts
drupal_add_js($base . ‘/js/formToWizard.js’);
}[/php]

Initiate the plugin

We need to write a small piece of JavaScript to initiate the plugin. Inside the js folder, create a file called jquery.wizardify.init.js and insert the following code:

[javascript]jQuery(document).ready(function () {
// wizardify the webform
jQuery("#webform-client-form-55").formToWizard({ submitButton: "edit-submit" });
});[/javascript]

What we’re doing here is using the form id of #webform-client-form-55 and applying the formToWizard plugin, once the page is fully loaded. My webform node id is 55, but yours will be something different. Make sure to double check the id of your form element, and use that in the jQuery context. The only parameter that we’re using is the submitButton, which allows you to specify the id of the submit button on the form. This will hide the submit button until the final “panel” of the form is displayed.

Include the init javascript

We need to add a new drupal_add_js line to our hook_preprocess to include the init javascript we just created. It now looks like:

[php]
/**
* Implements hook_preprocess_page
*/
function wizardify_preprocess_page(&$variables) {
// define base path for our module
$base = drupal_get_path(‘module’, ‘wizardify’);
// add the wizardifying javascripts
drupal_add_js($base . ‘/js/formToWizard.js’);
drupal_add_js($base . ‘/js/jquery.wizardify.init.js’);
}
[/php]

Now if you refresh the Webform node, you should see the new wizardified version of the form, complete with a progress indicator, created from the legend elements of our fieldsets. Go ahead and try it out.

Spiff it up

Our form now works, but we can take this another step further in the name of UX. We’re going to add the “button” class to our Next and Previous links, and add some custom css just to pretty things up a bit.

Add the button classes

Since the next and previous links are created by javascript, it’s fair to modify them using javascript. We want them to look like our theme’s buttons. In your jquery.wizardify.init.js file, we’re going to use the addClass method. It should now look something like:

[javascript]
jQuery(document).ready(function () {
// wizardify the webform
jQuery("#webform-client-form-55").formToWizard({ submitButton: "edit-submit" });
// add the ‘button’ class to the next and previous links
jQuery(‘a.prev’).addClass(‘button’);
jQuery(‘a.next’).addClass(‘button’);
});
[/javascript]

Refresh the page and it should now look like this:

Create custom CSS

We’re going to add a little bit of custom css to finish this thing up. We need to create a directory inside our module called css. In the css folder, create a file called wizardify.css and paste in the following code:

[css]
#steps{
border:1px solid #CCCCCC;
border-radius:4px;
margin-top:10px;
padding:10px;
}

#steps li{
list-style-type:none;
color:#ccc;
}

#steps .current{
color:#3B3B3B;
}

#steps .fieldset-legend{
margin-left:15px;
}

#step0 fieldset legend,
#step1 fieldset legend,
#step2 fieldset legend{
display:none;
}

.next,
.prev{
margin-left:10px;
}
[/css]

Include custom CSS

Now, we need to include that custom css file. Go to the wizardify.module file and insert a drupal_add_css in the hook_preprocess_page. It will now look like this:

[php]
/**
* Implements hook_preprocess_page
*/
function wizardify_preprocess_page(&$variables) {
// define base path for our module
$base = drupal_get_path(‘module’, ‘wizardify’);
// add the wizardifying javascripts
drupal_add_js($base . ‘/js/formToWizard.js’);
drupal_add_js($base . ‘/js/jquery.wizardify.init.js’);
// add the custom css
drupal_add_css($base .’/css/wizardify.css’);
}
[/php]

Refresh the page and it should now look pretty nice.



Success!

We’ve now successfully created our Webform node, added a jQuery plugin, included our custom Javascript, and included some custom CSS. My client deliverable actually took things a bit further with client-side validation and more robust styling, so feel free to experiment to create a great and useable faux-wizard form.