7

I have a multi-page form. Visit page 1, page 2 and then page 3. Push refresh (f5) and the form goes back to page 2.

This is with drupal-6. The problem looks similar to this http://drupal.org/node/1060290.

Digging into the problem, via the form_cache database table. Both page 1 and 2 data appear in there. In the php debugger it looks as though a new form_id has been created. ie. storage_form-1add3819cbea88139679819935a69686 is the key in the database cache table and form-bcf9556f57f5352a57dfbba4c2120ee7 is the 'form_id' on refresh.

What does my form code look like?

Main form function:

function myform_online(&$form_state) {
  // $form_state['storage']['step'] keeps track of what page we're on.
  // start at step 1 if no storage has been set
  if (!isset($form_state['storage']['step'])) {
    $form_state['storage']['step'] = 1;
 }

 // If we are saving the form data we should submit rather than display the details.
 // At least look at saving the step.

 // Don't lose our old data when returning to a page with data already typed in.
 $default_values = array();
 if (isset($form_state['storage']['values'][$form_state['storage']['step']])) {
    $default_values = $form_state['storage']['values'][$form_state['storage']['step']];
 }

 switch ($form_state['storage']['step']) {
    case 1:
        // Your Details
        module_load_include('inc', 'join_online', 'includes/step1'); 

And we handle submit:

function join_online_submit($form, &$form_state) {
//Save the values for the current step into the storage array.
//dsm($form_state); 

$form_state['storage']['values'][$form_state['storage']['step']] = $form_state['values'];

# ahah - bail.
if ($form_state['ahah_submission']) {
    return;
}

// How do we work out if this was a refresh? It currently does start with 1 and think that the step is #2. 

//Check the button that was clicked and change the step.
if ($form_state['clicked_button']['#id'] == 'edit-previous') {
    $form_state['storage']['step']--;
} elseif ($form_state['clicked_button']['#id'] == 'edit-next') {
    $form_state['storage']['step']++;
} elseif ($form_state['clicked_button']['#id'] == 'edit-finish') {
    //You should store the values from the form in the database here.
    //We must do this or the form will rebuild instead of refreshing.
    unset($form_state['storage']);

    //Go to this page after completing the form.
    $form_state['redirect'] = 'join_online/form/thank-you';
}
}
Henrik Opel
  • 19,341
  • 1
  • 48
  • 64
Interlated
  • 5,108
  • 6
  • 48
  • 79
  • Do you have `#ajax` or `#ahah` elements? Because in the case things are a bit different. You might want to have a look here: http://drupal.org/node/650016 – Max Dec 18 '11 at 12:38
  • It is a good point. The previous page to the one that fails does #ahah. Drupal does 'new cache' then delete old cache. But there is no pointer to the new cache when you refresh in this case. Also can't find a place to put it into the SESSION. Doesn't cache until it builds form and then all you get is a string. Still looking. – Interlated Dec 20 '11 at 04:25
  • I don't think you have to resort to session to save your data. Best thing would be to find a good working example of a multi-step form with `#ahah` elements and start from there. Unfortunately I can't think of one but there has to be a module out there. Here is a nice article from someone apparently was struggling with the same thing as you are: http://www.designend.net/en/webmaster-blog,drupal-ahah-multistep-ahah-forms-with-proper-ahah-behavior – Max Dec 21 '11 at 13:08
  • Maybe you could use a Multistep module. I think it will do what you are aiming for and more. – Povylas May 07 '12 at 15:32

1 Answers1

1

If you use $form_state['rebuild'] = TRUE in _submit function the state of the form is saved and can be used for default values.

Check this example: http://www.ferolen.com/blog/how-to-create-multistep-form-in-drupal-6-tutorial/

johnlemon
  • 20,761
  • 42
  • 119
  • 178