Here is an example of a basic multistep Drupal 6 form with 3 steps, "Previous" and "Next" buttons on each step and possibility of moving both forwards and backwards in the flow with submitted data being passed on between all steps.
/**
* Defines total number of form steps.
*/
define('TEST_FORM_TOTAL_STEPS', 3);
/**
* Implements hook_menu().
*/
function test_menu() {
$items = array();
// Form page.
$items['test/form'] = array(
'title' => t('Test Form'),
'page callback' => 'test_page',
'page arguments' => array(),
'access arguments' => array('access content'),
);
// Success page.
$items['test/success'] = array(
'title' => t('Test successful!'),
'page callback' => 'test_success',
'page arguments' => array(),
'access arguments' => array('access content'),
);
return $items;
}
/**
* Fetches and displays the form.
*/
function test_page() {
return drupal_get_form('test_form');
}
/**
* Displays simple confirmation page after finishing the whole process.
*/
function test_success() {
return 'OK!';
}
/**
* Generates the form.
*/
function test_form($form_state) {
// Set current step to 1 if user just starts the process.
if (!isset($form_state['storage']['step'])) {
$form_state['storage']['step'] = 1;
}
switch ($form_state['storage']['step']) {
case 1:
// Custom page title.
drupal_set_title('Step 1');
// All the real form fields.
$form['step1_field1'] = array(
'#title' => 'Step 1 Field 1',
'#type' => 'textfield',
'#default_value' => $form_state['storage']['values'][1]['step1_field1'],
);
// Add submit button(s).
$form += _test_add_submit_buttons($form_state);
// Not important - used only for displaying values posted so far.
$form['posted_values'] = array(
'#type' => 'markup',
'#value' => _test_display_posted_values($form_state),
);
break;
case 2:
// Custom page title.
drupal_set_title('Step 2');
// All the real form fields.
$form['step2_field1'] = array(
'#title' => 'Step 2 Field 1',
'#type' => 'textfield',
'#default_value' => $form_state['storage']['values'][2]['step2_field1'],
);
// Add submit button(s).
$form += _test_add_submit_buttons($form_state);
// Not important - used only for displaying values posted so far.
$form['posted_values'] = array(
'#type' => 'markup',
'#value' => _test_display_posted_values($form_state),
);
break;
case 3:
// Custom page title.
drupal_set_title('Step 3');
// All the real form fields.
$form['step3_field1'] = array(
'#title' => 'Step 3 Field 1',
'#type' => 'textfield',
'#default_value' => $form_state['storage']['values'][3]['step3_field1'],
);
// Add submit button(s).
$form += _test_add_submit_buttons($form_state);
// Not important - used only for displaying values posted so far.
$form['posted_values'] = array(
'#type' => 'markup',
'#value' => _test_display_posted_values($form_state),
);
break;
}
return $form;
}
/**
* Handles submitted form.
*/
function test_form_submit($form, &$form_state) {
// Save all posted values for $form_state['storage']
// to make them available in all other steps.
$form_state['storage']['values'][$form_state['storage']['step']] = $form_state['values'];
// Deal with current step based on which submit button was clicked.
switch ($form_state['clicked_button']['#id']) {
case 'edit-next':
// Do not finally submit the form yet, rebuild it instead.
$form_state['rebuild'] = TRUE;
// Go to next step.
$form_state['storage']['step']++;
break;
case 'edit-prev':
// Do not finally submit the form yet, rebuild it instead.
$form_state['rebuild'] = TRUE;
// Go to previous step.
$form_state['storage']['step']--;
break;
case 'edit-finish':
// Do something with all form values ($form_state['storage']) before unsetting it.
// ...
// And then unset it.
unset($form_state['storage']);
// This was the final step, so redirect to success page.
$form_state['redirect'] = 'test/success';
break;
}
}
/**
* Adds relevant submit buttons based on current step.
*/
function _test_add_submit_buttons($form_state) {
$buttons = array();
// Display 'Prev' button on all steps excluding first.
if ($form_state['storage']['step'] > 1) {
$buttons['prev'] = array(
'#type' => 'submit',
'#value' => 'Prev',
);
}
// Display 'Next' button on all steps excluding last.
if ($form_state['storage']['step'] < TEST_FORM_TOTAL_STEPS) {
$buttons['next'] = array(
'#type' => 'submit',
'#value' => 'Next',
);
}
// Display 'Finish' button on the last step.
if ($form_state['storage']['step'] == TEST_FORM_TOTAL_STEPS) {
$buttons['finish'] = array(
'#type' => 'submit',
'#value' => 'Finish',
);
}
return $buttons;
}
/**
* Displays values posted so far beneath the form.
*/
function _test_display_posted_values($form_state) {
$output = '<p>Posted values:</p>';
$output .= '<p>Step 1 field 1: ' . $form_state['storage']['values'][1]['step1_field1'] . '</p>';
$output .= '<p>Step 2 field 1: ' . $form_state['storage']['values'][2]['step2_field1'] . '</p>';
$output .= '<p>Step 3 field 1: ' . $form_state['storage']['values'][3]['step3_field1'] . '</p>';
return $output;
}