Creating Auto Submitting Forms with Drupal's Form API

If you are unfamiliar with building forms in Drupal, please view Patrick’s post on the various options for building forms in Drupal.

I will be focusing on forms built with Drupal’s Form API (or fapi).

My use case was a semi-typical one: have the input from one select list affect the options in another select list. Here is my wireframe: [insert wireframe here]

This could be done in any number of ways including:

  • ahah (or ajax)
  • I could have javascript limit the options after selection without a server call
  • Or, I could reload the page after the first selection is made

I chose to reload the page after the first choice was made.

Drupal has a built in handler for ajax like behavior in its form api aptly named “#ajax”. Using the ajax element in the Drupal’s form api looks like this:

$form['form_element'] = array(
  '#type' => 'submit',
  ‘#value' => t('Submit'),
  ‘#ajax' => array(
    'callback' => 'callback_function',
    'method' => 'replace',
    'effect' => 'fade',
  ),
);

It is pretty verbose, requires a php callback, and can be a bit of overkill for auto-submitting a form. In the days of pure HTML forms, we would simply add the form submit straight to the form input. As it turns out we can do the same thing to our form by exploiting the fact that the form API uses render arrays. All we have to do is attach this code snipit to our form element.

'#attributes' => array('onChange' => 'document.getElementById("people-filter-form").submit();')

Notice what is happening here. We are adding attributes to the form element. This is the same way that we would attach classes, only this time we are adding the attribute onChange='<some js to execute>'.

Below is the full form definition.

/**
 * Custom Report User Filter Form
 */
function people_filter_form($form, &$form_state) {
  $form['person'] = array(
    '#type' => 'select',
    '#options' => array(
      '' => 'Select a Person',
    ),
    '#default_value' => empty($_GET['person']) ? '' : check_plain($_GET['person']),
    '#attributes' => array('onChange' => 'document.getElementById("iris-app-people-filter-form").submit();'),
  );
  $people = _get_select_list_data('person');
  foreach ($people as $person) {
    $form['person']['#options'][$person->uid] =  $person->name;
  }
 
  $form['submit'] = array(
    '#type' => 'submit',
    '#value' => 'Search People',
  );
 
  return $form;
}