Wednesday 25 July 2012

Form API and AJAX callbacks


Here's a piece of information that's well hidden.

If you're using Drupal's AJAX functionality with forms - but you don't actually want to change the form but instead do other stuff on the page, you may run into trouble because there's something that's not clearly explained about the AJAX callback function in your PHP code.

You know you can add this:

$form['tickbox'] = array(
  '#type' => 'checkbox',
  '#title' => t('Change something on the page'),
  '#ajax' => array(
    'wrapper' => 'id-of-some-div-on-the-page',
    'callback' => 'mymodule_form_ajax_callback',
  ),
);

And when you click the box your function in the PHP gets called:

function mymodule_form_ajax_callback($form, $form_state) {
  return '<div id="">Hello!</div>';
}

Okay that just does a straight replace. But what if you want to append it instead? The documentation says that this function can return AJAX commands instead. So I can do this, right?

function mymodule_form_ajax_callback($form, $form_state) {
  return ajax_command_append(NULL, 'Hello!');
}

Nope. The documentation says I can return an array of commands. So I can do this, right?

function mymodule_form_ajax_callback($form, $form_state) {
  return array(
    ajax_command_prepend(NULL, 'Hello!'),
    ajax_command_append(NULL, 'Goodbye!'),
  );
}

Nope.

The answer is hidden around line 219 of includes/ajax.inc, this will work:

function mymodule_form_ajax_callback($form, $form_state) {
  return array(
    '#type' => 'ajax',
    '#commands => array(
      ajax_command_prepend(NULL, 'Hello!'),
      ajax_command_append(NULL, 'Goodbye!'),
    ),
  );
}

It needs to be a renderable array so this is what works.

No comments: