ขอขอบคุณ มิสเตอร์ดีดี้ ที่ทำให้ฉันเดินถูกทาง
บทความที่คุณให้ไว้ช่วยได้ แต่เพื่อที่จะหาทางออก ฉันต้องศึกษาอีกสองสามสิบเรื่อง และในที่สุดทางออกก็มาถึง
ดังนั้นสำหรับงานนี้ ทางออกเดียวที่ฉันพบคือ:
- อ่านสิ่งที่อยู่ใน "ตัวกรองวิทยุ"
- แก้ไข "ตัวกรองช่องทำเครื่องหมาย" เพื่อให้มีค่าจาก "ตัวกรองวิทยุ" ในทุกตัวเลือก
- รวม "ฟิลด์สถานะ" ทั้งหมดลงในฟิลด์ที่มีหลายค่าหนึ่งฟิลด์ เพื่อให้เราสามารถ...
- ใช้ตัวกรองตามบริบทเพื่ออ่านค่า "ตัวกรองช่องทำเครื่องหมาย" จาก URL และค้นหาค่านั้นในฟิลด์หลายค่าของเรา
1. การอ่านค่าจาก Radio filter
ฉันทำสิ่งนี้สำเร็จด้วย views_pre_view ตะขอ:
ฟังก์ชัน MY_MODULE_views_pre_view($view, $display_id, array &$args) {
// ตรวจสอบว่าเป็นมุมมองและโหมดการแสดงผลที่ถูกต้องหรือไม่
ถ้า ($view->id() == 'MY_VIEW') {
สวิตช์ ($display_id) {
กรณี 'MY_DISPLAY':
// รับค่าใด ๆ ที่อยู่ใน Radio Filter และเขียนลงในตัวแปรส่วนกลาง
$filter_input = $view->getExposedInput();
ทั่วโลก $arg;
$arg= $filter_input['RADIO_FILTER'];
}
}
}
(ในที่นี้และข้างหน้า ทุกอย่างใน CAPS คือชื่อที่คุณต้องแทนที่ด้วยชื่อที่คุณใช้)
ด้วยโค้ดนี้ ฉันอ่านสิ่งที่อยู่ใน Radio Filter และใส่ลงในตัวแปรส่วนกลาง $ หาเรื่อง.
2. ใส่ค่าจาก Radio Filter ลงใน Checkbox Filter
สำหรับส่วนนี้ฉันใช้ form_views_exposed_form_alter ตะขอ:
ฟังก์ชัน MY_MODULE_form_views_exposed_form_alter(&$form, $form_state, $form_id) {
// เรียกตัวแปรส่วนกลางด้วยค่า Radio Filter
ทั่วโลก $arg;
// แปลงค่า RAW ของ Radio Filter เป็นสิ่งที่เราสามารถใช้สำหรับตัวกรองตามบริบท
ถ้า ($arg == '1') {
$arg= 'เอซี';
}
อื่น ($arg == '2') {
$arg= 'ฮีตเตอร์';
}
อื่น ($arg == 'ทั้งหมด') {
$arg= '';
}
$arg_on = ($arg . '_on');
$arg_off = ($arg . '_off');
// ตรวจสอบว่าเป็นรูปแบบที่ถูกต้อง
ถ้า ($form['#id'] == 'EXPOSED_FILTER_FORM_ID') {
// เราต้องการค่าตัวกรองที่แตกต่างกัน ขึ้นอยู่กับว่าค่าใน Radio Filter ถูกเลือกหรือตั้งค่าเป็นค่าเริ่มต้น ("ทั้งหมด")
ถ้า ($arg != '') {
$form['CHECKBOX_FILTER']['#options'] = อาร์เรย์(
$arg_on => $arg_on,
$arg_off => $arg_off,
);
}
อื่น {
$form['CHECKBOX_FILTER']['#options'] = อาร์เรย์(
'_on' => '_on',
'_off' => '_off', );
}
// ถ้าไม่มีอะไรถูกเลือก เราควรพิจารณาทุกอย่างที่เลือก
ถ้า ($form['CHECKBOX_FILTER']['#value'] == '') {
$form['CHECKBOX_FILTER']['#value'] = [$arg_on, $arg_off];
}
}
}
วิธีนี้จะทำให้ฉันแก้ไขค่าใน Checkbox Filter การทำเช่นนี้ทำให้ใช้งานไม่ได้มากเหมือนตัวกรองที่เปิดเผย (ฉันไม่แน่ใจว่าทำไม แต่ช่วงเวลาที่แก้ไขแบบฟอร์มผ่าน hook - มันไม่ได้กรองอะไรอีกต่อไป) แต่มีพารามิเตอร์ URL ซึ่งเราจะใช้สำหรับตัวกรองตามบริบท .
3. การรวมช่องพารามิเตอร์ทั้งหมดเป็นช่องเดียว
อันนี้เป็นสิ่งที่ฉันคาดว่าจะหาโมดูลได้ แต่ล้มเหลว ดังนั้น hook_entity_presave มันคือ.
ฟังก์ชัน MY_MODULE_entity_presave (Drupal\Core\Entity\EntityInterface $entity) {
// ที่นี่เราเตรียมตัวแปรสำหรับทุกฟิลด์ที่เราจะต้องผสาน ...
ถ้า ($entity->bundle() == 'MY_NODE_TYPE') {
$par_ac = ($entity->field_AC_CHECK->value);
$par_heater = ($entity->field_HEATER_CHECK->value);
$par_all = ($par_ac . ',' . $par_heater);
// ... และดูว่ามี "เปิด" หรือ "ปิด" อยู่หรือไม่ ...
ถ้า (str_contains($par_all, 'เปิด')) {
$par_cont_on = '_on';
}
ถ้า (str_contains($par_all, 'ปิด')) {
$par_cont_off = '_off';
}
// ... เพื่อรวมทั้งหมดลงในฟิลด์เดียว และระบุค่า "เปิด" และ "ปิด" โดยรวมสำหรับกรณีที่ไม่ได้เติม Radio Filter
$entity->field_par_comb = [$par_ac, $par_heater, $par_cont_on, $par_cont_off];
}
}
ฉันไม่พอใจกับข้อเท็จจริงที่ว่าฟิลด์ถูกฮาร์ดโค้ดและไม่ได้รวบรวมแบบไดนามิก บางทีฉันอาจจะคิดหาวิธียกเลิกการฮาร์ดโค้ดเหล่านี้ในภายหลัง
แต่สำหรับตอนนี้ เรามีฟิลด์หลายค่าที่มีสถานะสำหรับทุกพารามิเตอร์ และในที่สุดเราก็สามารถ...
4. ใช้ตัวกรองตามบริบท
ตามที่เราพบในหน้า 2 ตัวกรองช่องทำเครื่องหมายที่เปิดเผยจะไม่ทำอะไรเลยเมื่อมีการแก้ไข แต่เราสามารถตรวจสอบพารามิเตอร์ URL ของตัวกรองช่องทำเครื่องหมายได้ ด้วยวิธีนี้ หากเรามี "checkbox_filter=heater_on" ตัวกรองตามบริบทจะดูในช่องที่มีหลายค่าจากหน้า 3 สำหรับค่า "heater_on"
เนื่องจากตัวกรองช่องทำเครื่องหมายสามารถมีค่าได้หลายค่า เราควรเลือก "OR" ร่วมกับค่าในการตั้งค่าของตัวกรอง
โปรดทราบว่าตัวกรองวิทยุควรเป็น "ไม่จำเป็น" เป็นเพราะเมื่อโหลดมุมมองเป็นครั้งแรก ค่าตัวกรองที่เปิดเผยเริ่มต้นจะไม่แสดงในพารามิเตอร์ URL ด้วยเหตุผลบางประการ แต่เนื่องจากค่า Radio Filter เริ่มต้นคือ "ใดๆ" (และเราควรซ่อนมันด้วย CSS ผ่าน :ลูกคนแรก ตัวเลือก) ในรหัสของเรามีส่วนที่คำนึงถึงกรณีนี้โดยการแทนที่ค่าตัวกรองวิทยุ "ทั้งหมด" ด้วย '' และเนื่องจากเรามีการตรวจสอบพิเศษและค่า "_on"/"_off" ในฟิลด์แบบหลายค่าของเรา จึงทำงานได้ดี:
- หากเลือกค่าเริ่มต้น "ใดๆ" ในตัวกรองวิทยุ รหัสจะไม่แทนที่ค่าตัวกรองช่องทำเครื่องหมาย
- ในการตั้งค่ามุมมอง ค่าตัวกรองช่องทำเครื่องหมายเริ่มต้นจะถูกตั้งค่าเป็น "_on" และ "_off" และตัวกรองสามารถทำงานได้
- เมื่อผู้ใช้เลือก "AC", "Heater" หรือตัวเลือกอื่นๆ ใน Radio Filter ระบบจะใส่ค่านี้ลงในค่าตัวกรองช่องทำเครื่องหมายที่แก้ไขแล้วและตัวกรองตามบริบทจะเริ่มทำงาน
นี่เป็นกรณีที่แย่มากสำหรับประสบการณ์การพัฒนาโมดูล Drupal ครั้งแรก แต่ใช้งานได้อย่างไม่มีที่ติ ลูกค้ามีความสุข ฉันก็มีความสุข