3

I'm trying to add multistep form functionality to a node creation form via a form alter. My (abbreviated) code follows:

function mymodule_form_FORM_ID_alter($form, &$form_state)
{
        if (!isset($form_state['storage']['step']))
        {
            $form['actions']['submit']['#submit'][] = 'my_form_submit';     
        } elseif (isset($form_state['storage']['step']) && $form_state['storage']['step'] == 'step-two')
        {
            $form['foo'] = array(
                '#type' => 'textfield',
                '#title' => 'Add foo',
            );
            $form['actions']['#type'] = 'actions';
            $form['actions']['submit'] = array(
                '#type' => 'submit',
                '#value' => 'Register',
                '#submit' => 'step_two_form_submit',
            );
        }
}

function my_form_submit($form, &$form_state)
{
    if (!isset($form_state['storage']['step']))
    {
        $form_state['storage']['step'] = 'step-two';
        $form_state['rebuild'] = TRUE;
    } 
    //so far so good
}

function step_two_form_submit($form, &$form_state)
{
    //This code never runs
    drupal_goto('/');
    dd('step two ran');
    //etc
}

The second step of the form loads as I would expect along with a submit function. The submit callback, however, is never called. Am I making a mistake by nuking the entire $form array? (The $form_state array, which is what I really need to hold onto, remains intact.) I feel like I'm very close but am missing something substantial.

  • check your #triggering_element and give #name to your submit buttons, that has solved weird issues in the past – Pan Chrono Jun 23 '14 at 15:03
1

This is actually easier than it looks! :)

Use the one submit callback and in it use a switch or if statement to execute different actions depdending on what step you're on.

function my_form_submit($form, &$form_state) {
  if (!isset($form_state['storage']['step'])) {
    $form_state['storage']['step'] = 'step-two';
    $form_state['rebuild'] = TRUE;
  }
  else if ($form_state['storage']['step'] === 'step-two') {
    // do something awesome for step-two
  }
}

UPDATED

The following is working code I have running in Drupal 6:

  // multistep form
  if (!isset($form_state['storage']['page']) || $form_state['storage']['page'] < 4) {
    $form_state['rebuild'] = TRUE;
    $page = $form_state['storage']['page'];
    $form_state['storage'][$page]['values'] = $form_state['values'];
    $form_state['storage']['page']++;
  }
  // process submit
  else {
    // grab submitted values for each step from storage array
  }

It runs in the only submit handler of a multistep form.

I realize this is Drupal 6 but its close enough, can you try this?

  • This is assuming I don't reset the $form array in step two? If I do reset the array, then isn't it arbitrary which submit function I call? If my submit callback isn't running currently, I don't think calling a different submit handler solves my problem, unfortunately... – starsinmypockets Jan 10 '12 at 19:50
  • Try it out, even if you reset the form, the storage is preserved, I'm pretty sure – Alex Weber Jan 10 '12 at 20:06
  • No, unfortunately, the submit callback is not called the second time. – starsinmypockets Jan 10 '12 at 20:13
  • I've updated my answer with a working example from a current site, see if it helps! – Alex Weber Jan 10 '12 at 20:19
  • thanks for your help. I think my code is not disimilar from what you posted. The problem seems to be that the code isn't being called by my submit button, which leads me to believe that there is something wrong with the $form array... I'm stumped – starsinmypockets Jan 10 '12 at 20:34
0

For multistep forms you can use Ctool multistep wizard.

Following are the useful links for the same:

http://www.grasmash.com/article/building-multistep-registration-form-drupal-7-using-ctools

http://www.webomelette.com/ctools-object-cache-multi-step-form

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.