Bidang pengisian otomatis berdasarkan bidang lain


10

Saya memiliki situasi yang sangat kompleks di mana saya memerlukan nasihat. Saya memiliki tipe konten my_content, yang memiliki bidang koleksi bidang yang menyertainya field_mycollection, yang memiliki bidang referensi entitas yang merujuk ke pengguna field_my_userreference, bidang telepon field_my_phone, bidang teks field_my_text, dan bidang teks lainnya field_my_anothertext.

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

Entitas pengguna juga memiliki bidang field_my_phone, field_my_textdan field_my_yetanothertextyang terakhir memiliki nama mesin yang berbeda.

Apa yang ingin saya lakukan, jika dalam my_contentbentuk edit / tambah, dalam field_my_userreferencepengguna dipilih, bidang lain harus diisi secara otomatis dari data pengguna yang dipilih. Bidang yang diisi otomatis harus tetap dapat diedit.

Bagaimana saya bisa mencapai tujuan ini? Saya ingin melakukannya, jika mungkin, dengan beberapa pengkodean, menggunakan hook_form_FORM_ID_alter().


Apakah Anda perlu itu terjadi langsung di formulir, atau di simpan?
Mołot

Langsung dalam bentuk. Saya sudah menerapkannya pada save, bahwa data akan diambil dari entitas pengguna jika dibiarkan kosong. Tetapi sebenarnya apa yang saya butuhkan di formulir :(
Елин Й.

OK, mengajukan jawaban saya.
Mołot

Jawaban:


11

Jika Anda ingin itu terjadi secara langsung, dan semua bidang sudah ada di formulir, cara teraman adalah hook_form_FORM_ID_alter()dengan menambahkan berikut ke formulir:

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

Kemudian di copy_field_value.jsbuat perilaku:

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

Anda juga dapat menggunakan hook_form_FORM_ID_alter()untuk menambahkan #ajaxparameter ke bidang sumber, tetapi itu akan membuat formulir Anda untuk memanggil server pada setiap salinan bidang. Jika Anda benar-benar perlu query database, itu adalah cara untuk pergi. Akan cukup luas untuk menggambarkannya lagi di sini. Anda perlu mengubah $form_state["input"]array untuk memperbarui nilai nyata yang dilihat oleh pengguna. Lakukan dalam fungsi pembuatan formulir, bungkus dengan issetuntuk menghindari pemberitahuan.

Jika elemen bentuk Anda $form["something"]["something"]["element"], nilainya akan di $form_state["input"]["something"]["something"]["element"]- dan Anda bisa mengaturnya dengan baik hook_form_alter, ingat untuk mengambil keduanya $formdan $form_statedengan referensi.

Catatan : .on()metode ditambahkan di jQuery 1.7, sehingga Anda akan memerlukan Pembaruan jQuery untuk menggunakan jawaban ini secara langsung, atau menerjemahkan kode saya untuk menggunakan .change()atau .blur()metode.


Terima kasih banyak atas instruksinya! Saya tidak begitu baik tentang JS API Drupal. Apakah Anda akan menjelaskan bagaimana saya mendapatkan nilai bidang dari entitas pengguna? Misalnya, jika pengguna dipilih, bagaimana saya bisa mengisi bidang berikutnya dengan info pengguna ini?
Елин Й.

1
@ ЕлинЙ. Kuncinya di sini adalah tidak peduli tentang latar belakang php. Cukup identifikasi parameter ID <input>tag menggunakan Firebug atau alat serupa untuk browser favorit Anda. Atau gunakan pemilih jQuery lainnya. Ini akan terjadi di browser saja, sehingga Anda memiliki apa yang Anda miliki di layar. Di sisi lain jika Anda benar-benar perlu query database (sepertinya saya melewatkan itu), #ajaxadalah cara untuk pergi. Tapi itu akan sangat luas. Anda perlu mengubah $form_state["values"]array untuk memperbarui nilai nyata yang dilihat oleh pengguna. Lakukan dalam fungsi pembuatan formulir, bungkus dengan issetuntuk menghindari pemberitahuan.
Mołot

Terima kasih lagi @ Mołot, saya akan mencoba menerapkannya besok, atau mungkin malam ini. Sepertinya saya perlu beberapa jam untuk membuatnya benar-benar berfungsi, jika tidak lebih.
Елин Й.

@ ЕлинЙ. semoga berhasil, jangan ragu untuk kembali dengan lebih banyak pertanyaan dan tautkan di sini di komentar jika mereka terhubung. Diperbarui, jawab sedikit, btw.
Mołot

1
Ok, saya akan bereksperimen sedikit dan saya akan menulis pengalaman saya.
Елин Й.

4

Anda dapat melakukannya menggunakan modul bidang yang dihitung

Bidang Terkomputasi adalah modul bidang CCK yang sangat kuat yang memungkinkan Anda menambahkan "bidang terkomputasi" khusus ke jenis konten Anda. Bidang yang dihitung ini diisi dengan nilai yang Anda tetapkan melalui kode PHP. Anda dapat menggambar apa pun yang tersedia untuk Drupal, termasuk bidang lain, pengguna saat ini, tabel database, apa saja. (Merasakan kekuatan belum? :)) Anda juga dapat memilih apakah akan menyimpan nilai bidang yang dikomputasi dalam database dengan bidang konten lainnya, atau meminta mereka "menghitung" dengan cepat selama tampilan simpul. (Meskipun Anda harus mencatat bahwa penggunaan Views membutuhkan nilai yang tersimpan di basis data.) Bidang ini secara harfiah merupakan pisau Swiss dari bidang CCK. Jadi mulailah memasak nilai-nilai berbasis PHP Anda!


Terima kasih atas tanggapan cepatnya. Kedengarannya sangat menjanjikan. Meskipun, saya tidak ingin menginstal modul untuk itu tetapi cukup menulis beberapa kode, karena saya hanya membutuhkan fungsi seperti itu pada formulir itu, dan sistem yang sebenarnya sudah terlalu besar dan banyak modul yang diinstal untuk fungsi yang beragam.
Елин Й.

Kedua, apakah mungkin menggunakan modul ini, bagi pengguna yang membuat atau mengedit node untuk menimpa bidang yang diisi secara manual dan menyimpan? Sehingga, di entitas pengguna dan konten my_content disimpan.
Елин Й.

Itu akan tergantung pada cara pengaturannya
4life

Terima kasih @ 4life, saya akan mencobanya juga jika saya tidak dapat mencapainya dengan coding, menggunakan instruksi Mołot.
Елин Й.

2

Saya ingin memposting bagaimana saya mencapainya berkat bantuan besar dari Mo Moot.

  1. Menerapkan hook_form_FORM_ID_alter () .
  2. Menambahkan div pembungkus di sekitar koleksi bidang.
  3. Karena koleksi bidang saya adalah bidang multi-nilai, iterasi di atasnya dan setel #ajaxproperti untuk bidang tersebut field_my_userreference.
  4. Membuat fungsi panggilan balik yang hanya mengembalikan item koleksi bidang kembali.
  5. Diperiksa dalam implementasi hook_form_FORM_ID_alter (), jika $ form_state untuk koleksi bidang disetel. Jika ya, dapatkan nilai dari entitas pengguna dan isi bidang input formulir dengan nilai-nilai itu.

Kode saya terlihat seperti:

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

Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.