Ist es möglich, mehr als ein Formularelement (Wrapper) zu ersetzen, das von nur einem #ajax-Triggerelement ausgelöst wird?

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'];

}

Ist es möglich, mehr als ein Formularbit in der Rückruffunktion zurückzugeben, um dem AJAX-Framework mitzuteilen, welches ersetzt $form['element_to_be_replaced_1']werden soll <div id="replace_div_1">und welches ersetzt $form['element_to_be_replaced_2']werden soll <div id="replace_div_2">?

Francisco Luz
quelle

Antworten:

73

Anstatt den HTML-Code des einzelnen zu aktualisierenden Elements zurückzugeben, kann Ihr Ajax-Rückruf ein Array von Ajax-Befehlen zurückgeben . Es können also zwei ajax_command_replace zurückgegeben werden , um jedes Element zu ersetzen.

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']))
    )
  );
}
Pierre Buyle
quelle
2
Das ist großartig !! Viel Zeit gespart. Vielen Dank :)
Sandesh Yadav
In 24 Stunden kommt ein Kopfgeld auf Ihren Weg.
AyeshK
Musste den Namen der Rückruffunktion ändern. Mit der Funktion ajax_example_simplest_callback (& ​​$ form, $ form_state) {} habe ich den weißen Bildschirm des Todes erhalten.
Ghoti
5

Alternative Drupal 8-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;
   }
}

Ein Unterschied besteht darin, dass der Renderbefehl gelöscht wird, da AjaxResponse Drupal \ Core \ Render implementiert \ AttachmentsInterface

machen ($ form ['element_to_be_replaced_1'])

Das Hinzufügen des Renderings funktioniert immer noch, aber ich hatte Probleme beim Aktualisieren einer TableSelect-Tabelle auf diese Weise.

Johann
quelle
Danke, es funktioniert. Ich denke, es wird nicht ratsam sein, render () zu verwenden, da Drupal-Dokumentationen besagen, dass es veraltet ist und in Drupal 9
Ngatia Frankline
4

Pierre Buyles Antwort hat bei mir nicht funktioniert. Etwas wie das Folgende funktionierte jedoch.

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);
}

Beachten Sie den Aufruf von ajax_deliver () , anstatt das Array von AJAX-Befehlen zurückzugeben.

Kojote
quelle
2
Ich nehme an, Sie verwenden in Ihrem Formular #ajax ['path']. In diesem Fall sollten Sie in Ihrer Implementierung von hook_menu die Eigenschaft 'Rückruf zustellen' verwenden. Dadurch wird Drupal angewiesen, das Ergebnis Ihres Seitenrückrufs als AJAX-Befehl anstatt als Markup zu rendern. Wenn Sie es jedoch direkt in Ihrem Seitenrückruf verwenden, umgehen Sie die normale Drupal-Seitenübermittlung.
Pierre Buyle