55
function ajax_example_simplest($form, &$form_state) {

  //This is my ajax trigger element
  $form['element_trigger'] = array(
    '#type' => 'select',
    '#options' => array(
      'one' => 'one',
      'two' => 'two',
      'three' => 'three',
    ),
    '#ajax' => array(
      'callback' => 'ajax_example_simplest_callback',

      /** Q: Can I somehow declare more than one wrapper? **/
      //Say for instance, something like:
      'wrapper' => array('replace_div_1', 'replace_div_2'),

     ),
  );

  //replace_div_1
  $form['element_to_be_replaced_1'] = array(
    '#type' => 'textfield',
    '#title' => t("My conditional field one"),
    '#prefix' => '<div id="replace_div_1">',
    '#suffix' => '</div>',
  );


 //... more form elements here

  //replace_div_2
  $form['element_to_be_replaced_2'] = array(
    '#type' => 'textfield',
    '#title' => t("My conditional field two"),
    '#prefix' => '<div id="replace_div_2">',
    '#suffix' => '</div>',
  );
  return $form;
}

function ajax_example_simplest_callback($form, $form_state) {

  //... do my stuff here


  //normally I would return only the form bit for replacing a single wrapper
  //declared in the trigger element, like this:
  return $form['element_to_be_replaced_blahblah'];

}

Is it possible to return more than one form bit in the callback function telling the AJAX framework that $form['element_to_be_replaced_1'] should replace <div id="replace_div_1"> and $form['element_to_be_replaced_2'] should replace <div id="replace_div_2">?

3 Answers 3

75
+50

Instead of returning the HTML of the single element to update, your ajax callback can return an array of ajax commands. So it can return two ajax_command_replace to replace each element.

function ajax_example_simplest_callback(&$form, $form_state) {
  return array(
    '#type' => 'ajax',
    '#commands' => array(
      ajax_command_replace("#replace_div_1", render($form['element_to_be_replaced_1'])),
      ajax_command_replace("#replace_div_2", render($form['element_to_be_replaced_2']))
    )
  );
}
4
  • 2
    This is awesome one !! Saved a lot of time . Thank you very much :) Commented Dec 21, 2012 at 6:43
  • A bounty is coming on your way in 24 hours.
    – AKS
    Commented Mar 16, 2015 at 22:59
  • Had to change the name of the callback function. Using function ajax_example_simplest_callback(&$form, $form_state) {} gave me the white screen of death.
    – Ghoti
    Commented Jul 26, 2019 at 17:30
  • The above code is replacing text field with just value, not an editable form with field value. How can we achieve that?
    – Suraj
    Commented Jun 16, 2020 at 15:26
6

Drupal 8 alternate syntax

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;

class name extends FormBase{
   function ajax_example_simplest(array $form, FormStateInterface &$form_state) {
       $response = new AjaxResponse();
       $response->addCommand(new ReplaceCommand("#replace_div_1", ($form['element_to_be_replaced_1'])));
       $response->addCommand(new ReplaceCommand("#replace_div_2", ($form['element_to_be_replaced_2'])));
       return $response;
   }
}

One diffrence is that the render command is dropped, because AjaxResponse implements Drupal\Core\Render\AttachmentsInterface

render($form['element_to_be_replaced_1'])

Adding the render still works, but I had problems when updating a TableSelect Table that way.

1
  • Thank you it works. I think it won't be wise to use render() because Drupal documentations says its deplicated and wont be available in Drupal 9 Commented Aug 23, 2017 at 21:10
4

Pierre Buyle's answer did not work for me. However, something like the following worked.

function ajax_example_simplest_callback(&$form, $form_state) {
    $commands = array();
    $commands[] = ajax_command_replace("#replace_div_1", render($form['element_to_be_replaced_1']));
    $commands[] = ajax_command_replace("#replace_div_2", render($form['element_to_be_replaced_2']));
    $page = array('#type' => 'ajax', '#commands' => $commands);
    ajax_deliver($page);
}

Note the call to ajax_deliver(), rather than returning the array of AJAX commands.

1
  • 2
    I guess you are using #ajax['path'] in your form. In that case, in your hook_menu implementation, you should use the 'deliver callback' property, this will instruct Drupal to render your page callback result as AJAX command instead of markup. But using it directly in your page callback, you bypass normal Drupal page delivery. Commented Aug 9, 2012 at 14:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.