Elenco di selezione dinamica nel modulo (elenco a discesa dipendente)


28

Sto usando Drupal sette. Voglio fare in modo che le opzioni in un elenco di selezione dipendono dal valore scelto in un altro elenco di selezione in un modulo. Sono sicuro che questo è stato chiesto molte volte prima, ma ho difficoltà a trovare una risposta chiara su come farlo.

Il modulo consente agli utenti di inserire una cronologia di lavoro. Devono selezionare uno squadrone che è un riferimento nodo al tipo di campo squadrone, e questo è in un elenco a discesa. Tuttavia, lo squadrone dipende da un elenco a discesa della città. Gli utenti devono prima selezionare una città che quindi filtrerà le opzioni per lo squadrone. Nel tipo di contenuto dello squadrone, ho creato una tassonomia per la città che viene taggata dallo squadrone.

Sarei molto grato per qualsiasi suggerimento sul modo migliore (più semplice?) Di fare questo, o per qualsiasi risorsa utile online che possa aiutare.

Risposte:


27

È possibile utilizzare Ajax per ottenere questo risultato. Drupal 7 ha un buon supporto Ajax ora. Nel tuo primo elenco selezionato (città) dovrai aggiungere le informazioni Ajax. Quindi, il secondo elenco di selezione può essere popolato in base alle informazioni nel primo. Puoi anche nascondere il secondo elenco di selezione fino a quando non viene selezionata un'opzione nella prima, e ti spiegherò come farlo tra poco. Innanzitutto, per impostare il modulo di base:

$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,
);

Questa è solo la configurazione di base degli elementi. Ora avrai bisogno di un modo per determinare quali opzioni dovrebbero andare nello squadrone. Per prima cosa devi identificare il tuo callback Ajax nell'elenco di selezione 'città'. Nella maggior parte dei casi puoi semplicemente restituire l'elemento che avvolge l'elemento ajax, in questo caso $ form.

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

Ora, quando l'elenco di selezione 'città' cambia, ricostruirà la parte del modulo di avvolgimento di squadroni. Il valore di "città" sarà ora in $ form_state ["valori"]. Quindi, quando il modulo viene ricostruito, dobbiamo determinare quali opzioni dare alla lista selezionata in base al valore di "città".

// 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,
  );
}

6
Esempi sono disponibili nel modulo Esempi ("Esempi AJAX" → "Elenco a discesa dipendente"). Puoi anche vedere nel modulo di selezione gerarchica .
Kalabro,

A proposito, in alternativa puoi farlo in una forma multi-step, ma non pensavo che suonasse come quello che stavi cercando. Inoltre ^ buona chiamata! I moduli di esempio sono ottimi per imparare questo tipo di cose.
jordojuice,

@jordojuice Grazie mille per la tua risposta. Ci sto lavorando adesso. Nel terzo esempio del codice che dai sopra (inizio // Ottieni il valore ...) in quale funzione inserisco questa parte del codice? Va nella funzione _ajax_callback? Grazie
Ben

Ho seguito il modulo di esempio per questo, ma ho ricevuto un errore ogni volta che seleziono un elemento nel primo menu a discesa: Avviso: array_values ​​() si aspetta che il parametro 1 sia array, stringa fornita in _field_filter_items () (riga 525 di I: \ My Documents \ web \ xampp \ htdocs \ mysite \ moduli \ campo \ field.module). Sto usando un modulo in più passaggi insieme a questo menu a discesa dipendente da Ajax che ho scritto in un modulo di sostituzione personalizzato .... Anche se i valori vengono cambiati per il secondo dd in base al primo. È solo un avvertimento che appare però irritante ... qualcuno può aiutarmi per favore a rimuovere quell'avvertimento? Grazie!
gennaio

2 Differenze importanti tra questo codice e ciò che ha funzionato per @Ben. Si noti che #suffix utilizza un id e il callback ajax restituisce l'elemento del modulo, non l'intero modulo. A parte questo, questo è stato di grande aiuto!
Wolffer-East,

11

Mille grazie a jordojuice sopra. Con il suo aiuto sono riuscito a trovare una soluzione. Ho anche fatto riferimento all'esempio su http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission . Alla fine ho usato il codice seguente che ha funzionato in un modulo personalizzato. Per qualche motivo non sono riuscito a trovare nessuno dei miei valori nei valori $ form_state, ma sono riuscito a trovarli in $ form. Alla fine, quando ho provato, stavo ricevendo un messaggio di errore che Drupal aveva rilevato una scelta illegale nel menu a discesa. Ho risolto il problema commentando la riga 1290 in form.inc:

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

Il codice finale che ho usato era:

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

?>

Ottengo una scelta illegale rilevata. Si prega di contattare l'amministratore del sito. errore quando ho provato a implementare sopra. Potete aiutarmi?
Harshal,

@harshal - Ho avuto lo stesso problema e ho risolto il problema implementando la soluzione che do nella mia risposta, vedi sopra (modifica form.inc). Questo è un po 'un trucco ma ha funzionato per me.
Ben

@harshal - Probabilmente una soluzione migliore è quella data da Hacker di seguito.
Ben

1

metti la riga di codice cioè
$nodes[''] = '- None -'; dopo

 $nodes = array();

in ur sappers_squadron_squadrons function e che risolverà il tuo errore

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



1

Utilizzare il modulo limite opzione campo di riferimento

Questo modulo consente ai campi di riferimento di diversi tipi di avere le opzioni disponibili dei loro widget limitate dai valori di altri campi nell'entità corrente.


È un'alternativa al modulo dei campi condizionali?
Umair,
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.