You are here

Drupal 6 multistep form example

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'] 

Comments

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:
http://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 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 http://drupal.org/node/144132#multistep states.

With this in mind I accomplished what I wanted. Hope it helps more of you.

Add new comment

Theme by Danetsoft and Danang Probo Sayekti inspired by Maksimer