I had a very hard time making a Drupal multistep form finding an example which wasn't trying to be clever. So when I had a nasty problem I made my own multistep_example module to help debug. the bug by the way turned out to be with the hide_submit module disable mode, which breaks when there are two submit buttons.
The following code attempts to make the simplest possible Drupal 6 multistep form, including submit and validate functions. Use it as the basis for your multistep form. The only issue is that #redirect doesn't work, so drupal_goto is used instead. Here is the module code in its entirety:
'Multistep example', 'page callback' => 'drupal_get_form', 'page arguments' => array('multistep_example_form'), 'access callback' => TRUE ); return $items; } function multistep_example_form($form_state) { if (!$form_state['storage']['step']) $form_state['storage']['step'] = 1; $form_state['values'] = $form_state['storage']['values']; drupal_set_title('Multistep example - step '. $form_state['storage']['step'] . ' of '. STEPS); $form = array(); //'next' appears at every step $form['next'] = array(//corresponds to 'edit-next' in form_submit '#type' => 'submit', '#value' => 'submit', '#weight' => 1 ); switch($form_state['storage']['step']) { case 1: $form['info1'] = array( '#title' => 'field on first page', '#type' => 'textfield', '#default_value' => $form_state['values']['info1'], '#element_validate' => array('multistep_element_validate'), ); break; case 2: $form['info2'] = array( '#title' => 'field on second page', '#type' => 'textfield', '#default_value' => $form_state['values']['info2'], '#element_validate' => array('multistep_element_validate'), ); } //next button if ($form_state['storage']['step'] > 1) { $form['back'] = array( //corresponds to 'edit-back' in form_submit '#value' => 'back', '#type' => 'submit', '#weight' => 1 ); } $form['#redirect'] = 'user'; return $form; } function multistep_example_form_submit(&$form, &$form_state) { //multistep processing if (!$form_state['storage']['values']) { $form_state['storage']['values'] = array(); } //increment the button, overwrite the storage values with the new values, and return if ($form_state['clicked_button']['#id'] == 'edit-back') { $form_state['storage']['step']--; $form_state['storage']['values'] = $form_state['values'] + $form_state['storage']['values']; return; } elseif ($form_state['clicked_button']['#id'] == 'edit-next' && $form_state['storage']['step'] < STEPS) { $form_state['storage']['step']++; $form_state['storage']['values'] = $form_state['values'] + $form_state['storage']['values']; return; } //if this is the last step, $values = $form_state['storage']['values'] + $form_state['values']; //clear the storage and rebuild so that the fom doesn't rebuild, and the #redirect works $form_state['rebuild'] = TRUE; unset($form_state['storage']); $values = $form_state['storage']['values']['info1'] .' & '. $form_state['storage']['values']['info2']; drupal_set_message('The form has been submitted with values: '.$values); } function multistep_example_form_validate($form, &$form_state) { drupal_set_message('validating multistep form'); } function multistep_element_validate($element, &$form_state) { drupal_set_message('validating field: '. $element['#name']); }?>
Comments2
Using this code as an example
Using this code as an example to build from I ran into issues regarding using the '#value' attribute in image_buttons. If anyone else finds their way here and has a problem with only seeing the last button as being clicked check out this link:
https://drupal.org/node/206955.
When using image_buttons you cannot set a #value, nor can you set a #default_value. You need to use #return_value. The reason for this is explained in the above link.
It seemed really nice, but as
It seemed really nice, but as the above comments state it doesn't work.
The first submit doesn't take you to the second step, but you stay at STEP 1.
As I found out, values don't get stored for long somehow (the behavior is still a bit mysterious to me). However the $form_stat['storage'] data will be kept over all calls. In addition "If $form_state['storage'] is populated by any submit handlers, $form_state['rebuild'] is automatically set to true" as https://drupal.org/node/144132#multistep states.
With this in mind I accomplished what I wanted. Hope it helps more of you.