Drupal 6 AHAH forms: Making New Fields Work
Tags:
Today, I was working with drupal 6's AHAH form elements. Initially, I was delighted at how well they worked. That delight turned to confusion once I realized that the form elements I had put in the menu callback of the #ahah['path'] was missing its name attribute. After doing a bit of research in how the poll module handled the formapi voodoo, I created a generalized function to aid in building AHAH callbacks. If there is a better way to do this, I wasn't able to find it.  <?php
// this is an example menu_callback that would be referenced by the #ahah['path'] property
function easy_ahah_form_field() {
  // all you have to worry about is the new form field that will be inserted via #ahah
  $form = array(
    '#type' => 'select',
    '#title' => 'You selected that because...',
    '#options' => array(
      '1' => 'drugs',
      '2' => 'I do what I want.',
      '3' => "I'm feeling lucky..."
    ),
  );
  // ahah_render is where the magic happens.
  // 'the value of this field will show up as $form_value['user_problem']
  $output = ahah_render($form, 'user_problem');
  print drupal_to_js(array('data' => $output, 'status' => true));
  exit();
}
/*
  This function is largely based on the poll module, its been simplified for reuse.
  $fields is the specific form elements you want to attach via ahah,
  $name is the form fields array key... e.g. the name for $form['title'] is "title"
*/
function ahah_render($fields, $name) {
  $form_state = array('submitted' => FALSE);
  $form_build_id = $_POST['form_build_id'];
  // Add the new element to the stored form. Without adding the element to the
  // form, Drupal is not aware of this new elements existence and will not
  // process it. We retreive the cached form, add the element, and resave.
  $form = form_get_cache($form_build_id, $form_state);
  $form[$name] = $fields;
  form_set_cache($form_build_id, $form, $form_state);
  $form += array(
    '#post' => $_POST,
    '#programmed' => FALSE,
  );
  // Rebuild the form.
  $form = form_builder($_POST['form_id'], $form, $form_state);
  // Render the new output.
  $new_form = $form[$name];
  return drupal_render($new_form);
}
?>