Hello, I'm developing a module where I have to add a small multistep form to an existing node edit form of a content type. Basically the user can select an option from a dropdown list and press a load button to reload the page. The form then gets rebuilt differently depending on the selected option.

To keep things simple I have made the following example (which works very similar to my module):

// $Id$

/**
 * Implementation of hook_form_alter
 */
function test_form_alter($form_id, &$form) {
  // node add/edit form
  if (isset($form['type']) && $form['type']['#value'] . '_node_form' == $form_id) {
    $form['test'] = array(
      '#type' => 'fieldset',
      '#title' => t('Test'),
      '#collapsible'=> true,
      '#after_build' => array('test_after_build')
    );
    
    $form['test']['test_select'] = array(
      '#type' => 'select',
      '#title' => t('Select number of textfields'),
      '#default_value' => '0',
      '#options' => array(0, 1, 2, 3, 4, 5)
    );

    $form['test']['test_load'] = array(
      '#type' => 'button',
      '#value' => t('Load'),
      '#name' => 'op'
    );
  }
}


/**
 * #after_build function for test form
 */
function test_after_build($form, $form_values = NULL) {
  // load selected number of textareas into form
  if (isset($form_values['op']) && ($form_values['op'] == t('Load') || $form_values['op'] == t('Preview'))) {
    for ($i = 0; $i < $form_values['test_select']; $i++) {
      $form['test']['test_textarea_' . $i] = array(
        '#type' => 'textarea',
        '#default_value' => '',
        '#weight' => $i
      );
    }
  }
  
  return $form;
}

The problem is that whenever the page gets reloaded after pressing the load or preview button, I get for each added textfield the following error:
warning: implode() [function.implode]: Invalid arguments passed in D:\homepages\...\httpdocs\includes\form.inc on line 623.

Furthermore none of the data that is entered in the textfields is preserved after the user presses load or preview. Any idead what I'm doing wrong?

Thanks & cheers!

Comments

account-deletion-needed’s picture

Ok I'm not sure why this works but I put the form building code that was inf the #after_build function into form_alter instead
and used $_POST instead of $form_values to read the submitted data (although I think that's not the correct way to do it?).

Code now looks like this:

// $Id$

/**
 * Implementation of hook_form_alter
 */
function nf_product_table_form_alter($form_id, &$form) {
  // node add/edit form
  if (isset($form['type']) && $form['type']['#value'] . '_node_form' == $form_id) {
    $form['test'] = array(
      '#type' => 'fieldset',
      '#title' => t('Test'),
      '#collapsible'=> true,
      '#weight' => -2
    );
    
    $form['test']['test_select'] = array(
      '#type' => 'select',
      '#title' => t('Select number of textfields'),
      '#default_value' => '0',
      '#options' => array(0, 1, 2, 3, 4, 5),
      '#weight' => -1
    );

    $form['test']['test_load'] = array(
      '#type' => 'button',
      '#value' => t('Load'),
      '#name' => 'op',
      '#weight' => -1
    );
    
    if (isset($_POST['op']) && ($_POST['op'] == t('Load') || $_POST['op'] == t('Preview'))) {
      for ($i = 0; $i < $_POST['test_select']; $i++) {
        $form['test']['test_textarea_' . $i] = array(
          '#type' => 'textarea',
          '#default_value' => '',
          '#weight' => $i
        );
      }
    }
  }
}

No more errors and the textfields get pre-populated if data is entered and load/preview is pressed. How come the exact same code
didn't work as an #after_build function?

beautifulmind’s picture

Regards.
🪷 Beautifulmind

account-deletion-needed’s picture

Unfortunately the above fix doesn't work anymore once the data is submitted through the submit button.
I added a submit handler in form_alter:

$form['#submit']['test_submit'] = array();

Which prints out the submitted data:

function test_submit($form, $form_values) {
  ob_start();
  print_r($form_values);
  drupal_set_message(ob_get_contents());
  ob_end_clean();
}

But for some reason none of the entered textarea data shows up in $form_values ...