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/…32ceead4cfe08470e8e66a7cd

    == 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, 1.640 mal angesehen

    29.382 mal gelesen

Kommentare 1