It seems that it is not possible to have D6 automagically re-populate an invalid step (one that fails validation) of a mult-step form. I'm not sure if I'm missing something, or if this is intended behaviour.

I am trying to create a multi-step form, following the basic pattern outlined here: http://drupal.org/node/262422. In my case, I want to use an arbitrary number of steps (more than two) and validate each step before proceeding to the next. However, if any data is present in $form_state['storage'] when a form is submitted the forms engine rebuilds it, regardless of the validation outcome.

The problem stems from line #142 of forms.inc:

if (!empty($form_state['rebuild']) || !empty($form_state['storage'])) {  <-- The problem is with this conditional
  $form = drupal_rebuild_form($form_id, $form_state, $args);
}

This forces a rebuild of the form, wiping out the $_POST data which is used to repopulate a form when re-displayed. Changing the conditional to:

if ($form_state['rebuild']) {

...and then explicitly setting (and unsetting) $form_state['rebuild'] in response to failed validation or successful submission allows per-step form validation.

This approach requires a couple of extra lines of code in _validation and _submit handlers, to handle the explicit rebuild flag, but I think the additional functionality is well worthwhile.

CommentFileSizeAuthor
#2 dontrebuildonerror-291939-2.patch1.33 KBdropcube

Comments

dropcube’s picture

Version: 6.3 » 7.x-dev
Assigned: Unassigned » dropcube
Priority: Critical » Normal

Adding !form_get_errors() to the condition fixed the issue for me. This means, does not rebuild the form if there are validations errors.

  if (!empty($form_state['rebuild']) || !empty($form_state['storage']) && !form_get_errors()) {
    $form = drupal_rebuild_form($form_id, $form_state, $args);
  }

I will post a patch later.

dropcube’s picture

Title: Multi-step Form Invalid Data Re-display Issue » Multistep forms should not be rebuilt if there are validation errors.
Status: Active » Needs review
StatusFileSize
new1.33 KB

The condition should be like this:

  if ((!empty($form_state['rebuild']) || !empty($form_state['storage'])) && !form_get_errors()) {
      $form = drupal_rebuild_form($form_id, $form_state, $args);
  }

Is this a good approach FAPI experts ?

Attached the patch.

dropcube’s picture

Assigned: dropcube » Unassigned
Status: Needs review » Closed (duplicate)

Ok, there was a previous issue about this. I am marking this one duplicate in favor of #302240: button broken due to fix various problems when using form storage .