Tuesday, March 15, 2011

Create multiple step form in Drupal 6

Create multiple step form in Drupal 6
Fri, Apr 24, 2009 by Sae
Multiple step form which consists of multiple steps or pages is useful sometimes. It allows you to create a form workflow and helps to make your web site user-friendly and flexible. For example, you can make different contents on next pages based on user inputs from previous pages.

The key things to make a form multiple pages are setting $form_state['rebuild'] and $form_state['storage'] variables in a submit function.



function example_form_submit($form, &$form_state) {
if($form_state['storage']['page'] == 1) {
$form_state['rebuild'] = TRUE;
$form_state['storage'][$page]['values'] = $form_state['values'];
$form_state['storage']['page']++;
else {
//process the data
}
}

In Drupal 6 FormAPI, a form is cached after it is built once, so setting $form_state['rebuld'] to TRUE rebuilds the form from scratch and allows you to make changes on the form structure after the form is submitted. Also, storing the input from the form into $form_state['storage'] cache the data and carries them to the next page so you can process all inputs together when the last step form is submitted.

I was working on a very simple multi-step form which asks users to choose a type of contents on the first page and provides different input fields based on user's choice from the first step on the next page. My form function was like:

function example_form(&$form_state) {
if(isset($form_state['storage']['page'])) {
$page = $form_state['storage']['page'];
} else {
$page = 1;
}
switch($page) {
case 1:
$form['content_types'] = array(
'#type' => 'radios',
'#title' => t('Content Type'),
'#description' => t('Select a content type'),
'#options' => $options );
break;
case 2:
$type = $form_state['values']['content_types'];
$form['content_fields'] = example_content_fields_form($type);
break;
}
return $form;
}

When the form is loaded first time, $form['storage']['page'] is not set yet. Set this 'page' key to 1 as a default value. Now you can create form elements based on the value of this 'page' variable. When the form is submitted, the submit function stores the input data to $form_state['storage'] variable and increments the page counter. Drupal FAPI reloads the form and back to the form function again.

You can create a form with more steps in the same way applying more page counts. Also, this works with hook_form_alter() so you can customize Drupal forms such as a registration form
=========================================
create article . I got this other solution on the intenet, it is worth looking at.

How to Handle the Three Scenerios

Let's step back for a moment. We now understand the cause of the problem in Form API 1.0: a mismatch between the user's submitted input, and the form array that's build based on it. We also understand how Form API 2.0 fixes that, allowing one form array to be used for processing and another for display. With that in mind, how can your module handle the three dynamic form scenerios outlined at the beginning of the article?

The Long Form

As with all of these scenerios, the real action will happen in your form building function. It will use hidden fields to indicate what 'stage' is currently being displayed, and to store the user input from previous stages. While this was theoretically possible using Form API 1.0, the new features make it much simpler. Here's an example of how your form-building code would look:

function my_form($param1, $param2, $form_values = NULL) {
// In a multistep form, drupal_get_form() will always
// pass the incoming form values to you after any other
// parameters that you specify manually. Do this instead
// of looking at the incoming $_POST variable manually.

if (!isset($form_values)) {
$step = 1;
}
else {
$step = $form_values['step'] + 1;
}

$form['step'] = array(
'#type' => 'hidden',
'#value' => $step,
);

switch ($step) {
case 1:
// Create the fields for the first step of your form here
break;

case 2:
// First, add a hidden field for each of the incoming
// form values.
// Then, add the fields regular form fields that the user
// will see in this second step.
break;

case 3:
// And so on and so forth, until you've reached the final
// step.
break;
}

// This part is important!
$form['#multistep'] = TRUE;
$form['#redirect'] = FALSE;

$form['submit'] = array(
'#type' => 'submit',
);

return $form;
}

In the validation code for your form, you can check the 'step' field to see which set of fields you need to check, and display any errors. The function will keep accumulating hidden values and displaying a new set of fields until it reaches the final step. You'll probably want to prevent your form submission handler from processing the form data until all the steps have been completed. To do that, something like this would be effective:

function my_form_submit($form_id, $form_values) {
$final_step = 10;

if ($form_values['step'] == $final_step) {
// Process the form here!
}
}

The Wizard

This scenerio, from a code perspective, is almost exactly the same as The Long Form. Depending on how your Wizard works, though, you may want to have your form submission handler actually process each step's data, rather than storing it as hidden fields in the next step. Or, you may want to process 'batches' of steps together before proceeding. For example:

function my_form_submit($form_id, $form_values) {
switch ($form_values['step']) {
case 3:
// Process the form data from steps 1, 2, and 3
break;
case 9:
// Process the form data from steps 4 through 9
break;
case 10:
// Process the form data from step 10,
break;
}
}

For very complex wizards, you may also want to split out individual steps as helper functions, but you'll still need to use the 'core' function as the central dispatcher. It's the one that the Form API knows to call automatically during the building and processing stages.

Reference:
http://www.appnovation.com/create-multiple-step-form-drupal-6

1 comment:

drupal themes said...

thank you for your valuable tutorial. this is very much help to update the drupal knowledge. now working as a drupal developer., now im going share our company each drupal developer.