Metodo più semplice per i campi condizionali in un modulo


20

Qual è il modo più semplice per ottenere un po 'di magia javascript per abilitare / disabilitare i campi modulo in base al valore di un altro campo? Sembra qualcosa che dovrebbe esserci un aiuto da qualche parte, ma non riesco a trovarlo. Sto cercando una soluzione che non sia limitata ai nodi.


Non sono sicuro che questa sia davvero una domanda Drupal. È JavaScript e dovrebbe essere richiesto su StackTranslate.it.
Camsoft

3
Stavo cercando una soluzione Drupal. Sono in grado di scrivere Javascript per questo, ma sembra davvero che debba essere collegato in qualche modo all'API Form.
Fuzzy76,

Questo è figo. Non penso che fosse chiaro nella domanda originale. Non sono a conoscenza di alcun modulo che possa farlo.
Camsoft

Risposte:


18

La magia sta usando la proprietà #ahah / #ajax con elementi del modulo, in questo modo puoi definire cosa dovrebbe innescare la modifica e cosa dovrebbe essere modificato di conseguenza, inoltre si integra perfettamente con jQuery.

Questa è la parte importante dell'esempio seguente:

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

Ecco un esempio che mostra una pagina basata su form con due menu a discesa: l'elenco delle opzioni nel secondo menu a discesa dipende dalla selezione nel primo menu a discesa.

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

Questo è il modo giusto per modificare un modulo in base al valore di uno dei suoi campi. Ma per nascondere / mostrare o abilitare / disabilitare i campi, la proprietà #states sull'elemento modulo è più semplice.
Pierre Buyle,

6

Il modulo Campi condizionali non fa proprio questo?

Quando si modifica un nodo, i campi controllati vengono mostrati dinamicamente e nascosti con JavaScript.


Per moduli nodo e campi CCK, sì. Ma volevo qualcosa che potesse essere usato in altre circostanze. Chiarirò la mia domanda.
Fuzzy76,

3

Esistono due diversi sistemi che è possibile utilizzare:

  • # ahah / # ajax ti consente di inviare il modulo con AJAX e ricostruirlo sul lato server. Utile quando si desidera effettivamente aggiungere nuovi elementi del modulo, un esempio tipico in D6 è upload.module. Già spiegato sopra.
  • Una novità di Drupal 7 è il sistema #states che ti permette di fare cose come mostrare / nascondere / abilitare / disabilitare gli elementi del modulo basati su altri elementi. Vedi http://www.randyfay.com/node/58 per ulteriori informazioni al riguardo.

1

Il metodo più semplice sarebbe scrivere il tuo JavaScript e usare jQuery per collegare i gestori di eventi agli eventi di sfocatura e messa a fuoco. Quindi, quando vengono attivati ​​i callback, disabilitare / abilitare i campi in base alla propria logica.


E se non è in grado di scrivere il suo jQuery? Un modulo Drupal non sarebbe facile da programmare? - A causa del chiarimento della domanda, ritiro il mio commento.
Decifrare l'

In primo luogo, non ero a conoscenza del modulo Campi condizionali, in secondo luogo, quanto sovraccarico aggiungerà un modulo come questo al suo progetto su un semplice JS lato client?
Camsoft
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.