Kotak centang terpilih (taksonomi) mengisi daftar pilih baru dengan nilai-nilai kotak yang dipilih

7

* pertanyaan dijawab: Bantuan diperlukan dengan hook_node_submit di modul khusus untuk menyimpan data *


Di Drupal 7, saya memiliki tipe konten khusus. Dalam hal ini, ada referensi istilah multi pilih untuk memilih kategori untuk konten itu.

Saya sekarang harus dapat memilih satu dari kategori yang sebelumnya dipilih dan menandainya sebagai kategori 'utama'.

Katakanlah saya memiliki beberapa bidang referensi istilah pilih dengan opsi berikut:

Apples
Bananas
Pears
Oranges
Grapes
Pineapples

Pengguna memilih Apel, Pir dan Anggur. Sekarang saya juga perlu:

  1. Secara terprogram membuat bidang lain untuk masing-masing pilihan ini — mungkin dengan panggilan balik ajax — dan memiliki tombol radio sehingga saya hanya dapat memilih salah satu istilah yang dipilih yang merupakan kategori utama saya.
  2. Buat bidang radio di sebelah item yang dicentang — mungkin juga dengan ajax — tempat saya dapat memilih yang utama dari yang dipilih.

Adakah yang punya ide tentang ini?

Agar lebih jelas, saya memiliki banyak daftar ini pada satu jenis konten. Mengulangi setiap daftar sebagai daftar nilai tunggal bukanlah suatu opsi.

Saya kira taruhan terbaik saya adalah dengan menggunakan hook_form_alter()semacam panggilan balik AJAX untuk membuat tombol radio tunggal di sebelah kotak centang yang baru saja dicentang pengguna, atau secara terprogram membuat daftar bidang radio baru untuk setiap item yang dicentang dalam daftar yang ditentukan.

Pembaruan: Oke, saya telah memutuskan bahwa cara terbaik untuk melakukannya adalah dengan membuat modul khusus yang menggunakan ajax untuk membuat tombol radio untuk setiap kotak centang yang dicentang, memungkinkan untuk memilih elemen yang harus digunakan sebagai elemen utama.

Jadi saya sudah terbiasa hook_form_alter()menambahkan #after_buildfungsi karena kita perlu menunggu formulir yang akan diberikan sebelum kita dapat mengakses nilai-nilai istilah pajak.

Berikut ini adalah modul saya. Saya menggunakan banyak komentar sehingga harus jelas apa yang saya coba lakukan:

MYMODULE.module

/**
 * Implementation of HOOK_form_alter()
 * Do the ajax form alteration
 */
function MYMODULE_form_alter(&$form, &$form_state, $form_id) {

  // 1.CONTENT FORM
  // I created a custom content type 'content' and added a term
  // reference to it 
  if($form_id == 'content_node_form') {

    // tax term ref is the main part, so let us
    // remove title and body fields
    unset($form['body']);
    unset($form['title']);

    // do our stuff after the form has been rendered ...
    $form['#after_build'][] = 'MYMODULE_after_build';

  }
}

/**
 * after_build function for content_node_form
 */
function MYMODULE_after_build(&$form, &$form_state) {

    dsm($form);  

    // In the after_build call we can now actually use the 
    // element_children function to grab the values of the fields that
    // don't start with a hash tag #
    // in this test case 1,2,3,4 and 5

    // wrap each of the elements rendered ...
    foreach(element_children($form['field_taxonomy']['und']) as $key) {

      $form['field_taxonomy']['und'][$key] += array(

        // this is added before the element and then replaced by our callback ..
        // we use the $key value in the id so that we know which div to replace 
        // depending on which checkbox is checked ...
        '#prefix' => '<div class="taxonomy_term_wrapper">
                        <div id="callback_replace_'.$key.'">Replace Me ' . $key . '</div>',

        // this is added after the element so we basically wrap around it ..
        '#suffix' => '</div>',

        // add some ajax stuff here ...
        '#ajax' => array(
          // name of the callback function to call upon change
          'callback' => 'MYMODULE_callback',
          // the id of the element that will be replaced
          'wrapper' => 'callback_replace_'.$key,
          // replace the wrapper
          'method' => 'replace',
          // what kind of effect do we want ...
          'effect' => 'fade',
          // show progress on callback
          'progress' => array('type' => 'throbber'),
        ),
      ); 



      if (!empty($form_state['values']['field_taxonomy']['und'][$key])) {
        // the form to show upon change ...
        $form['field_taxonomy']['und']['main_cat'] = array(
          // we want a radio button
          '#type' => 'radio',
          '#title' => t('Test Title'),
          '#description' => t('Test Description ...'),
          '#default_value' => empty($form_state['values']['field_taxonomy']['und'][$key]) ?
                              $form_state['values']['field_taxonomy']['und'][$key] :
                              $form_state['values']['field_taxonomy']['und'][$key],
        );
      }

    }

  return $form;
} 

function MYMODULE_callback($form, $form_state) {
 return $form['field_taxonomy']['und']['main_cat'];
}

Ini terlihat seperti sebelum memeriksa kotak:

Ini terlihat seperti sebelum memeriksa kotak

HTML dari formulir yang diberikan adalah yang berikut:

tangkapan layar

tecjam
sumber
Ini sebenarnya bukan jawaban, tetapi coba lihat pada modul Contoh. Ini memiliki beberapa contoh bentuk ajax rapi yang dapat membantu Anda sepanjang jalan :) drupal.org/project/examples
Chapabu
Hai Chapabu, terima kasih atas jawaban Anda. Saya telah menggunakan contoh-contoh ajax, tetapi masalah saya terletak pada kenyataan bahwa saya perlu menggunakan after_build untuk menambahkan kode saya dan sekarang saya bingung mengapa tidak melakukan apa-apa ... Saya telah menambahkan lebih banyak kode di atas - termasuk kemajuan saya sejauh ini dengan modul. Mungkin Anda dapat melihat kesalahan
tecjam
hmm..satu-satunya hal yang saya dapat (cepat) lihat berbeda di after_build Anda adalah formatnya. Dalam dokumen Drupal dikatakan itu akan terlihat seperti ini - $ form ['# after_build'] => array ('MYMODULE_after_build');
Chapabu
Saya percaya $ form ['# after_build'] => array ('MYMODULE_after_build'); sama dengan $ form ['# after_build'] [] = 'MYMODULE_after_build'; - Catat []
tecjam
Juga, fungsi after_build tampaknya berfungsi dengan baik karena tidak membungkus istilah taksonomi saya di div kustom saya dan menambahkan div pengganti saya. Hanya panggilan
baliknya

Jawaban:

1

buat item sebagai kotak centang. setelah dipilih, perlihatkan daftar drop-down dengan item-item ini atau tombol radio lain untuk memilih kategori utama. Anda dapat menyembunyikan drop down kedua menggunakan kode berikut sampai kotak centang pertama dipilih.

'#states' => array(
'visible' => array(
':input[name="your checkbox"]' => array('checked' => TRUE),
 ),
)

tambahkan ini ke elemen yang ingin Anda sembunyikan. ini hanya akan terlihat ketika kotak centang dicentang.

ana
sumber
0

Bagaimana dengan dua daftar, satu judul utama yang mengambil satu pilihan, beberapa lainnya. Anda masih perlu mengatasi daftar atau seleksi kedua untuk menghilangkan duplikasi.

Ashlar
sumber
Hai dan terima kasih atas jawaban Anda. Ya, tentu saja itu akan berhasil. Namun, saya memiliki banyak sekali daftar di halaman pembuatan konten dan memiliki semuanya dua kali bukan pilihan. Saya hanya menjawab pertanyaan di atas demi sebuah contoh.
tecjam