การป้อนอัตโนมัติโดยใช้ฟิลด์อื่น


10

ฉันมีสถานการณ์ที่ซับซ้อนมากซึ่งฉันต้องการคำแนะนำ ฉันมีชนิดเนื้อหาmy_contentซึ่งมีข้อมูลการเก็บรวบรวมข้อมูลที่แนบมากับมันfield_mycollectionซึ่งมีข้อมูลอ้างอิงนิติบุคคลอ้างอิงให้กับผู้ใช้field_my_userreferenceข้อมูลโทรศัพท์field_my_phone, ช่องข้อความและข้อมูลข้อความอื่นfield_my_textfield_my_anothertext

My Content
|_ field_mycollection
   |_ field_my_userreference
   |_ field_my_phone
   |_ field_my_text
   |_ field_my_anothertext

นิติบุคคลผู้ใช้ยังมีสาขาfield_my_phone, field_my_textและfield_my_yetanothertextที่หลังมีชื่อเครื่องที่แตกต่างกัน

สิ่งที่ฉันต้องการจะทำถ้าในmy_contentรูปแบบการแก้ไข / เพิ่มในfield_my_userreferenceผู้ใช้มีการเลือกเขตข้อมูลอื่น ๆ ควรจะเติมอัตโนมัติจากข้อมูลของผู้ใช้ที่เลือก ฟิลด์ที่เติมอัตโนมัติควรยังคงสามารถแก้ไขได้

ฉันจะบรรลุเป้าหมายนี้ได้อย่างไร hook_form_FORM_ID_alter()ฉันต้องการที่จะทำมันถ้าเป็นไปได้กับบางการเข้ารหัสโดยใช้


คุณต้องการให้มันเกิดขึ้นในแบบฟอร์มหรือบันทึก?
Mołot

สดในแบบฟอร์ม ฉันได้ดำเนินการไปแล้วว่าเมื่อบันทึกข้อมูลจะถูกนำมาจากเอนทิตีผู้ใช้ถ้าปล่อยว่างไว้ แต่จริงๆแล้วสิ่งที่ฉันต้องการในแบบฟอร์ม :(
Елин Й.

ตกลงโพสต์คำตอบของฉัน
Mołot

คำตอบ:


11

หากคุณต้องการให้มันเกิดขึ้นจริงและฟิลด์ทั้งหมดอยู่ในแบบฟอร์มแล้ววิธีที่ปลอดภัยที่สุดคือการใช้hook_form_FORM_ID_alter()เพื่อเพิ่มการติดตามในแบบฟอร์ม:

$form['#attached']['js'] = array(
  drupal_get_path('module', 'module_name') . '/js/copy_field_value.js',
);

จากนั้นในการcopy_field_value.jsสร้างพฤติกรรม:

(function($) {
  Drupal.behaviors.moduleNameCopyFieldValue = {
    attach: function (context, settings) {

      // Repeat this for all fields as needed
      $('#source', context).on('blur', function () { 
        // above you can use change instead of blur if element is not changed by another js
        if (!$('#destination').val() || 0 === $('#destination').val().length) {
          $('#destination').val($(this).val());
          // wrap line above in "if no value" like I did, or other condition you like
        }
      });
      // end of "repeat this"
    }
  };
})(jQuery);

คุณยังสามารถใช้hook_form_FORM_ID_alter()เพื่อเพิ่ม#ajaxพารามิเตอร์ลงในเขตข้อมูลต้นทาง แต่มันจะทำให้แบบฟอร์มของคุณโทรไปยังเซิร์ฟเวอร์ในการคัดลอกแต่ละเขตข้อมูล หากคุณต้องการสืบค้นฐานข้อมูลจริงมันเป็นวิธีที่จะไป มันจะค่อนข้างกว้างที่จะอธิบายอีกครั้งที่นี่ คุณต้องแก้ไข$form_state["input"]อาร์เรย์เพื่ออัปเดตค่าจริงที่ผู้ใช้เห็น ทำได้ในฟังก์ชั่นการสร้างแบบฟอร์มห่อด้วยissetเพื่อหลีกเลี่ยงการแจ้งเตือน

หากองค์ประกอบฟอร์มของคุณเป็น$form["something"]["something"]["element"]ค่าของมันจะอยู่ใน$form_state["input"]["something"]["something"]["element"]- และคุณสามารถตั้งค่าได้hook_form_alterทุกอย่างเพียงจำไว้ว่าต้องใช้ทั้งสอง$formและ$form_stateโดยการอ้างอิง

หมายเหตุ : .on()วิธีการถูกเพิ่มเข้ามาใน jQuery 1.7 ดังนั้นคุณจะต้องมีjQuery Updateเพื่อใช้คำตอบนี้โดยตรงหรือแปลรหัสของฉันเพื่อใช้.change()หรือ.blur()วิธีการ


ขอบคุณมากสำหรับคำแนะนำ! ฉันไม่ค่อยดีกับ JS API ของ Drupal คุณจะอธิบายว่าฉันจะรับค่าฟิลด์จากเอนทิตีผู้ใช้ได้อย่างไร ตัวอย่างเช่นหากเลือกผู้ใช้ฉันจะเติมฟิลด์ต่อไปด้วยข้อมูลผู้ใช้นี้ได้อย่างไร
ЕлинЙ

1
@ ЕлинЙ เคล็ดลับที่นี่ไม่สนใจพื้นหลัง PHP เพียงระบุพารามิเตอร์ ID ของ<input>แท็กโดยใช้ Firebug หรือเครื่องมือที่คล้ายกันสำหรับเบราว์เซอร์ที่คุณชื่นชอบ หรือใช้ตัวเลือก jQuery อื่น ๆ มันจะเกิดขึ้นในเบราว์เซอร์เท่านั้นดังนั้นคุณมีสิ่งที่คุณมีบนหน้าจอ ในทางกลับกันถ้าคุณต้องการสืบค้นฐานข้อมูลจริง ๆ (ดูเหมือนว่าฉันพลาดไปแล้ว) #ajaxเป็นวิธีที่จะไป แต่มันจะค่อนข้างกว้าง คุณต้องแก้ไข$form_state["values"]อาร์เรย์เพื่ออัปเดตค่าจริงที่ผู้ใช้เห็น ทำได้ในฟังก์ชั่นการสร้างแบบฟอร์มห่อด้วยissetเพื่อหลีกเลี่ยงการแจ้งเตือน
Mołot

ขอบคุณอีกครั้ง @ Mołotฉันจะพยายามนำไปใช้ในวันพรุ่งนี้หรืออาจจะเย็นนี้ ดูเหมือนว่าฉันจะต้องใช้เวลาสองสามชั่วโมงเพื่อให้มันได้ผลจริงถ้าไม่มาก
ЕлинЙ

@ ЕлинЙ โชคดีอย่าลังเลที่จะกลับมาพร้อมคำถามเพิ่มเติมและเชื่อมโยงพวกเขาที่นี่ในความคิดเห็นหากพวกเขาเชื่อมต่อ อัปเดตตอบเล็กน้อย btw
Mołot

1
ตกลงฉันจะทดลองสักหน่อยแล้วฉันจะเขียนประสบการณ์ของฉัน
ЕлинЙ

4

คุณสามารถทำได้โดยใช้โมดูลฟิลด์ที่คำนวณ

Computed Field เป็นโมดูลฟิลด์ CCK ที่ทรงพลังมากซึ่งช่วยให้คุณเพิ่ม "ฟิลด์คำนวณ" ที่กำหนดเองให้กับประเภทเนื้อหาของคุณ เขตข้อมูลจากการคำนวณเหล่านี้บรรจุด้วยค่าที่คุณกำหนดผ่านรหัส PHP คุณสามารถวาดสิ่งที่มีให้ Drupal รวมถึงฟิลด์อื่น ๆ ผู้ใช้ปัจจุบันตารางฐานข้อมูลคุณตั้งชื่อมัน (รู้สึกถึงพลังหรือไม่ :)) คุณยังสามารถเลือกได้ว่าจะเก็บค่าฟิลด์ที่คำนวณของคุณในฐานข้อมูลด้วยฟิลด์เนื้อหาอื่น ๆ หรือให้พวกเขา "คำนวณ" ได้ทันทีในระหว่างมุมมองโหนด (แม้ว่าคุณควรทราบว่าการใช้ Views ต้องใช้ค่าฐานข้อมูลที่เก็บไว้) ฟิลด์นี้เป็นดาบของกองทัพบกสวิสแห่ง CCK ดังนั้นเริ่มทำค่า PHP ตามของคุณ!


ขอบคุณสำหรับการตอบสนองอย่างรวดเร็ว. มันฟังดูมีแนวโน้มมาก แม้ว่าฉันไม่ต้องการติดตั้งโมดูลสำหรับที่ แต่เพียงเขียนรหัสเพราะฉันต้องการฟังก์ชั่นดังกล่าวเฉพาะในรูปแบบนั้นและระบบจริงมีขนาดใหญ่เกินไปและโมดูลจำนวนมากติดตั้งสำหรับฟังก์ชั่นที่หลากหลาย
ЕлинЙ

ประการที่สองเป็นไปได้หรือไม่ที่จะใช้โมดูลนี้สำหรับผู้ใช้ที่สร้างหรือแก้ไขโหนดเพื่อแทนที่ฟิลด์ที่มีการเติมข้อมูลอัตโนมัติด้วยตนเองและบันทึก? ดังนั้นในเอนทิตีผู้ใช้และ my_content จะมีการบันทึกค่าต่างกัน
ЕлинЙ

ซึ่งจะขึ้นอยู่กับวิธีการติดตั้ง
4life

ขอบคุณ @ 4life ฉันจะลองดูถ้าฉันไม่สามารถทำได้ด้วยการเข้ารหัสโดยใช้คำแนะนำของMołot
ЕлинЙ

2

ฉันต้องการโพสต์ว่าฉันประสบความสำเร็จได้อย่างไรด้วยความช่วยเหลือที่ยอดเยี่ยมของ @ Mołot

  1. ดำเนินการhook_form_FORM_ID_alter ()
  2. เพิ่ม div การล้อมรอบคอลเลกชันฟิลด์
  3. ตั้งแต่การเก็บรวบรวมข้อมูลของฉันเป็นสนามหลายค่าซ้ำมากกว่านั้นและตั้งค่าคุณสมบัติสำหรับสนาม#ajaxfield_my_userreference
  4. สร้างฟังก์ชั่นการโทรกลับซึ่งเพียงแค่คืนค่ารายการการรวบรวมฟิลด์กลับ
  5. เช็คอินในการนำไปใช้งาน hook_form_FORM_ID_alter () หากมีการตั้งค่า $ form_state สำหรับการรวบรวมฟิลด์ ถ้าใช่รับค่าจากเอนทิตีผู้ใช้และเติมฟิลด์อินพุตแบบฟอร์มด้วยค่าเหล่านั้น

รหัสของฉันดูเหมือนว่า:

function MYMODULE_form_my_content_node_form_alter(&$form, &$form_state, $form_id) {
  $form['field_mycollection']['#prefix'] = '<div id="mycollection-wrapper">';
  $form['field_mycollection']['#suffix'] = '</div>';
  foreach ($form['field_mycollection']['und'] as $key => $fc_mycollection) {
    if (is_numeric($key)) {
      $form['field_mycollection']['und'][$key]['field_my_userreference']['und']['#ajax'] = array(
        'callback' => 'MYMODULE_mycollection_callback',
        'wrapper' => 'mycollection-wrapper',
      );
      if (isset($form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id'])) {
        $user_wrapper = entity_metadata_wrapper('user', $form_state['values']['field_mycollection']['und'][$key]['field_my_userreference']['und'][0]['target_id']);
        $form_state['input']['field_mycollection']['und'][$key]['field_my_text']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_text->value() : '';
        $form_state['input']['field_mycollection']['und'][$key]['field_my_anothertext']['und'][0]['value'] = $user_wrapper->field_my_text->value() ? $user_wrapper->field_my_yetanothertext->value() : '';
      }
    }
  }
}

function MYMODULE_mycollection_callback($form, &$form_state) {
  return $form['field_mycollection'];
}

โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.