52
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">?

migrated from stackoverflow.com Aug 4 '11 at 16:04

This question came from our site for professional and enthusiast programmers.

73
+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']))
    )
  );
}
  • 2
    This is awesome one !! Saved a lot of time . Thank you very much :) – Sandesh Yadav Dec 21 '12 at 6:43
  • A bounty is coming on your way in 24 hours. – AyeshK Mar 16 '15 at 22:59
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.

  • 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. – Pierre Buyle Aug 9 '12 at 14:27
3

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.

  • 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 – Ngatia Frankline Aug 23 '17 at 21:10

Your Answer

By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.

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