• Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

jQuery: 'Chain Select' anpassen (+ PHP)

aJunkie

Mitglied
Halli Hallo,

AJAX ist momentan eine Herausforderung für mich.

Ich möchte eine Funktion möglichst allgemein halten und diese ggf. in benötigten Dateien manipulieren, so wie jetzt.

Mein Anliegen ist, dass eine <select> mit Werten aus der Datenbank gefüllt wird. Nach Auswahl einer darin liegenden <option> wird per AJAX eine weitere Information aus der Datenbank geholt. Es handelt sich hier lediglich um ein Integer.
Dementsprechend wird in der zweiten <select> nur eine <option> sein, da in der Datenbank nur ein Integer dazu gibt.
Ich würde gerne mit diesem Wert weiterarbeiten, nämlich diesen Wert in einer for Schleife einbauen und diese soll so viele <option> ausgeben wie die Zahl aus der Datenbank groß ist.

Ich würde dafür gerne möglichst die Funktion selbst nicht anrühren wollen. Geht das im PHP Teil selbst?

HTML:
// CHAIN SELECT
(function ($) {
    $.fn.selectChain = function (options) {
        var defaults = {
            key: "id",
            value: "label"
        };
        
        var settings = $.extend({}, defaults, options);
        
        if (!(settings.target instanceof $)) settings.target = $(settings.target);
        
        return this.each(function () {
            var $$ = $(this);
            
            $$.change(function () {
                var data = null;
                if (typeof settings.data == 'string') {
                    data = settings.data + '&' + this.name + '=' + $$.val();
                } else if (typeof settings.data == 'object') {
                    data = settings.data;
                    data[this.name] = $$.val();
                }
                
                settings.target.empty();
                
                $.ajax({
                    url: settings.url,
                    data: data,
                    type: (settings.type || 'get'),
                    dataType: 'json',
                    success: function (j) {
                        var options = [], i = 0, o = null;
                        
                        for (i = 0; i < j.length; i++) {
                            // required to get around IE bug (http://support.microsoft.com/?scid=kb%3Ben-us%3B276228)
                            o = document.createElement("OPTION");
                            o.value = typeof j[i] == 'object' ? j[i][settings.key] : j[i];
                            o.text = typeof j[i] == 'object' ? j[i][settings.value] : j[i];
                            settings.target.get(0).options[i] = o;
                        }

            // hand control back to browser for a moment
            setTimeout(function () {
                settings.target
                                .find('option:first')
                                .attr('selected', 'selected')
                                .parent('select')
                                .trigger('change');
            }, 0);
                    },
                    error: function (xhr, desc, er) {
                        // add whatever debug you want here.
            alert("an error occurred");
                    }
                });
            });
        });
    };
})(jQuery);
PHP:
if (@$_REQUEST['ajax']):
    $link = mysql_connect('localhost', 'root', '');
    if ($link == false)
        trigger_error('Connect failed - ' . mysql_error(), E_USER_ERROR);

    $connected = mysql_select_db('1555', $link);
    
    if ($connected) {
        $results = mysql_query('SELECT units FROM `e_books` WHERE book_name = "' . mysql_real_escape_string(strip_tags($_REQUEST['selectedBook'])) . '"');
        
        $json = array();
        
        while (is_resource($results) && $row = mysql_fetch_object($results)):
            //$json[] = '{"book_name" : "' . $row->book_name . '"}';
            $json[] = '"'.$row->units.'"';            
        endwhile;
        
        echo '[' . implode(',', $json) . ']';
        die(); // filthy exit, but does fine for our example.
    } else {
        user_error("Failed to select the database");
    }
endif;
//...
<script type="text/javascript">
<!--
// CHAIN SELECT
    $(function () {
        var cat = $('#bookSelect');
        var el = $('#unitSelect');
        
        el.selectChain({
            url: '/school/module/englisch/add_voc.php',
            data: { ajax: true, anotherval: "anotherAction" }            
        });        

        cat.selectChain({
            target: el,
            url: '/school/module/englisch/add_voc.php',
            data: { ajax: true}
        }).trigger('change');

    });
    
//-->
</script>
// ...
            <select id="bookSelect" name="selectedBook">
                <?php
                $q = mysql_query("SELECT book_name FROM `e_books` ORDER BY book_name ASC");
                while($row = mysql_fetch_object($q)):
                    echo '<option>'.htmlspecialchars_decode($row->book_name).'</option>'."\n";
                endwhile;
                ?>
            </select>
            
            <select id="unitSelect" name="selectedBook">
                <option>[none selected]</option>
            </select>
 
Du verwendest doch offensichtlich schon ein Plugin für deinen Zweck Select Chain | jQuery Plugins
Das sollte doch ungefähr das tun was du willst. Was ist jetzt konkret dein Problem damit? Deine Frage:
Ich würde dafür gerne möglichst die Funktion selbst nicht anrühren wollen. Geht das im PHP Teil selbst?
ist nicht sonderlich ergiebig. Man merkt, das es wohl irgendein Problem/Frage gibt, wir verstehen aber nicht wie das Problem lautet.
 
Ja, diesen Plugin nutze ich. Es funktioniert auch.
Ich bekomme durch diesen Plugin eine AJAX-Antwort von der Datenbank. Die Antwort ist eine Ganzzahl. Diese Ganzzahl wird im zweiten <select> als <option> ausgegeben.
1 Antwort == 1 Ganzzahl == 1 <option> Ausgabe

Ich hätte gerne:
for($i = 1; $i < $row->units; $i++):
// so viele <option value="$i"> wie die Zahl aus der AJAX-Antwort STATT <select><option>5</option></select>
endfor;
 
Hast Recht. Warum frage ich sowas, wenn ich übermüdet bin. :)

Ich habe es jetzt so geregelt:
PHP:
// ...
        $json = array();
        
        while (is_resource($results) && $row = mysql_fetch_object($results)):
            //$json[] = '{"book_name" : "' . $row->book_name . '"}';
            
            for($i = 1; $i <= $row->units; $i++):
            $json[] = $i;
            endfor;
            
            #$json[] = '"'.$row->units.'"';            
        endwhile;
        
        echo '[' . implode(',', $json) . ']';

//...
 
Also Ich nehme jetzt mal einen typischen Manga-Reader als Beispiel: So ähnlich klingt dein Problem für mich.
Folgendes Beispiel ist nur um dein Problem zu verstehen und wie man dort vorgehen könnte :)

Das erste Select könnte in dem Beispiel für das Buch stehen:
HTML:
<select name="book" id="bookSelect">
   <option value="op1">One Piece Band 1</option>
   <option value="op2">One Piece Band 2</option>
   <option value="dn1">Death Note Band 1</option>
   <option value="dn2">Death Note Band 2</option>
</select>

Nun legst du einen Event-Handler auf das Select
Code:
 $("#bookSelect").change(getChapter);

Das 2. Select wäre die Anzahl der Kapitel, die du dir erst einmal beschaffen musst. Dafür nutzen für die Funktion getChapter.

Code:
function getChapter(element) {
    // Wie ist das Kürzels des Buchs in der Datenbank
    var bookname = $(element).attr("value");
    $.ajax({
      "url"   : "readChapter",
      "data"  : {
        "book" : bookname,
        "chapterSelectId" : "chapterSelect"
      },
      "onsuccess" : fillChapter,
      "dataType" : "json"
    });
}

Nun sollte von deinem PHP ein Array im JSON-Format zurückkommen. Dabei sollte zunächst einmal der Buchname durchgereicht werden, welcher im assoziativem Array den Namen bookname hat. Desweiteren liest du die Anzahl der kapitel aus der Datenbank welche im Array den Namen Chapter haben sollten.
Damit du das Array als String ausgeben kannst musst du es in JSON umwandeln mit dem Befehl json_encode($array);

Das zurückgegebene JSON kannst du dann weiter mit JS verarbeiten.

Code:
function fillChapter(response) {
   var bookname = response.bookname;
   var chapters = response.chapters;
   var chapterSelect = $("#"+response.chapterSelectId);
   
   // Alte Chapter leeren
   chapterSelect.html("");
   
   // Neue Chapter-Optionen eintragen
   for(var i=1; i <= chapters; i++) {
     chapterSelect.append("<option value='"+bookname+"'>"+i+"</option>");
   }
   
   // Event-Listener auf Options legen
   chapterSelect.find("option").change(selectChapter);
   
}

Wie deine selectChapter Funktion dann aussehen würde weiss ich nicht :)

Du solltest dir nebenbei angewöhnen Funktionen oder sogar Klassen zu verwenden. Denke du bist langsam bereit für den Umstieg. Bist nun ja auch schließlich fast 3 Jahre dabei ;)
 
Vielen Dank, Gilles, für die ausführliche Antwort. Dein Beispiel habe ich verstanden.
Ich habe es momentan so gelöst wie in dem obigen Beitrag von mir. Der kam fast zeitgleich mit deinem.

Wegen Klassen und Funktionen: Ich programmiere halt ziemlich selten... Ich habe es noch vor und notiere mir dementsprechend immer meine Ideen. Irgendwann geht's dann auch los mit den Klassen. :) Vor drei Jahren fragte ich nur mal schnell, wie man ein Bild einfügt, etc und war dann wieder monatelang weg. :P
 
Vielen Dank, Gilles, für die ausführliche Antwort. Dein Beispiel habe ich verstanden.
Ich habe es momentan so gelöst wie in dem obigen Beitrag von mir. Der kam fast zeitgleich mit deinem.

Wegen Klassen und Funktionen: Ich programmiere halt ziemlich selten... Ich habe es noch vor und notiere mir dementsprechend immer meine Ideen. Irgendwann geht's dann auch los mit den Klassen. :) Vor drei Jahren fragte ich nur mal schnell, wie man ein Bild einfügt, etc und war dann wieder monatelang weg. :P

Ich sehe ja ab und zu deine Fragen bezüglich Code. Und man sieht, dass deine Anwendungen immer komplexer werden.
Ich weiß ja nicht wie es dir geht, aber an deiner Stelle hätte ich wohl schon ein wenig den Überblick über meine Anwendung verloren :D
Den Code in Funktionen oder in Klassen zu kapseln schafft dir einen guten Überblick über deine Anwendung. Wenn du dann fragen dazu hast --> Fragen :)
 
:) Ja Gilles. Wenn ich mal ordentlich Zeit finde, möchte ich mich in die PHP-LernDVD einarbeiten. ^^ Da wird die Objektorientierung durchgenommen.

// Edit: Und die Nachfrage hat sich erledigt. :)
 
Zuletzt bearbeitet:
Zurück
Oben