เป็นไปได้หรือไม่ที่จะแทนที่องค์ประกอบแบบฟอร์มมากกว่าหนึ่งรายการ (wrappers) ที่ถูกทริกเกอร์โดยองค์ประกอบการเรียกใช้ #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">?

คำตอบ:


73

แทนที่จะส่งคืน HTML ขององค์ประกอบเดียวเพื่ออัปเดต ajax callback ของคุณสามารถส่งคืนอาร์เรย์ของคำสั่ง ajaxได้ ดังนั้นมันสามารถส่งคืน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

เงินรางวัลกำลังจะมาในแบบของคุณใน 24 ชั่วโมง
AyeshK

จำเป็นต้องเปลี่ยนชื่อฟังก์ชั่นการโทรกลับ การใช้ฟังก์ชัน ajax_example_simplest_callback (& ​​$ ฟอร์ม, $ form_state) {} ทำให้หน้าจอขาวแห่งความตาย
Ghoti

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

หนึ่ง diffrence คือคำสั่ง render ถูกดร็อปเนื่องจาก AjaxResponse ใช้ Drupal \ Core \ Render \ AttachmentsInterface

แสดงผล ($ form ['element_to_be_replaced_1'])

การเพิ่มการแสดงผลยังคงใช้ได้ แต่ฉันมีปัญหาเมื่ออัปเดต TableSelect Table ด้วยวิธีดังกล่าว


ขอบคุณมันได้ผล ฉันคิดว่าคงไม่เป็นการดีถ้าจะใช้ render () เพราะเอกสารประกอบของ Drupal กล่าวว่าเอกสารนี้มีเนื้อหาไม่น่าเชื่อถือและใช้ได้ใน 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 คุณควรใช้คุณสมบัติ 'ส่งโทรกลับ' ซึ่งจะสั่งให้ Drupal แสดงผลการโทรกลับของหน้าเว็บเป็นคำสั่ง AJAX แทนมาร์กอัป แต่เมื่อใช้โดยตรงในการเรียกกลับหน้าเว็บของคุณคุณจะข้ามการส่งหน้า Drupal ปกติ
Pierre Buyle
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.