Metode termudah untuk bidang bersyarat dalam formulir


20

Apa cara termudah untuk mendapatkan beberapa sihir javascript untuk mengaktifkan / menonaktifkan bidang formulir berdasarkan pada nilai bidang lain? Ini terdengar seperti sesuatu yang harus ada pembantu di suatu tempat, tetapi saya tidak dapat menemukannya. Saya mencari solusi yang tidak terbatas pada node.


Tidak yakin ini benar-benar pertanyaan Drupal. Ini adalah JavaScript dan harus ditanyakan pada Stack Overflow.
Camsoft

3
Saya mencari solusi Drupal. Saya mampu menulis Javascript untuk itu, tetapi rasanya benar-benar seperti itu harus dicolokkan ke dalam Formulir API.
Fuzzy76

Itu keren. Saya tidak berpikir itu jelas dalam pertanyaan awal. Saya tidak tahu modul apa pun yang bisa melakukan ini.
Camsoft

Jawaban:


18

Sihir yang menggunakan #ahah / #ajax properti dengan elemen bentuk, dengan cara itu Anda dapat menentukan apa yang harus memicu modifikasi dan apa yang harus diubah sebagai hasilnya, ditambah diintegrasikan dengan jQuery.

Ini adalah bagian penting dari contoh di bawah ini:

'#ajax' => array(
    'event' => 'change',
    'callback' => 'myajax_ajax_callback',
    'wrapper' => 'dropdown_second_replace',
),

Berikut adalah contoh yang memperlihatkan halaman berbasis formulir dengan dua dropdown: daftar opsi pada dropdown kedua bergantung pada pilihan pada dropdown pertama.

<?php

/**
 * Implementation of hook_menu().
 * Registers a form-based page that you can access at "http://localhost/myajax"
 */
function myajax_menu(){
    return array(
        'myajax' => array(
            'title' => 'A page to test ajax',
            'page callback' => 'drupal_get_form',
            'page arguments' => array('myajax_page'),
            'access arguments' => array('access content'), 
        )
    );
}



/**
 * A form with a dropdown whose options are dependent on a
 * choice made in a previous dropdown.
 *
 * On changing the first dropdown, the options in the second are updated.
 */
function myajax_page($form, &$form_state) {
    // Get the list of options to populate the first dropdown.
    $options_first = myajax_first_dropdown_options();

    // If we have a value for the first dropdown from $form_state['values'] we use
    // this both as the default value for the first dropdown and also as a
    // parameter to pass to the function that retrieves the options for the
    // second dropdown.
    $value_dropdown_first = isset($form_state['values']['dropdown_first']) ? $form_state['values']['dropdown_first'] : key($options_first);

    $form['dropdown_first'] = array(
        '#type' => 'select',
        '#title' => 'First Dropdown',
        '#options' => $options_first,
        '#default_value' => $value_dropdown_first,

        // Bind an ajax callback to the change event (which is the default for the
        // select form type) of the first dropdown. It will replace the second
        // dropdown when rebuilt
        '#ajax' => array(
            // When 'event' occurs, Drupal will perform an ajax request in the
            // background. Usually the default value is sufficient (eg. change for
            // select elements), but valid values include any jQuery event,
            // most notably 'mousedown', 'blur', and 'submit'.
            'event' => 'change',
            'callback' => 'myajax_ajax_callback',
            'wrapper' => 'dropdown_second_replace',
        ),
    );
    $form['dropdown_second'] = array(
        '#type' => 'select',
        '#title' => 'Second Dropdown',
        // The entire enclosing div created here gets replaced when dropdown_first
        // is changed.
        '#prefix' => '<div id="dropdown_second_replace">',
        '#suffix' => '</div>',
        // when the form is rebuilt during ajax processing, the $value_dropdown_first variable
        // will now have the new value and so the options will change
        '#options' => myajax_second_dropdown_options($value_dropdown_first),
        '#default_value' => isset($form_state['values']['dropdown_second']) ? $form_state['values']['dropdown_second'] : '',
    );
    return $form;
}

/**
 * Selects just the second dropdown to be returned for re-rendering
 *
 * Since the controlling logic for populating the form is in the form builder
 * function, all we do here is select the element and return it to be updated.
 *
 * @return renderable array (the second dropdown)
 */
function myajax_ajax_callback($form, $form_state) {
    return $form['dropdown_second'];
}


/**
 * Helper function to populate the first dropdown. This would normally be
 * pulling data from the database.
 *
 * @return array of options
 */
function myajax_first_dropdown_options() {
    return array(
        'colors' => 'Names of colors',
        'cities' => 'Names of cities',
        'animals' => 'Names of animals',
    );
}


/**
 * Helper function to populate the second dropdown. This would normally be
 * pulling data from the database.
 *
 * @param key. This will determine which set of options is returned.
 *
 * @return array of options
 */
function myajax_second_dropdown_options($key = '') {
    $options = array(
        'colors' => array(
            'red' => 'Red',
            'green' => 'Green',
            'blue' => 'Blue'
        ),
        'cities' => array(
            'paris' => 'Paris, France',
            'tokyo' => 'Tokyo, Japan',
            'newyork' => 'New York, US'
        ),
        'animals' => array(
            'dog' => 'Dog',
            'cat' => 'Cat',
            'bird' => 'Bird'
        ),  
    );
    if (isset($options[$key])) {
        return $options[$key];
    }
    else {
        return array();
    }
}

Ini adalah cara yang tepat untuk mengubah formulir tergantung pada nilai salah satu bidangnya. Tetapi untuk menyembunyikan / menampilkan atau mengaktifkan / menonaktifkan bidang, properti #states pada elemen formulir lebih mudah.
Pierre Buyle

6

Bukankah modul Conditional Fields melakukan hal itu?

Saat mengedit node, bidang yang dikontrol ditampilkan secara dinamis dan disembunyikan dengan JavaScript.


Untuk formulir simpul dan bidang CCK, ya. Tetapi saya menginginkan sesuatu yang dapat digunakan dalam keadaan lain. Saya akan mengklarifikasi pertanyaan saya.
Fuzzy76

3

Ada dua sistem berbeda yang dapat Anda gunakan:

  • # ahah / # ajax memungkinkan Anda untuk mengirimkan formulir dengan AJAX dan membangunnya kembali di sisi server. Berguna ketika Anda benar-benar ingin menambahkan elemen formulir baru , contoh khas di D6 adalah upload.module. Sudah dijelaskan di atas.
  • Baru di Drupal 7 adalah sistem #states yang memungkinkan Anda melakukan hal-hal seperti memperlihatkan / menyembunyikan / mengaktifkan / menonaktifkan elemen formulir berdasarkan elemen lain. Lihat http://www.randyfay.com/node/58 untuk informasi lebih lanjut tentang itu.

1

Metode termudah adalah menulis JavaScript Anda sendiri dan menggunakan jQuery untuk melampirkan penangan acara ke acara blur dan fokus. Kemudian ketika panggilan balik Anda diaktifkan, nonaktifkan / aktifkan bidang berdasarkan logika Anda.


Dan jika dia tidak mampu menulis jQuery sendiri? Bukankah modul Drupal lebih mudah daripada pengkodean? - Karena klarifikasi pertanyaan, saya menarik kembali komentar saya.
Menguraikan

Pertama saya tidak mengetahui modul Conditional Fields sendiri, kedua berapa banyak overhead yang akan ditambahkan modul ke proyeknya pada beberapa JS sederhana sisi klien?
Camsoft
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.