Drupal: Using #ahah to modify forms

Often it is useful to dynamically modify forms by adding or removing form elements with Javascript or Ajax. Drupal 6 makes it easy to do that, using the element attribute #ahah which will react to specified events.

Getting started with AHAH (Asychronous HTML and HTTP, which is really just a fancy name for Ajax) is fairly difficult at first, but once you have a reusable pattern it should be fairly easy.

The following example will add a new option into the select dropdown everytime the user clicks add.

Firstly, you need to define the AHAH attribute on the element upon form declaration.

function example_admin_something_form($form_state) {
  $form = array();
  // The dropdown which gets refreshed when new items are added.
  $form['example_dropdown'] = array(
    '#type' => 'select',
    '#title' => 'Example Dropdown',
    '#options' => array(),
    '#prefix' => "<div id='example-select-wrapper'>",
    '#suffix' => '</div>',

  );
  // The magical AHAH button. This does not cause a page reload.
  $form['add'] = array(
    '#type' => 'button',
    '#value' => 'Add',
    '#ahah' => array(
      'event' => 'click',
      'path' => "example/ahah/add_option",
      'wrapper' => "example-select-wrapper",
      'method' => 'replace',
    ),

  );

  // A textfield which allows the user to enter in new select options.
  $form['new_option'] = array(
    '#type' => 'textfield',
    '#title' => t('New Option Name'),
  );

  // Submit button to actually save the form data.
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Save',
  );

  return $form;
}

Create a menu path which links to your menu handler.

function hook_menu() {
  $path['example/ahah/add_option'] = array(
    'page callback' => 'example_ahah_add_option_js',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  return $path;
}

And now for the handler.

function example_ahah_add_option_js() {
  // Retrieve the cached form
  $form_state = array('submitted' => FALSE);
  $form_build_id = $_POST['form_build_id'];
  $form = form_get_cache($form_build_id, $form_state);
  // -----
  // You can modify the form here to append new options
  $new_option = $_POST['new_option'];
  $options = $form['example_dropdown']['#options'];
  if (!empty($new_option)) {
    // If the key isnt important to you, just use this line.
    // $form['example_dropdown']['#options'][] = $new_option;
    // I use "Array + Array" here as it maintains the keys if necessary.
    // array_merge() does not maintain the keys.
    $form['example_dropdown']['#options'] = $options + array($new_option);
  }
  // End editable code
  // -----
  // Reset the cached form. Without doing this, Drupal will think this
  // is an externally modified form attack and ignore the data.
  form_set_cache($form_build_id, $form, $form_state);
  $form += array('#post' => $_POST, '#programmed' => FALSE);
  $form = form_builder($_POST['form_id'], $form, $form_state);
  // -----
  // Now we should render only the part of the form we wish to update.
  // This will provide the output to place into the wrapper.
  drupal_json(array(
    'status'   => TRUE,
    'data'     => theme('status_messages') . drupal_render($form['example_dropdown']),
  ));
}

Now the form should append a new option, only if text is entered into the textfield. For more options for the #ahah attribute (such as events, effects or progress bars), see the documentation.

[ Sources ]

  • Drupal Documentation for #ahah
    You've probably seen this already, but a good place to start when getting an brief overview.
  • Getting going with AHAH and Drupal 6
    This has nice flowcharts and describes (with images) what the #ahah options are.
  • Drupal 6 AHAH forms: Making New Fields Work
    A bare bones code snippet which works and offers some light explanation. It is a good idea to wrap the reusable code fragments into a new function as he did. Would probably better to rename $form in easy_ahah_form_field() to $field.

    My tutorial is based upon this code fragment, which ignores step #5 (the submit handler step) in the link below.
  • Doing AHAH Correctly in Drupal 6
    Detailed description of how the process works. This is not noob friendly and will hurt your brain.
 
Copyright © Twig's Tech Tips
Theme by BloggerThemes & TopWPThemes Sponsored by iBlogtoBlog