ฉันมีเอนทิตีฟิลด์ที่มีฟิลด์อ้างอิงไปยังย่อหน้า field_paragraphs
และย่อหน้า _type พร้อมช่องอ้างอิงไปยังเหตุการณ์ content_type field_events
.
สิ่งที่ฉันพยายามในฟอร์มเอนทิตีคือการมีปุ่มในฟอร์มย่อยของเหตุการณ์ paragraph_type ซึ่งเมื่อคลิกเติมล่วงหน้า field_events
ของparagraph_typeที่มีเนื้อหา การแสดงแบบฟอร์มของ field_events
ใช้ entity_browser เพื่อให้ผู้ใช้เลือกหรือยกเลิกการเลือกเหตุการณ์ที่เพิ่มโดยทางโปรแกรมด้วยตนเอง และฉันเดาว่านี่คือจุดที่ฉันติดอยู่
ฉันคิดว่าฉันเกือบจะได้คำตอบแล้ว ให้ฉันลองอธิบาย:
เมื่อคลิกปุ่ม เหตุการณ์ที่เพิ่มจะไม่ปรากฏ ถ้าฉันใช้เอนทิตี_เบราว์เซอร์ตอนนี้เพื่อแทรกเหตุการณ์ เหตุการณ์ทั้งหมดที่ฉันเพิ่มโดยทางโปรแกรมจะแสดงขึ้น
ดังนั้นฉันจึงต้องบอกเอนทิตี_เบราว์เซอร์ในการโทรกลับของฉันเพื่อส่งคืนรายการที่อัปเดต ฉันเดาว่า (ฉันเป็นมือใหม่หัดใช้ Drupal ดังนั้นโปรดดำเนินการตามสบาย) แต่ฉันไม่มีเงื่อนงำว่าต้องทำอย่างไร และฉันคิดว่ามันควรจะเป็นไปได้ โดยไม่ต้องทำเช่นนั้น? ฉันหมายถึงแค่เพิ่มการอ้างอิงและปล่อยให้ "ฟอร์มสร้างใหม่โดยไม่ขึ้นกับการแสดงฟอร์ม" ... ฉันไม่รู้ว่านี่คือรหัสจนถึงตอนนี้:
/**
* ใช้ hook_field_widget_WIDGET_TYPE_form_alter()
*/
ฟังก์ชัน module_field_widget_paragraphs_form_alter(&$องค์ประกอบ, &$form_state, $บริบท) {
สวิตช์ ($ element['#paragraph_type']) {
กรณี 'เหตุการณ์':
$replace_id = $element['subform']['field_events']['widget']['#id'];
$องค์ประกอบ["แบบฟอร์มย่อย"]['add_tomorrows_events_button'] = [
'#type' => 'ปุ่ม',
'#attributes' => [
'ชื่อ' => 'add_tomorrows_events',
]
'#value' => t('เพิ่มกิจกรรมวันพรุ่งนี้'),
'#อาแจ็กซ์' => [
'callback' => 'module_insert_tomorrows_events_into_paragraph_events',
'wrapper' => $replace_id,
'วิธีการ' => 'แทนที่',
'เหตุการณ์' => 'คลิก',
]
];
หยุดพัก;
ค่าเริ่มต้น:
// รหัส...
หยุดพัก;
}
}
/**
* โทรกลับ Ajax
*/
ฟังก์ชัน module_insert_tomorrows_events_into_paragraph_events ( &$form, FormStateInterface &$form_state) {
/* รับดัชนีของย่อหน้าใน field_paragraphs */
$triggering_element = $form_state->getTriggeringElement();
$paragraph_index = $triggering_element["#parents"][1];
/* สำหรับตอนนี้ ลองเพิ่ม 10 เหตุการณ์ */
$results = \Drupal::entityQuery('โหนด')
->เงื่อนไข('ประเภท', 'เหตุการณ์')
-> ช่วง (0, 10)
->ดำเนินการ ();
/* ที่นี่ฉันกำลังพยายามสร้างสตริงเหมือนที่อยู่ในคีย์ target_id ของวิดเจ็ต
เช่น "node:3213 node:54354 node:432423"
*/
$target_ids = "";
foreach (ผลลัพธ์ $ เป็น $res) {
$target_ids .= " โหนด:".$res;
}
$form["field_paragraphs"]['widget'][$paragraph_index]["subform"]["field_events"]["widget"]["target_id"]['#value'] = $target_ids;
/* แค่อย่างอื่นที่ฉันลอง */
/*$form["field_paragraphs"]['widget'][$paragraph_index]["subform"]["field_events"]["widget"]["target_id"]['#default_value'] = $target_ids;*/
/* $form_state->setValue(['field_paragraphs', $paragraph_index, 'subform', 'field_events', 'target_id'], $target_ids);
$form_state->setRebuild(จริง);
*/
/* พยายามอัปเดต EB แต่ "ปัจจุบัน" ไม่อัปเดต :/
$t = EntityReferenceBrowserWidget::updateWidgetCallback($form, $form_state);
ส่งคืน $t["field_paragraphs"]["widget"][$paragraph_index]["subform"]["field_events"]["widget"];
*/
ส่งคืน $form["field_paragraphs"]['widget'][$paragraph_index]["subform"]["field_events"]["widget"];
}
TL; DR: เหตุการณ์ถูกเพิ่ม แต่เอนทิตี_ฟอร์ม/เอนทิตี_เบราว์เซอร์ไม่ได้รับการอัปเดตเป็นภาพ หลังจากใช้เอนทิตี_เบราว์เซอร์ เหตุการณ์ที่เพิ่มโดยทางโปรแกรมทั้งหมดจะแสดงขึ้น จะแสดงได้อย่างไรตั้งแต่แรก