Dynamische Auswahlliste im Formular (abhängiges Dropdown)

28

Ich benutze Drupal sieben. Ich möchte, dass die Optionen in einer Auswahlliste von dem Wert abhängen, der in einer anderen Auswahlliste in einem Formular ausgewählt wurde. Ich bin mir sicher, dass dies schon oft gefragt wurde, aber ich habe Schwierigkeiten, eine klare Antwort dafür zu finden.

Über das Formular können Benutzer einen Arbeitsverlauf eingeben. Sie müssen ein Geschwader auswählen, das eine Knotenreferenz zum Geschwaderfeldtyp ist, und dies befindet sich in einer Dropdown-Liste. Das Geschwader ist jedoch von einer Stadt-Dropdown-Liste abhängig. Benutzer müssen zuerst eine Stadt auswählen, die dann die Optionen für die Staffel filtert. Im Geschwader-Inhaltstyp habe ich eine Taxonomie für eine Stadt erstellt, die dem Geschwader zugeordnet wird.

Ich wäre Ihnen sehr dankbar, wenn Sie Hinweise dazu geben würden, wie Sie am besten (am einfachsten?) Vorgehen können, oder wenn Sie hilfreiche Online-Ressourcen benötigen.

Ben
quelle

Antworten:

27

Sie können Ajax verwenden, um dies zu erreichen. Drupal 7 hat jetzt gute Ajax-Unterstützung. In Ihrer ersten Auswahlliste (Stadt) müssen Sie Ajax-Informationen hinzufügen. Dann kann die zweite Auswahlliste basierend auf den Informationen in der ersten gefüllt werden. Sie können die zweite Auswahlliste auch ausblenden, bis eine Option in der ersten ausgewählt ist, und ich werde erklären, wie Sie das in Kürze tun. Zunächst richten Sie die Grundform ein:

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

Dies ist nur die Grundeinstellung der Elemente. Jetzt müssen Sie einen Weg finden, um zu bestimmen, welche Optionen im Geschwader verfügbar sein sollen. Zuerst müssen Sie Ihren Ajax-Rückruf in der Auswahlliste "Stadt" angeben. In den meisten Fällen können Sie nur das Element zurückgeben, das das Ajax-Element umschließt, in diesem Fall $ form.

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

Wenn sich die Auswahlliste "Stadt" ändert, wird der Staffelumbruch-Teil des Formulars neu erstellt. Ihr 'Stadt'-Wert wird jetzt in $ form_state [' Werte '] angegeben. Wenn also das Formular neu erstellt wird, müssen wir anhand des Werts von "Stadt" festlegen, welche Optionen der Auswahlliste zugewiesen werden sollen.

// 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
quelle
6
Beispiele finden Sie im Modul Beispiele ("AJAX-Beispiele" → "Abhängiges Dropdown"). Sie können auch unter Hierarchisches Auswahlmodul nachsehen.
Kalabro
Sie können dies übrigens auch in mehreren Schritten tun, aber ich habe nicht gedacht, dass das so klingt, wie Sie es sich vorgestellt haben. Auch ^ guten Ruf! Beispielmodule eignen sich hervorragend, um solche Dinge zu lernen.
Jordojuice
@jordojuice Vielen Dank für Ihre Antwort. Ich arbeite gerade daran. In dem dritten Beispiel des Codes, den Sie oben angegeben haben (begin // Get the value ...), in welche Funktion setze ich diesen Teil des Codes? Geht das in der _ajax_callback Funktion? Danke
Ben
Ich habe das Beispielmodul dazu befolgt, aber jedes Mal, wenn ich ein Element in der ersten Dropdown-Liste auswähle, ist ein Fehler aufgetreten: Warnung: array_values ​​() erwartet, dass Parameter 1 ein Array ist, eine Zeichenfolge, die in _field_filter_items () (Zeile 525 von I: \ My Documents) angegeben ist \ web \ xampp \ htdocs \ mysite \ modules \ field \ field.module). Ich verwende ein mehrstufiges Formular in Verbindung mit diesem Ajax-abhängigen Dropdown, das ich in einem benutzerdefinierten Überschreibungsmodul geschrieben habe. Es ist nur eine Warnung, die auftaucht, aber ärgerlich ... Kann mir bitte jemand helfen, diese Warnung zu entfernen? Vielen Dank!
Januar
2 Wichtige Unterschiede zwischen diesem Code und dem, was bei @Ben funktioniert hat. Beachten Sie, dass das #Suffix eine ID verwendet und der Ajax-Rückruf das Formularelement und nicht das gesamte Formular zurückgibt. Ansonsten war das super hilfreich!
wolffer-east
11

Vielen Dank an jordojuice oben. Mit seiner Hilfe gelang es mir, eine Lösung zu finden. Ich habe auch auf das Beispiel unter http://public-action.org/content/drupal-7-form-api-dependent-lists-and-ajax-form-submission verwiesen . Ich habe schließlich den folgenden Code verwendet, der in einem benutzerdefinierten Modul funktioniert. Aus irgendeinem Grund konnte ich keinen meiner Werte in den $ form_state-Werten finden, konnte sie aber in $ form finden. Schließlich erhielt ich beim Testen eine Fehlermeldung, dass Drupal eine unzulässige Auswahl in der Dropdown-Liste festgestellt hatte. Ich habe das umgangen, indem ich Zeile 1290 in form.inc auskommentiert habe:

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

Der endgültige Code, den ich verwendet habe, war:

<?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
quelle
Ich bekomme eine Eine illegale Wahl wurde festgestellt. Bitte wenden Sie sich an den Site-Administrator. Fehler, als ich versuchte, oben zu implementieren. Kannst du helfen?
Harshal
@ harshal - Ich hatte das gleiche Problem und habe die Lösung implementiert, die ich in meiner Antwort angegeben habe. Siehe oben (Änderung von form.inc). Dies ist ein bisschen hacken, aber es hat für mich funktioniert.
Ben
@ harshal - Eine wahrscheinlich bessere Lösung ist die von Hacker unten angegebene.
Ben
1

Setzen Sie die Codezeile dh
$nodes[''] = '- None -'; nach

 $nodes = array();

in ur sappers_squadron_squadrons function und das wird deinen Fehler lösen

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

Hacker
quelle
1

Die Hauptursache für "Es wurde eine illegale Auswahl festgestellt. Wenden Sie sich an den Site-Administrator." ist, dass die leere Zeichenfolge mit dem Wert 0 von hinzugefügt$nodes[]=""; wird, für das Feld field_squadron ungültig ist.

Siehe Erweiterte PHP-Programmierung und -Entwicklung. Beachten Sie jedoch, dass die Flags DANGEROUS_SKIP_CHECK und validated in D7 veraltet sind .

Nachdem ich diese Zeile entfernt hatte, war der Fehler verschwunden.

Siripong
quelle
1

Verwenden Sie das Referenzfeld Option Limit Modul

Dieses Modul ermöglicht es Referenzfeldern verschiedener Typen, die verfügbaren Optionen ihrer Widgets durch die Werte anderer Felder in der aktuellen Entität zu beschränken.

Rakesh Nimje
quelle
Ist es eine Alternative zum Bedingungsfeldmodul?
Umair