Select-Auswahl mit AJAX Abhängigkeit

Diese Seite verwendet Cookies. Durch die Nutzung unserer Seite erklären Sie sich damit einverstanden, dass wir Cookies setzen. Weitere Informationen

  • Dieses Tutorial vermittelt die Kenntnisse um beliebig viele Select-Felder mit AJAX zu verbinden.
    == Code ==
    index.html

    Quellcode

    1. <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
    2. <html xmlns="http://www.w3.org/1999/xhtml" dir="ltr" xml:lang="de">
    3. <head>
    4. <meta http-equiv="content-type" content="text/html; charset=UTF-8" />
    5. <title>Select-Auswahl mit AJAX Abhängigkeit</title>
    6. <script type="text/javascript" src="script.js"></script>
    7. <style type="text/css">
    8. <!--
    9. /* demostyle - not necessary to make it work*/
    10. body{font-size:11pt;font-family:Verdana,Arial,Sans}
    11. //-->
    12. </style>
    13. </head>
    14. <body onload="sendRequest(null, 'elem1')">
    15. <form method="post" action="" id="ajaxSelect">
    16. <table>
    17. <tr id="elem1" style="display:none">
    18. <td>HauptKategorie:</td>
    19. <td><select name="hauptkategorie" size="4" onchange="sendRequest(this, 'elem2')"><option value=""></option></select></td>
    20. </tr>
    21. <tr id="elem2" style="display:none">
    22. <td>UnterKategorie:</td>
    23. <td><select name="unterkategorie" size="4" onchange="sendRequest(this, 'elem3')"><option value=""></option></select></td>
    24. </tr>
    25. <tr id="elem3" style="display:none">
    26. <td>UnterUnterKategorie1:</td>
    27. <td><select name="unterunterkategorie" size="4" onchange="sendRequest(this, 'elem4')"><option value=""></option></select></td>
    28. </tr>
    29. <tr id="elem4" style="display:none">
    30. <td>UnterUnterKategorie2:</td>
    31. <td><select name="unterunterkategorie" size="4" onchange="sendRequest(this)"><option value=""></option></select></td>
    32. </tr>
    33. </table>
    34. <div>
    35. <input type="submit" />
    36. </div>
    37. </form>
    38. </body></html>
    Alles anzeigen


    script.js

    Quellcode

    1. /**
    2. * clears a select form element
    3. *
    4. * @param targetSel - dom reference to the select element
    5. */
    6. function clearSelect(targetSel) {
    7. for (var i=targetSel.length; i>=0; i--) {
    8. targetSel.options[i] = null;
    9. }
    10. }
    11. /**
    12. * sends a request under usage of a loading graphic - targettable has to be positioned relative
    13. *
    14. * @param srcref - reference to the select element with chosen data
    15. * @param target - form element name of target element
    16. */
    17. function sendRequest(domref, target) {
    18. // skip if no target specified
    19. if(!target) return false;
    20. // save reference to next target
    21. if(domref) domref.followup = target;
    22. var req;
    23. try {
    24. req = window.XMLHttpRequest ? new XMLHttpRequest():
    25. new ActiveXObject("Microsoft.XMLHTTP");
    26. } catch (e) {
    27. // no AJAX Support
    28. }
    29. req.onreadystatechange = function() {
    30. if ((req.readyState == 4) && (req.status == 200)) {
    31. // merge empty line with response
    32. var data = eval('(' + req.responseText + ')');
    33. var targetRef = document.getElementById(target);
    34. var targetSel = targetRef.getElementsByTagName('select')[0];
    35. // make it visible
    36. targetRef.style.display = 'block';
    37. // clear old data
    38. clearSelect(targetSel);
    39. // fill with data from json response
    40. var i=0;
    41. for(var x in data) {
    42. targetSel.options[i++] = new Option(
    43. data[x].text,
    44. data[x].id
    45. );
    46. }
    47. // clear all followups
    48. while(targetSel.followup) {
    49. targetRef = document.getElementById(targetSel.followup);
    50. // make it hidden
    51. targetRef.style.display = 'none';
    52. // mark next select
    53. targetSel = targetRef.getElementsByTagName('select')[0];
    54. // clear old data
    55. clearSelect(targetSel);
    56. }
    57. }
    58. }
    59. req.open('post', 'ajax.php');
    60. req.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
    61. // send empty post with initial load
    62. req.send(domref !== null ? 'id='+domref.value+'&name='+domref.name : '');
    63. return false; // return false to avoid reload/recentering of the page
    64. }
    Alles anzeigen


    ajax.php
    Die meisten werden in dem Umgang mit einer Datenbank vertraut sind. Die ajax.php empfängt eine $_REQUEST Variable "id" und muss eine zweidimensionales Array mit den Schlüsseln "id" und "key" zurückgeben. Auf Basis des PDO Tutorials habe ich folgenden Demo Code erstellt:

    Quellcode

    1. <?php
    2. $sql = "SELECT id, text
    3. FROM category
    4. WHERE parentID = :id";
    5. $stmt = MyDB::getInstance()->prepare($sql);
    6. $stmt->execute(array(
    7. ':id' => $_REQUEST['id']
    8. ));
    9. $return = $stmt->fetchAll();
    10. echo json_encode($return);
    11. ?>
    Alles anzeigen


    Für das Demoscript habe ich folgenden Code bereitgestellt:

    Quellcode

    1. <?php
    2. // u can use $_POST['name'] to build your controller depending on the form name
    3. // but in a category tree the name is not important, we just need the parent id
    4. $id = isset($_REQUEST['id']) ? $_REQUEST['id'] : 0;
    5. // (1) example array with four main categories
    6. for($i=0; $i<4; $i++) {
    7. // four subcategories each
    8. for($j=($i*10); $j<($i*10)+3; $j++) {
    9. $idx = $j+1;
    10. $data[$i][$j] = array(
    11. 'id' => $idx,
    12. 'text' => sprintf('cat %d (parent:%d)', $idx, $i),
    13. );
    14. // with three childs eiter
    15. for($k=($idx*10); $k<($idx*10)+3; $k++) {
    16. $data[$idx][$k] = array(
    17. 'id' => $k,
    18. 'text' => sprintf('subcat %d (parent:%d)', $k, $idx),
    19. );
    20. }
    21. }
    22. }
    23. // access the childs with its parent index
    24. $return = $data[$id];
    25. echo json_encode($return);
    26. ?>
    Alles anzeigen


    == Abhängige Felder definieren ==
    Das Beispiel lässt sich um beliebig viele Select-Auswahlfelder erweitern. Ihr müsst der Methode sendRequest als ersten Parameter immer this übergeben und als zweiten Parameter die ID des Container, der das abhängige Select-Feld enthält.
    Am Ende der Kette - wenn also keine abhängigen Felder mehr nachgeladen werden sollen - übergebt ihr einfach gar keinen Parameter.

    Quellcode

    1. <tr id="elem1">
    2. <td>Haupt Kategorie:</td>
    3. <td><select onchange="sendRequest(this, 'elem2')"></select></td>
    4. </tr>
    5. <tr id="elem2">
    6. <td>Unter Kategorie:</td>
    7. <td><select></select></td>
    8. </tr>


    == Felder nicht verstecken ==
    Im konkreten Beispiel wurde entschieden abhängige Select-Auswahlfelder erst anzuzeigen, sobald das Elternelement die notwendige Auswahl getroffen hat. Sollte es besser ins Layout passen und ihr wollt stattdessen leere Listenelemente verwendet, so entfernt einfach die style Eigenschaft display:none. Das müsst ihr sowohl im HTML Code machen, als auch alle display Aufrufe im Quelltext entfernen.

    == Demo ==
    Eine Live Demo findet ihr unter demo.easy-coding.de/ajax/selec…hl-mit-ajax-abhaengigkeit. Des weiteren wird der kompletten Code hier als ZIP Archiv zur Verfügung gestellt: download.zip.

    easy-coding.de/Attachment/564/…dd33da3461029ab64892b3371

    == Fortsetzung ==
    Mehr Informationen zum Datenbankbeispiel findet ihr auch hier: [wiki]Select-Auswahl mit AJAX Abhängigkeit und verschiedenen Tabellen[/wiki]
    Bilder
    • select-auswahl-mit-ajax-abhaengigkeit.png

      4,69 kB, 318×217, 2.358 mal angesehen

    36.876 mal gelesen

Kommentare 3

  • Torben Brodt -

    Hi,
    könntest du mit deinem Code ein neues Posting im Forum erstellen?
    Dein Vorposter hat sein Array Problem übrigens hier gelöst: [url='http://www.easy-coding.de/schleife-in-ajax-php-durch-einen-array-ersetzen-t7146.html']Schleife in ajax.php durch einen array ersetzen[/url]
    Lg

  • Chrisssss -

    Ich habe evtl. den Fehler gefunden, weiß aber nicht, wie er zu beheben ist.

    Beim debuggen habe ich herausgefunden, dass meine ajax.php folgendes antwortet:
    [quote] [][{"id":1,"text":"cat 1 (parent:0)"},{"id":2,"text":"cat 2 (parent:0)"},{"id":3,"text":"cat 3 (parent:0)"}] [/quote]Das online-Beispiel antwortet hingegen
    [quote] [{"id":1,"text":"cat 1 (parent:0)"},{"id":2,"text":"cat 2 (parent:0)"},{"id":3,"text":"cat 3 (parent:0)"}] [/quote]Der Unterschied ist, dass bei mit anscheinend eine leere Node am Anfang ist.
    Woran kann das liegen? Wie kann ich es beheben?

    Für Hilfe wäre ich sehr dankbar.

  • Chrisssss -

    Hallo,

    Ich versuche das Script zu verstehen. Leider zeigt er bei mir nur eine leere Hauptkategorie an.

    Welche Struktur und Inhalte hat die BeispielDB? Vieleicht hilft mir das beim Verständnis weiter.

    LG,
    Christoph

  • pegatech -

    Guten Tag
    Ich möchte die verschachtelte Schleife in ajax.php (die wie ich gesehen habe auch einen Array erzeugt), durch einen statischen Array ersetzen.
    Versucht habe ich den Array den die Schleife erzeugt nachzubauen (mit anderen Werten halt), wenn ich nun die Schleife durch meinen statischen array austauschen möchte,
    so bekomme ich nachher in der index.html nur den erstel Wert zu sehen. Hat also bei mir nicht geklappt ohne das ich wüsste warum.

    Wie müsste den ein array aussehen mit dem ich in der ajax.php die Werte (cat1,cat2,cat21,cat22) duch meine eigene ersetzen könnte?
    Das ajax.php ist als Textform als Anhang dazugesendet, falls jemand Details von meinem selbstgebauten Array ansehen möchte.

    Ich wäre um jeden Tipp dankbar
    herzliche Grüsse

    M.Koller

  • Torben Brodt -

    Hallo, ich glaube nicht, dass es ein Schlüsselwortproblem ist.
    Evtl erzeugt new Option beim IE kein DOM Element, dass sich mit appendChild einhängen lässt.

    Ich habe die Schleife jedenfalls folgendermaßen abgeändert:
    [syntax="javascript"]var i=0;
    for(var x in data) {
    targetSel.options[i++] = new Option([/syntax]

    Lg

  • Tilman -

    Hallo,
    das Problem ist, dass im IE data[x].text (Zeile 47 im JavaScript) ein reserviertes Schlüsselwort ist. Wenn man das durch data[x].texte ersetzt geht es. Natürlich ist dann auch noch die ajax.php entsprechend anzupassen, in Zeile 13 und Zeile 20 jeweils das 'text' => sprintf(...)... durch ein 'texte' ersetzten.
    Viel erfolg beim Einsetzen des Skriptes und noch ein herzliches Dankeschön an die Macher des Skripts!!!
    Tilman

  • xac -

    hallo easy coding,

    ich habe das selbe phänomen, wie schnoerp. da diese lösung die bisang beste im netz ist, würde ich mich über die lösung des problems ebenso freuen.

    problem ist folgendes: das select feld wird gefüllt, es ist klickbar (also values wurden gesetzt) nur ist der text nicht lesbar...

    getestet unter msie 6 und 7

    viele grüße xac

  • Schnoerp -

    Hallo,

    im Internet Explorer sind in deiner Demo keine Bezeichnungen der Options vorhanden.
    Gibts da schon eien Lösung ?