Sie haben ein Dropdown-Menü, und je nach Auswahl des Benutzers in diesem einen wird ein zweites Dropdown mit Auswahlmöglichkeiten gefüllt. Wir werden drei verschiedene Wege behandeln, wie Sie das machen können.
Demo anzeigen Dateien herunterladen
Der Markup
Für unser Beispiel ist der Markup immer gleich, nur zwei einfache select-Elemente. Das erste hat drei Optionen. Die erste informiert den Benutzer, eine Option auszuwählen, und die nächsten beiden sind tatsächliche Auswahlmöglichkeiten. Das zweite select hat nur eine Option, die den Benutzer auffordert, zuerst aus dem ersten Dropdown auszuwählen. Die Optionen im zweiten Dropdown werden dynamisch ersetzt.
<select id="first-choice">
<option selected value="base">Please Select</option>
<option value="beverages">Beverages</option>
<option value="snacks">Snacks</option>
</select>
<br>
<select id="second-choice">
<option>Please choose from above</option>
</select>
Option 1: Textdateien verwenden
Die Idee für diesen Beitrag stammt von Robert Young, der mir diese Technik mitgeteilt hat. Die Idee ist, dass sie einfach zu verwenden und zu verstehen ist. Nicht jeder möchte sich mit Datenbanken und Ähnlichem auseinandersetzen.
Für jede Möglichkeit eine Textdatei haben

In diesen Textdateien die HTML-Ersetzung für neue Optionen bereithalten
<option>Coffee</option>
<option>Coke</option>
Jetzt verwenden wir jQuery, um die Änderung des ersten Selects zu beobachten. Alle unsere Beispiele verwenden jQuery.
$("#first-choice").change(function() {
$("#second-choice").load("textdata/" + $(this).val() + ".txt");
});
Das funktioniert gut. Es ist tatsächlich einfach zu machen. Die potenziellen Nachteile sind 1) Daten in HTML-Tags wie diesem zu speichern ist vielleicht nicht der richtige Weg, diese Daten sind schwer für andere Zwecke wiederzuverwenden. 2) Nicht besonders skalierbar, da für jede einzelne Möglichkeit eine neue Textdatei erforderlich ist.
Option 2: JSON-Daten verwenden
Eine Alternative ist, die benötigten Daten im JSON-Format zu speichern. Sie könnten sie direkt in Ihrem JavaScript haben, das Sie laden, oder sie in einer externen Datei aufbewahren. Für diese Demo wird es eine externe Datei namens data.json sein. Das sind ihre Inhalte
{
"beverages": "Coffee,Coke",
"snacks": "Chips,Cookies"
}
Wir beobachten erneut eine Änderung des Werts des ersten Selects, laden dann die JSON und ermitteln, welche Teile davon wir benötigen
$("#first-choice").change(function() {
var $dropdown = $(this);
$.getJSON("jsondata/data.json", function(data) {
var key = $dropdown.val();
var vals = [];
switch(key) {
case 'beverages':
vals = data.beverages.split(",");
break;
case 'snacks':
vals = data.snacks.split(",");
break;
case 'base':
vals = ['Please choose from above'];
}
var $secondChoice = $("#second-choice");
$secondChoice.empty();
$.each(vals, function(index, value) {
$secondChoice.append("<option>" + value + "</option>");
});
});
});
Der Vorteil hier ist, dass wir die Daten ziemlich generisch speichern, sodass es einfach wäre, sie für andere Zwecke wiederzuverwenden. Beachten Sie, dass wir die Option-Tags im JavaScript selbst hinzufügen, das ist ziemlich flexibel. Die Nachteile dieser Technik sind, dass sie etwas komplizierter ist (aber wirklich, es ist nicht so schlimm). Wir könnten erwägen, das JSON in separate Dateien aufzuteilen, damit wir nicht alle Daten bei jeder Änderung laden müssen, aber dann stoßen wir auf dasselbe Skalierbarkeitsproblem wie bei Textdateien. Die Datenbank, die uns JSON zurückgibt, ist hier auch eine Möglichkeit.
Option 3: Eine Datenbank verwenden
Wir werden weiterhin das erste Select mit jQuery beobachten und die neuen Optionen dynamisch mit der .load()-Funktion von jQuery laden. Aber um aus einer Datenbank abzurufen, benötigen wir einen Vermittler, der diese Datenbankgespräche für uns führen kann (JavaScript kann das nicht von selbst). Wir verwenden also eine Datei "getter.php", und diese Datei wird uns das zurückgeben, was wir brauchen.
Zuerst benötigen wir eine sehr einfache Datenbank, aus der wir abrufen können

CREATE TABLE `dd_vals` (
`index` int(11) NOT NULL,
`category` varchar(255) NOT NULL,
`dd_val` varchar(255) NOT NULL,
UNIQUE KEY `index` (`index`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;
INSERT INTO `dd_vals` (`index`, `category`, `dd_val`) VALUES (1, 'snacks', 'Chips'),
(2, 'snacks', 'Cookies'),
(3, 'beverages', 'Coffee'),
(4, 'beverages', 'Coke');
Jetzt können wir diese Datenbank in der Tabelle "dd_vals" nach Einträgen abfragen, die Snacks oder Getränke als Kategorie haben, und nur das erhalten, was wir wollen. Unsere Abfrage muss etwa so enden:
SELECT * FROM dd_vals WHERE category='beverages'
Machen wir also unsere Datei getter.php, die sich mit dieser Datenbank verbindet und einen GET-Parameter für die Kategoriewahl hat, fügen wir diesen in die Abfrage ein und geben zurück, was sie findet, in Option-Tags.
<?php
$username = "username";
$password = "password";
$hostname = "localhost";
$dbhandle = mysql_connect($hostname, $username, $password) or die("Unable to connect to MySQL");
$selected = mysql_select_db("dropdownvalues", $dbhandle) or die("Could not select examples");
$choice = mysql_real_escape_string($_GET['choice']);
$query = "SELECT * FROM dd_vals WHERE category='$choice'";
$result = mysql_query($query);
while ($row = mysql_fetch_array($result)) {
echo "<option>" . $row{'dd_val'} . "</option>";
}
?>
Jetzt ist unser JavaScript wirklich einfach. Wir beobachten wieder Änderungen am ersten Dropdown und laden die Datei getter.php in das zweite Dropdown. Der schicke Trick hier ist, der Datei getter.php einen URL-Parameter zu übergeben, der der Wert aus dem ersten Dropdown ist.
$("#first-choice").change(function() {
$("#second-choice").load("getter.php?choice=" + $("#first-choice").val());
});
Für sehr kleine Websites und isolierte Beispiele kann eine Datenbank viel Arbeit oder sogar übertrieben erscheinen, aber dies ist bei weitem die flexibelste Option. Der Code ist sauber, schnell, die Daten sind so gespeichert, dass wir fast alles damit machen können usw.
Das ist nicht alles?
Wie bei allem im Web gibt es noch mehr Wege, dies anzugehen. Wir könnten die Werte in einem assoziativen Array speichern. Wir könnten MongoDB verwenden. Wir könnten die verschiedenen Selects fertig im HTML haben und sie nach Bedarf mit JavaScript ein- und ausblenden. Sie alle haben Vor- und Nachteile.
Demo anzeigen Dateien herunterladen
Hinweis: Ich füge das Datenbankbeispiel nicht in den Download ein, da es erst funktioniert, wenn Sie Ihre eigene Datenbank zum Verbinden haben und alles andere. So ist es weniger verwirrend.
Das ist ein tolles Tutorial und sehr nützlich! Danke Chris!
super
Ich musste mich kürzlich mit diesem Problem auseinandersetzen; Anfangs habe ich mich für JSON entschieden, aber das erwies sich als keine so gute Idee. JSON fügt jeder Aktion eine kleine Verlangsamung hinzu, und es stellte sich heraus, dass einige meiner Benutzer Erfahrungen damit hatten, wenn sie die WLAN-Verbindung verloren und die Anfrage lautlos fehlschlug; Was ich tat, war, die gesamten Auswahldaten einfach in den HTML zu speichern (lang lebe json_encode()) und meine ursprüngliche JSON-Getter-Funktion einfach so zu ändern, dass sie diese verwendet.
Die Markup ist auf diese Weise vielleicht nicht ganz sauber, aber meine Benutzer waren ziemlich glücklich, und das ist es, was über allem steht.
Wenn ich das richtig verstanden habe, verwenden Sie auf diese Weise keine "externen" Daten, um Ihr Formular dynamisch zu füllen ... Sie verwenden nur ein vordefiniertes JS-Array/Objekt, das alle möglichen Elemente enthält ...
Dies könnte ein einfacher Weg sein, bis Sie eine sehr begrenzte Anzahl von Elementen haben (wie normalerweise), sonst denke ich, dass Sie eine dynamische Lösung mit asynchronen Anfragen bevorzugen sollten.
@Loige, wenn ich Crafty_Shadow richtig verstehe, glaube ich, er verwendet externe, dynamische Daten. Aus seiner Beschreibung geht hervor, dass er PHP verwendet, um ein Array aus einer Datenbank abzurufen und es dann in den tatsächlichen HTML der servierten Seite auszugeben. Dies ermöglicht es ihm, die Felder über die Datenbank dynamisch zu aktualisieren, ohne einen AJAX-Aufruf zu benötigen, da der Datenbankinhalt in die ursprüngliche Seite eingebettet ist.
Während diese Lösung für eine kleine Anzahl von Elementen vorzuziehen ist, ist es bei einer Erweiterung der Datenbank auf Tausende von Elementen wahrscheinlich empfehlenswert, zur traditionelleren AJAX-Methode zurückzukehren, da die Dateigröße des servierten HTML-Files unnötig anwachsen würde.
@Benjamin
Das ist genau das, was ich meinte :)
Danke für die bessere Erklärung! Ihr Englisch ist sicher besser als meins :P
Das ist so cool. Früher war das viel Arbeit und Code, um das zu tun. Tolle Arbeit!
Wirklich schönes Tutorial, ich habe bereits ein ähnliches Skript erstellt, aber auf eine etwas andere Weise, aber Ihres ist sehr cool! Ich habe einige Funktionen gelernt, die ich vorher noch nicht gesehen habe.
Einen schönen Tag noch
Wie immer tolle Sachen, Chris, danke!
Es sieht so aus, als ob die Option „Bitte wählen“ einen Wert in der Demo vermisst.
<pre>
<option value=”base”>Bitte wählen Sie aus den obigen Optionen</option>
</pre>
Ich mag die verschiedenen Optionen wirklich. Tolles Tutorial und danke für die Tipps.
Alle 3 Beispiele verwenden $(“#first-choice”).change(function() {…});
um das $.load auszulösen, wenn sich die erste Liste ändert. Aber was ist mit dem Neuladen der Seite oder der Verwendung der ZURÜCK-Taste? Oft erhalten Sie einen anderen Wert als den Standard in Liste #1, aber keine Optionen in Liste #2.
Ein zusätzlicher Befehl $(“#first-choice”).change(); zwingt das Skript, die richtige 2. Liste sofort beim Laden der Seite zu laden. Sie könnten ihn sogar wie folgt am Ende des Hauptbefehls anhängen:
$("#first-choice").change(function() {
$("#second-choice").load("getter.php?choice=" + $("#db-one").val());
}).change();
sollte es nicht sein
$("#first-choice").change(function() {
$("#second-choice").load("getter.php?choice=" + $("#db-one").val());
}).trigger("change");
mit der Methode
trigger()…Ja. Das erste, was jQuery über .change() sagt, ist
„Diese Methode ist eine Kurzform für .bind(‚change‘, handler) in der ersten Variante und .trigger(‚change‘) in der zweiten.“
Also funktioniert beides. Danke, dass Sie darauf hingewiesen haben. Ich habe immer nur $.click() oder $.change() verwendet und kannte die trigger()-Methode, für die sie Kurzformen waren, nicht.
@Rob Young
Danke für den Hinweis…
Soweit ich weiß, simuliert trigger wirklich eine Ereignisaktivierung (und ein Ereignisobjekt wird erstellt und an den Callback übergeben). Der Aufruf wird also weitergegeben und die Ausbreitung kann gestoppt werden…
Vielleicht irre ich mich, aber ich glaube nicht, dass man dasselbe tun kann, indem man die Ereignisfunktion grob aufruft…
Ich werde mich weiter mit der Dokumentation beschäftigen, um diesen Aspekt der Bibliothek gut zu verstehen ;)
Sollte für den letzten Code-Schnipsel nicht $(“#db-one”).val() sein, sondern $(this).val() oder $(“#first-choice”).val()!?
Ja, danke. Ich habe die IDs aus Gründen der Klarheit im geschriebenen Artikel geändert und es übersehen. Behoben.
Können Sie eine eigenständige Version der Datenbankdemo mit SQLite zum Laufen bringen?
Ich weiß nicht viel über SQLite, aber das wäre toll. Wenn Sie es zum Laufen bekommen, würde ich gerne einen Folgeartikel dazu machen.
SQLite ist MySQL ziemlich gleichgestellt. Der Unterschied besteht darin, dass es nicht auf dem Hauptserver hinter den Kulissen gespeichert und aus dem Speicher abgerufen wird, nein, stattdessen sind SQLite-Datenbanken einzelne Dateien direkt in Ihrem FTP, die Sie in PHP öffnen und lesen/schreiben können, genau wie MySQL.
Es gibt jedoch ein paar Haken
* Wenn es groß wird, wird es sehr langsam (jedes Mal, wenn Sie Daten daraus benötigen, muss diese gesamte Datei von der Festplatte aus „geöffnet“ werden.
* Sperren (zwei Personen können nicht gleichzeitig darauf zugreifen). Auch wenn das in der Praxis nicht so oft vorkommt, kann es eine echte Enttäuschung sein.
Gute Seite aber
* Es erfordert keinen Benutzernamen/Passwort oder irgendwelchen „Back-End“-Kram. Das Erstellen der Zeit und das Haben von Lese-/Schreibzugriff (CHMOD) darauf ist ausreichend, und es läuft. Das bedeutet, wenn Sie eine leichtgewichtige Anwendung erstellen, bei der der Kunde keine Dinge in Phpmyadmin einrichten muss, ist es mit SQLIte das Hochladen und loslegen (das PHP-Skript könnte sogar SQLite erstellen, wenn es noch nicht existiert).
Beispiele für PHP5
* http://devzone.zend.com/article/760
* http://www.switchonthecode.com/tutorials/php-tutorial-creating-and-modifying-sqlite-databases
Hallo,
Ich habe die Datenbank und die Dateien erstellt und es funktioniert nicht.
Danke,
Ich habe eine index.html
Wo habe ich das gerade gesehen? ;) http://screenr.com/AKZ
Sehr cooles Tutorial, und viiiiel einfacher, als ich dachte.
Guter Ansatz,
Um die Funktionalität weiter abzusichern, könnten Sie das gesamte System in PHP mit derselben Tabelle betreiben, die Sie gerade haben
+-------+----------+----------+
| index | category | dd_val |
+-------+----------+----------+
| 1 | snack | chips |
| 2 | snack | Cookies |
| 3 | beverage | Coke |
| 4 | beverage | Coffee |
+-------+----------+----------+
im ersten Dropdown laden Sie nur die Kategorien und im zweiten laden Sie alle dd_vals. Sobald der Benutzer das Formular absendet, überprüfen Sie, ob die Kategorie zur dd_val passt. Wenn Sie eine Übereinstimmung erhalten, fahren Sie wie geplant fort, andernfalls lösen Sie einen Fehler aus.
Sobald dieser Teil funktioniert, fügen Sie eine jQuery-Schicht hinzu, um die zweite Liste mit den richtigen dd_vals basierend auf der im ersten Dropdown ausgewählten Kategorie zu füllen.
Auf diese Weise haben Sie einen schönen Fallback, wenn JavaScript nicht funktioniert (entweder weil der Benutzer die Funktion in seinem Browser deaktiviert hat oder weil es einen Fehler im JavaScript selbst gibt).
Ich lese gerne Ihre Artikel. Für den JSON-Teil würde ich vorschlagen
{
"beverages": "Coffee,Coke",
"snacks": "Chips,Cookies"
}
zu ändern zu
{
"beverages": ["Coffee", "Coke"],
"snacks": ["Chips", "Cookies"]
}
Es verwendet ein paar Zeichen mehr, erfasst aber die Absicht der Datenstrukturen besser.
Außerdem entfällt die Notwendigkeit, die
split-Methode aufzurufen, da die Werte bereits in einem Array vorliegen.Genau das wollte ich auch sagen :) JSON verwenden, wie es gedacht war.
Als JavaScript-Fan, der ich bin, habe ich nach einem Kommentar wie Ihrem Steven gesucht ;) Die Verwendung eines Arrays für diese Auflistung würde es Ihnen ermöglichen, etwas wie
vals = data[key] || [‘Bitte wählen Sie aus den obigen Optionen’];
was die Liste aus den Daten anhand des Schlüssels abruft und, falls sie undefiniert ist, auf [‚Bitte wählen‘] zurückgreift
Aber das ist vielleicht nur nebensächlich zum Thema dieses Artikels, der gut zeigt, einige Ihrer Optionen auf.
Das ist großartig, vielen Dank.
Ich habe mir vor ein paar Monaten den Kopf zerbrochen, um das herauszufinden... am Ende habe ich aufgegeben.
Danke für das Tutorial, einfach großartig, wie bereits gesagt, früher war das viel Code und jetzt nur noch zwei einfache, schöne, leicht verständliche Zeilen jQuery und PHP.
Der PHP-Code ist anfällig für SQL-Injection-Angriffe, da Sie die $choice-Variable nicht escapen. Außerdem verwenden Sie die alte MySQL-Bibliothek (die jetzt veraltet ist), sodass sie nur mit MySQL funktioniert. Ich würde vorschlagen, sie auf PDO umzustellen, das neuer ist und mit einigen Datenbanken (SQLite, PostgreSQL, MySQL unter anderem) funktioniert.
Siehe: http://www.webdevrefinery.com/forums/topic/1272-your-mysql-code-sucks/
Danke für einen hervorragenden Beitrag zu dynamischen Dropdowns und drei Ansätzen, einige schöne Ideen, wir nutzen Datenbanken wie gesagt für Flexibilität, sauberen Code und Skalierbarkeit. LT
Es gibt bereits ein jQuery Select Chain Plugin von Remy Sharp, http://remysharp.com/2007/09/18/auto-populate-multiple-select-boxes/, das eine Wrapper für die Funktionalität bietet.
Wir verwenden es viel, alles, was wir tun mussten, war, eine PHP-Wrapper-Funktion zu schreiben, um einen JSON-String aus einem Array von Werten zu generieren, sodass die Quelle der Werte keine Rolle spielt, ob aus einer Datenbank, einer Datei oder einem Webdienst.
Ich stimme Steven Albano zu und würde den Basiswert anstelle des Beibehaltens im Code in die JSON einfügen.
Das Hinzufügen der Optionen funktioniert nicht, da kein Funktionsaufruf vorhanden ist.
Überprüfen Sie das jsfiddle, um zu sehen, wie ich den Code schreiben würde.
Die MySQL-Variante ist im Vergleich zu den beiden anderen etwas umständlich, manchmal kann die Anfrage so langsam sein, dass sie mehrere Sekunden dauert. Wahrscheinlich etwas, das man vermeiden sollte, es sei denn, es gibt keine Alternative.
Argh.. ich sehe veraltete mysql_*-Funktionen.
Gutes Tut trotzdem.
Hallo Chris, tolle Tutorials. Ich habe die Dateien heruntergeladen und es funktioniert gut und ist leicht zu befolgen, aber es funktioniert nicht unter Google Chrome (funktioniert aber unter FF). Bin ich der Einzige, der dieses Problem hat?
Hallo,
Danke für dieses großartige Tutorial ;)
Ich hatte ein Problem mit dynamischen Dropdowns, die eine Datenbank verwenden.
Ich habe 3 Menüs erstellt: das zweite hängt vom ersten ab, das dritte hängt vom zweiten ab.
Aber es gibt ein Problem. Das zweite enthält einige Elemente mit Leerzeichen und Elemente aus einem Wort.
Für Elemente mit einem Wort ist alles in Ordnung.
Aber wenn ich ein Element aus zwei Teilen (das Leerzeichen enthält) auswähle, zeigt das dritte Menü keine Ergebnisse an!
Was denkst du? Was ist das Problem mit Leerzeichen?!
Ich habe die Lösung gefunden
Sie müssen die Variable mit escape() codieren!!! und keine Probleme mehr mit Leerzeichen ;)
escape($(this).val())
Vielleicht sollten Sie das zu Ihrem Code hinzufügen, um ihn perfekt zu machen :D
$(“#first-choice”).change(function() {
$(“#second-choice”).load(“textdata/” + $(this).val() + “.txt”);
});
Tschüss und nochmals danke
@cristi
Ich habe Option 3: Using a Database hier hochgeladen: http://rapidshare.com/files/428684871/dropdown.rar
Legen Sie den Ordner ‚dropdown‘ in Ihren ‚www‘-Ordner. Erstellen Sie in phpMyAdmin eine neue Datenbank und nennen Sie sie ‚dropdown‘. Importieren Sie dann die Datei dd_vals.sql, die sich im Rar-Ordner befindet, und Sie können loslegen. Hoffe, es hilft.
Es ist schön, solch fortgeschrittene Designthemen so detailliert diskutiert zu sehen. Ich mache schon seit einigen Jahren Webdesign und wünschte wirklich, es gäbe solche Ressourcen, als ich anfing. Ich wäre wahrscheinlich mit meiner Webdesign-Karriere viel weiter gekommen.
Ich konnte auch das JSON-Beispiel nicht zum Laufen bringen (fehlender Funktionsaufruf beim Hinzufügen von Select-Optionen zu $secondChoice). Davids jsfiddle-Link hat sehr geholfen.
Hallo, bezüglich der Verwendung der Textdateimethode. Wie würden Sie den Code erweitern, um mehr als zwei Dropdown-Felder zuzulassen?
Liste 1 füllt Liste 2…
Liste 2 füllt Liste 3…
Liste 3 füllt Liste 4…
Vielen Dank.
Hallo,
Ich habe Ihr Tutorial gesehen. Es scheint ein sehr einfacher Weg zu sein, ein Dropdown-Menü zu handhaben, aber entschuldigen Sie, ich kann kein Ergebnis erzielen. Die Fehlermeldung, die ich erhalte, lautet „Undefined index: choice in“
Brauche Ihre Hilfe.
Ripon
Hey,
Ihr Tutorial ist sehr hilfreich, aber ich habe Probleme mit dem dritten Beispiel. Wenn Sie es erneut hochladen könnten (der Link ist kaputt), wäre das schön.
Wenn es nicht zu viel verlangt ist, würde ich gerne alles ohne eine externe Datei wie getter.php machen.
Entschuldigung, wie ändert oder fügt man weitere Optionen zu diesem Dropdown-System hinzu?
Können einige dieser Beispiele von localhost ausgeführt werden? Ich habe Ihre Quelldateien heruntergeladen und versucht, sie von meinem localhost aus zu testen. Keines der Text- oder JSON-Beispiele funktioniert von dort aus. Mein localhost ist richtig verbunden. Danke
Vielen Dank Chris Coyier, das ist wirklich ein großartiges Tutorial. Ich möchte Ihnen eine Frage stellen: Wie kann ich PDO mit dem dritten Beispiel, dem Datenbankbeispiel, verwenden?