Daftar pilih dinamis dalam bentuk (dropdown dependen)

28

Saya menggunakan Drupal tujuh. Saya ingin membuat opsi dalam daftar pilih menjadi tergantung pada nilai yang dipilih dalam daftar pilih lain dalam formulir. Saya yakin ini telah ditanyakan berkali-kali sebelumnya, tetapi saya mengalami kesulitan menemukan jawaban yang jelas untuk bagaimana melakukan ini.

Formulir ini untuk pengguna untuk memasukkan riwayat kerja. Mereka perlu memilih skuadron yang merupakan referensi simpul ke tipe bidang skuadron, dan ini ada dalam daftar drop-down. Namun, skuadron, tergantung pada daftar drop-down kota. Pengguna pertama-tama harus memilih kota yang kemudian akan memfilter opsi untuk skuadron. Dalam tipe konten skuadron, saya membuat taksonomi untuk kota yang akan ditandai ke skuadron.

Saya akan sangat berterima kasih atas petunjuk apa pun tentang cara terbaik (paling sederhana?) Untuk melakukan hal ini, atau untuk sumber daya online yang bermanfaat yang akan membantu.

Ben
sumber

Jawaban:

27

Anda dapat menggunakan Ajax untuk mencapai ini. Drupal 7 memiliki dukungan Ajax yang baik sekarang. Pada daftar pilih (kota) pertama Anda, Anda perlu menambahkan informasi Ajax. Kemudian, daftar pilih kedua dapat diisi berdasarkan informasi di yang pertama. Anda bahkan dapat menyembunyikan daftar pilih kedua sampai opsi di yang pertama dipilih, dan saya akan menjelaskan bagaimana melakukannya sedikit. Pertama, untuk mengatur bentuk dasar:

$form['city'] = array(
  '#type' => 'select',
  '#title' => t('City'),
  '#options' => $options,
  '#ajax' => array(
    'event' => 'change',
    'wrapper' => 'squadron-wrapper',
    'callback' => 'mymodule_ajax_callback',
    'method' => 'replace',
  ),
);
$form['squadron_wrapper'] = array('#prefix' => '<div class="squadron-wrapper">', '#suffix' => '</div>');
$form['squadron_wrapper']['squadron'] = array(
  '#type' => 'select',
  '#title' => t('Squadron'),
  '#options' => $squadron_options,
);

Ini hanya pengaturan dasar elemen. Sekarang Anda akan membutuhkan cara untuk menentukan opsi apa yang harus masuk dalam skuadron. Pertama, Anda perlu membuat panggilan balik Ajax Anda diidentifikasi di daftar pilih 'kota'. Dalam kebanyakan kasus, Anda bisa mengembalikan elemen yang membungkus elemen ajax, dalam hal ini $ form.

function mymodule_ajax_callback($form, $form_state) {
  return $form;
}

Sekarang, ketika perubahan daftar pilih 'kota' itu akan membangun kembali bagian skuadron-pembungkus formulir. Nilai 'kota' Anda sekarang akan berada di $ form_state ['nilai']. Jadi, ketika formulir dibangun kembali kita perlu menentukan opsi apa yang akan diberikan ke daftar pilih berdasarkan nilai 'kota'.

// Get the value of the 'city' field.
$city = isset($form_state['values']['city']) ? $form_state['values']['city'] : 'default';
switch ($city) {
  case 'default':
    // Set default options.
    break;
  case 'losangeles':
    // Set up $squadron_options for los angeles.
    break;
}

// If you want to hide the squadron select list until a city is
// selected then you can do another conditional.
if ($city !== 'default') {
  $form['squadron_wrapper']['squadron'] = array(
    '#type' => 'select',
    '#title' => t('Squadron'),
    '#options' => $squadron_options,
  );
}
jordojuice
sumber
6
Contoh dapat ditemukan dalam modul Contoh ("Contoh AJAX" → "Dropdown yang tergantung"). Anda juga dapat melihat di modul Select Hierarchical .
kalabro
Ngomong-ngomong, alternatifnya Anda bisa melakukan ini dalam bentuk multi-langkah, tapi saya tidak berpikir itu terdengar seperti apa yang Anda cari. Juga ^ panggilan bagus! Modul contoh sangat bagus untuk mempelajari hal semacam ini.
jordojuice
@jordojuice Terima kasih banyak atas jawaban Anda. Saya sedang mengerjakannya sekarang. Pada contoh ketiga dari kode yang Anda berikan di atas (awal // Dapatkan nilai ...) fungsi apa yang saya masukkan bagian dari kode? Apakah itu masuk dalam fungsi _ajax_callback? Terima kasih
Ben
Saya mengikuti contoh modul untuk ini tetapi saya mendapat kesalahan setiap kali saya memilih item di drop down pertama: Peringatan: array_values ​​() mengharapkan parameter 1 menjadi array, string yang diberikan dalam _field_filter_items () (baris 525 dari I: \ My Documents \ web \ xampp \ htdocs \ mysite \ modules \ field \ field.module). Saya menggunakan bentuk multi-langkah dalam hubungannya dengan drop-down ajax dependen ini yang saya tulis dalam modul custom override .... Meskipun nilai-nilai bisa diubah untuk dd kedua berdasarkan yang pertama. Itu hanya peringatan yang muncul tetapi menjengkelkan ... bisakah seseorang tolong bantu saya menghapus peringatan itu? Terima kasih!
Januari
2 Perbedaan penting antara kode ini dan apa yang akhirnya berfungsi untuk @Ben. Perhatikan bahwa #suffix menggunakan id, dan panggilan balik ajax mengembalikan elemen form, bukan seluruh form. Selain itu, ini sangat membantu!
wolffer-east
11

Banyak terima kasih kepada jordojuice di atas. Dengan bantuannya saya berhasil menemukan solusi. Saya juga merujuk pada contoh di http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-smission . Saya akhirnya menggunakan kode di bawah ini yang berfungsi dalam modul khusus. Untuk beberapa alasan saya tidak dapat menemukan nilai saya di nilai $ form_state, tetapi dapat menemukannya dalam $ form. Akhirnya, ketika saya mengujinya, saya mendapatkan pesan kesalahan bahwa Drupal telah mendeteksi pilihan ilegal di drop-down. Saya menyelesaikan ini dengan mengomentari baris 1290 dalam form.inc:

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

Kode terakhir yang saya gunakan adalah:

<?php

function sappers_squadron_form_work_history_node_form_alter(&$form, &$form_state) {     
        //echo '<pre>';
        //print_r ($form);
        //echo '</pre>';

        $squadron_options = array();

        if(isset($form['field_wkhist_city']['und']['#default_value'][0])) {
            $city = $form['field_wkhist_city']['und']['#default_value'][0];
        }
        else {
            $city = 0;
        }

        $squadron_options = sappers_squadron_squadrons($city);

        $form['field_wkhist_city']['und']['#ajax'] = array(
            'event' => 'change',
            'wrapper' => 'squadron-wrapper',
            'callback' => 'sappers_squadron_ajax_callback',
            'method' => 'replace',
        );

        $form['field_squadron']['und']['#prefix'] = '<div id="squadron-wrapper">';
        $form['field_squadron']['und']['#suffix'] = '</div>';
        $form['field_squadron']['und']['#options'] = $squadron_options;
}


function sappers_squadron_ajax_callback($form, $form_state) {   
    $city = $form['field_wkhist_city']['und']['#value'];

    $form['field_squadron']['und']['#options'] = sappers_squadron_squadrons($city);

    return $form['field_squadron'];
}


function sappers_squadron_squadrons($city) {
    $nodes = array();

    $select = db_query("SELECT node.title AS node_title, node.nid AS nid FROM  {node} node INNER JOIN {taxonomy_index} taxonomy_index ON node.nid = taxonomy_index.nid WHERE (( (node.status = '1') AND (node.type IN  ('squadron')) AND (taxonomy_index.tid = $city) )) ORDER BY node_title ASC");

    $nodes[]="";

    foreach ($select as $node) {
            $nodes[$node->nid] = $node->node_title;
    }

    return $nodes;
}

?>
Ben
sumber
Saya mendapatkan pilihan ilegal yang terdeteksi. Silakan hubungi administrator situs. kesalahan ketika saya mencoba menerapkan di atas. Bisakah kamu membantu?
harshal
@harshal - Saya memiliki masalah yang sama dan mengatasinya dengan menerapkan solusi yang saya berikan dalam jawaban saya, silakan lihat di atas (mengubah form.inc). Ini sedikit peretasan tetapi berhasil bagi saya.
Ben
@harshal - Mungkin solusi yang lebih baik adalah yang diberikan oleh Hacker di bawah ini.
Ben
1

letakkan baris kode yaitu
$nodes[''] = '- None -'; setelah

 $nodes = array();

di ur Anda sappers_squadron_squadrons function dan itu akan menyelesaikan kesalahan Anda

form_error($elements, $t('An illegal choice has been detected. Please contact the site administrator.'));

Peretas
sumber
1

Gunakan modul batas opsi bidang referensi

Modul ini memungkinkan bidang referensi dari beberapa jenis memiliki opsi widget yang tersedia dibatasi oleh nilai-nilai bidang lain di entitas saat ini.

Rakesh Nimje
sumber
Apakah ini merupakan alternatif dari modul bidang bersyarat?
Umair