是否可以替换仅由一个#ajax触发元素触发的多个表单元素(包装器)?


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

}

是否有可能在回调函数中返回一个以上的表单位,以告知AJAX框架$form['element_to_be_replaced_1']应该替换<div id="replace_div_1">$form['element_to_be_replaced_2']应该替换<div id="replace_div_2">

Answers:


73

您的ajax回调可以返回ajax命令数组,而不是返回要更新的单个元素的HTML 。因此它可以返回两个ajax_command_replace来替换每个元素。

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
这真棒!节省了很多时间。非常感谢您:)
Sandesh Yadav 2012年

24小时内您将获得赏金。
AyeshK 2015年

不得不更改回调函数的名称。使用函数ajax_example_simplest_callback(&$ form,$ form_state){}给了我死亡的白屏。
哥提

5

Drupal 8备用语法

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

一个区别是渲染命令被删除了,因为AjaxResponse实现了Drupal \ Core \ Render \ AttachmentsInterface

渲染($ form ['element_to_be_replaced_1'])

添加渲染仍然可行,但是以这种方式更新TableSelect Table时出现问题。


谢谢你的工作。我认为它不会是明智的使用渲染(),因为Drupal的单证称,其deplicated并不会在Drupal 9可用
Ngatia Frankline

4

Pierre Buyle的答案对我不起作用。但是,类似以下的方法起作用。

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

请注意对ajax_deliver()的调用,而不是返回AJAX命令的数组。


2
我猜您在表单中使用#ajax ['path']。在这种情况下,在hook_menu实现中,应该使用'deliver callback'属性,这将指示Drupal将页面回调结果呈现为AJAX命令而不是标记。但是直接在页面回调中使用它,就可以绕开正常的Drupal页面传递。
皮埃尔·布伊
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.