" Dropdown aus array in abhängigkeit laden


JuSeCo

Grünschnabel
PHP:
           <?php
                    $statement = $pdo->prepare("SELECT DISTINCT * FROM de_ger_kat_branchen GROUP BY ueber_kat ");
                       $result = $statement->execute(array(':ueber_kat' => "ueber_kat", ':unter_kat' => "unter_kat"));
                    $kat = $statement->fetchAll(PDO::FETCH_ASSOC);
            ?>
                <select name="main" id="ueberkat" onchange="return showUnterkat">
                    <?php
                        foreach($kat as $row) {
                            echo "<option name=" . $row['ueber_kat'] . " value=" . $row['ueber_kat'] . " > " . $row['ueber_kat'] . "</option>";
                      
 
 
                    
                        }
                    ?>
 
                </select>
                <select name="sub">
                    <?php

                    
                        foreach($kat as $row2) {
                            echo "<option name=" . $row2['unter_kat'] . " value=" . $row2['unter_kat'] . " > " . $row2['unter_kat'] . "</option>";
                      
 
 
                    
                        }
                    ?>               
                
                
                
                </select>
Hey Leute,

ich habe hier 2 Probleme, zunächst mein Plan. Ich Lade aus einer DB Daten in ein Array und diese sollen dann in 2 Verschiedene Dropdown Menus. In der DB sind die Daten wie folg:

ID - ueber_kat - unter_kat

1 - Haus - Boden
2 - Haus - Flur
3 - Auto - Reifen
usw.

Nun Möchte ich ueber_kat in das erste Dropdown, wobei ich keine doppelten Einträge möchte. das ginge mit DISTINCT oder GROUP BY.
Dadurch verliere ich jedoch datein im Array soweit ich das verstanden habe und in der print_f() ausgabe sehe.

Des weiteren ist es so, dass ich möchte das das 2te Dropdown neu geladen wird in abhängigkeit vom ersten, dort sollen dann die entsprechenden unter_kat werte eingetragen sein.

Die daten in der DB sind mit 93 einträgen absolut fest und werden nicht mehr erweitert weshalb ich damit einverstanden bin diese alle gleichzeitig im Array zu haben und nehme den trafic verlust in kauf.

Bisher habe ich folgendes:
 

Sempervivum

Erfahrenes Mitglied
Die daten in der DB sind mit 93 einträgen absolut fest und werden nicht mehr erweitert weshalb ich damit einverstanden bin diese alle gleichzeitig im Array zu haben und nehme den trafic verlust in kauf.
Stimme zu: Wenn es nur so wenige Daten sind, lohnt es sich nicht, clientseitig die Daten für das zweite Dropdown nachzuladen. Ich würde die Daten so wie sie sind über JSON an Javascript übergeben und daraus zwei Arrays bzw. Objekte aufbauen:
Das erste für das erste Select mit Haus, Auto, ...
Das zweite für das zweite Select als Objekt bzw. ass. Array mit Haus, Auto, ... als Schlüssel

Natürlich könntest du, wenn Du eine serverseitige Lösung bevorzugst, alle Selects mit PHP aufbauen und dann dass richtige zweite mit Javascript sichtbar machen. Dabei wäre das Datenvolumen wahrscheinlich größer aber bei 93 Einträgen sicher auch kein Problem.
 

JuSeCo

Grünschnabel
Danke für die Rasche antwort. Mit JS bin ich leider gar nicht bewandert lese jedoch weiter an Lösungen.

Habe es nun soweit geschafft, dass ich im ersten Dropdown die einträge nur noch einmal angezeigt bekomme indem ich das array vorher groupe.

Gibt es evt eine einfache Lösung um nun das 2te richtig auswählen zu lassen? Im Grunde bräuchte ich einen Befehl der sagt das bei onChange vom ersten select der Value der option an das 2te Selectfeld übergeben wird und dieses Neu aus dem Array anzeigt.


PHP:
            <?php
                    $statement = $pdo->prepare("SELECT * FROM de_ger_kat_branchen  ");
                       $result = $statement->execute(array(':ueber_kat' => "ueber_kat", ':unter_kat' => "unter_kat"));
                    $kat = $statement->fetchAll(PDO::FETCH_ASSOC);


                    foreach ( $kat as $value ) {
                        $group[$value['ueber_kat']] = $value;
                    }
                                
                    ?>
                <select name="main" id="ueberkat" >
                    <?php


                        foreach($group as $row) {
                            echo "<option name=" . $row['ueber_kat'] . " value=" . $row['ueber_kat'] . " > " . $row['ueber_kat'] . "</option>";
                
                        }
                    ?>
 
                </select>
                <?php echo $row['ueber_kat']; ?>
                <select name="unterkat" id="unterkat">
                    <?php

                    
                        foreach($kat as $row2) {
                            echo "<option name=" . $row2['unter_kat'] . " value=" . $row2['unter_kat'] . " > " . $row2['unter_kat'] . "</option>";
                      
 
 
                    
                        }
                    ?>
 

Sempervivum

Erfahrenes Mitglied
Offenbar bist Du mit PHP und SQL besser vertraut als mit Javascript.
Gibt es evt eine einfache Lösung um nun das 2te richtig auswählen zu lassen? Im Grunde bräuchte ich einen Befehl der sagt das bei onChange vom ersten select der Value der option an das 2te Selectfeld übergeben wird und dieses Neu aus dem Array anzeigt.
Wenn es beim onchange ausgeführt werden soll, ohne dass der Benutzer einen Submit-Button drücken muss, braucht es AFAIK Javascript.
Angenommen, Du hast alle Selects in dieser Form definiert:
HTML:
<select id="ueberkat">
    <!-- hier deine Optionen -->
</select>
<select class="unterkat" id="unterkat-Haus">
    <!-- hier deine Optionen -->
</select>
<select class="unterkat" id="unterkat-Auto">
    <!-- hier deine Optionen -->
</select>
Dann würde dieses JS das richtige Select sichtbar machen und alle anderen unsichtbar:
Javascript:
var unterkats = document.querySelectorAll('select.unterkat');
document.getElementById('ueberkat').addEventListener('change', function() {
    for (var i = 0; i < unterkats.length; i++) {
        if (unterkats[i].id == 'unterkat-' + this.value) {
            // es handelt sich um das select, das zu der ausgewählten Ueberkategorie gehoert
            // wir machen es sichtbar
            unterkats[i].style.display = 'block';
        } else {
            // es handelt sich um eines der anderen Selects
            // wir machen es unsichtbar
            unterkats[i].style.display = 'none';
        }          
    }
})
(ungetestet)
 

JuSeCo

Grünschnabel
Danke erneut für die Antwort.
Du hast recht, mit JS kenne ich mich nahezu gar nicht aus. Beim lesen verstehe ich zwar ungefähr was es machen soll und kann kleine anpassungen vornehmen, dass war es derzeit aber auch schon.
Zu deinem Script, es funktioniert in der Form nicht.
Ich weiß eine schlechte beschreibung. Ich habe nun mal alles in die selbe datei gepackt um sicher zu gehen das es nicht zu fehlern kommt weil das script nicht richtig erkannt wird. Im Grunde kann ich nur sagen, dass nichts passiert. Alle Selectfelder sind sichtbar und ohne Inhalt.

Dennoch zu meinem Verständnis.

JS Zeile 4 soll in der ID nach unterkat- suchen und this.value wäre dann der Wert aus der Db den ich im ersten selectfeld auswähle. Nur um das für die zukunft verstanden zu haben?

Sonst habe ich das script so verstanden, das ich zunächst eine variable erzeuge namens unterkats. Und diese soll dann ein selectfeld namens unterkat beeinflussen, deswegen select.unterkat.

Nächste Zeile ruft dann ueberkat ab und führt beim wechsel (change) die function aus?

Hoffe das so richtig verstanden zu haben.
 

Sempervivum

Erfahrenes Mitglied
Ja, dieses JS war ungetestet und sollte nur eine grobe Starthilfe sein.
Etwas wichtiges hatte ich unterschlagen: Damit am Anfang die Selects mit den Unterkategorien alle unsichtbar sind, braucht es noch ein wenig CSS:
Code:
select.unterkat {
    display: none;
}
Die anderen Fragen versuche ich in den Kommentaren zu beantworten:
Code:
// Wir erzeugen zunaechst eine Liste (Nodelist, im wesentlichen ein Array)
// der Selects mit den Unterkategorien
var unterkats = document.querySelectorAll('select.unterkat');
// Eventlistener für das Select mit den Oberkategorien registrieren
// Die anonyme Funktion wird aufgerufen, wenn sich die ausgewaehlte Option aendert
document.getElementById('ueberkat').addEventListener('change', function() {
    // in this.value steht jetzt der Wert (Auto, Haus, ...) der ausgewaehlten Option
    // zur Verfuegungn
    // Wir arbeiten nun alle Selects der Unterkategorien ab
    for (var i = 0; i < unterkats.length; i++) {
        // Pruefung, ob das aktuelle Select zu der in der Oberkategorie ausgewaehlten
        // Option gehoert. Dies ist z. B. der Fall wenn in Oberkategorie "Haus"
        // ausgewaehlt wurde und das Select für die Unterkategorie die id
        // "unterkat-Haus" hat
        if (unterkats[i].id == 'unterkat-' + this.value) {
            // es handelt sich um das select, das zu der ausgewählten Ueberkategorie gehoert
            // wir machen es sichtbar
            unterkats[i].style.display = 'block';
        } else {
            // es handelt sich um eines der anderen Selects
            // wir machen es unsichtbar
            unterkats[i].style.display = 'none';
        }         
    }
})
Alle Selectfelder sind sichtbar und ohne Inhalt.
Du musst sie natürlich durch PHP mit Inhalt füllen. Dort wo ich als HTML-Kommentar geschrieben habe:
"hier dein Optionen"
musst Du die Optionen hinein generieren.
 

Sempervivum

Erfahrenes Mitglied
PS: Hier noch eine getestete Demo:
Code:
    <style>
        select.unterkat {
            display: none;
        }
    </style>
    <select id="ueberkat">
        <option>Haus</option>
        <option>Auto</option>
    </select>
    <select class="unterkat" id="unterkat-Haus">
        <option>Fenster</option>
        <option>Tuer</option>
    </select>
    <select class="unterkat" id="unterkat-Auto">
        <option>Reifen</option>
        <option>Motor</option>
    </select>
    <script>
        // Wir erzeugen zunaechst eine Liste (Nodelist, im wesentlichen ein Array)
        // der Selects mit den Unterkategorien
        var unterkats = document.querySelectorAll('select.unterkat');
        // Eventlistener für das Select mit den Oberkategorien registrieren
        // Die anonyme Funktion wird aufgerufen, wenn sich die ausgewaehlte Option aendert
        document.getElementById('ueberkat').addEventListener('change', function () {
            // in this.value steht jetzt der Wert (Auto, Haus, ...) der ausgewaehlten Option
            // zur Verfuegungn
            // Wir arbeiten nun alle Selects der Unterkategorien ab
            for (var i = 0; i < unterkats.length; i++) {
                // Pruefung, ob das aktuelle Select zu der in der Oberkategorie ausgewaehlten
                // Option gehoert. Dies ist z. B. der Fall wenn in Oberkategorie "Haus"
                // ausgewaehlt wurde und das Select für die Unterkategorie die id
                // "unterkat-Haus" hat
                if (unterkats[i].id == 'unterkat-' + this.value) {
                    // es handelt sich um das select, das zu der ausgewählten Ueberkategorie gehoert
                    // wir machen es sichtbar
                    unterkats[i].style.display = 'block';
                } else {
                    // es handelt sich um eines der anderen Selects
                    // wir machen es unsichtbar
                    unterkats[i].style.display = 'none';
                }
            }
        });
    </script>
 

JuSeCo

Grünschnabel
So, nachdem ich nun seit heute morgen ca 10 Uhr bis jetzt dran saß und viel Probiert und gelesen habe bin ich zum erfolg gekommen. Vorab ist zu sagen, dass ich auf eine Lösung zurück gegriffen habe die ich vermeiden wollte. Mein Ursprünglicher Plan war, dass ich aus der DB abfrage direkt die selectfelder für das 2te Mitbefüllen kann, doch dies erwies sich als extrem Problemetisch für mich da ich es nicht geschafft habe das nur die zugehörigen Felder im Select2 eingetragen werden sondern immer alle oder immer die selben 14 stück. 14, weil ich 14 verschiedene auswahlen in select1 habe.

Dennoch, vielen vielen dank für deine Mühe. Mit deinem Script hatte ich die Grundlage, auf der meine jetzige Lösung beruht.
2 Dinge haben mir bei deiner Lösung zunächst Probleme bereitet.
1. Wenn man in select 1 die erste auswahl beibehalten möchte muss man erst die 2te wählen um die erste nehmen zu können.
2. Ich habe den css teil in meine css datei gepackt und das funktionierte bei meiner Lösung nicht mehr. Bei deiner jedoch Super.

Also, hier meine Lösung, die ich nur dank dir schaffen konnte:

PHP:
                    $statement = $pdo->prepare("SELECT * FROM de_ger_kat_branchen  ");
                       $result = $statement->execute(array(':ueber_kat' => "ueber_kat", ':unter_kat' => "unter_kat"));
                    $kat = $statement->fetchAll(PDO::FETCH_ASSOC);

                     foreach ($kat as $value) {
                        $group[$value['ueber_kat']] = $value;
                    }
                    
                    echo "<select id=ueberkat >";
                                echo "<option value=err>Bitte wählen...</option>";
                                foreach($group as $row) {   
                                    echo "<option value=".str_replace(" ", "", $row['ueber_kat']).">".$row['ueber_kat']."</option>";
                                }
                    echo "</select>";               
                    

                    foreach($group as $row['ueber_kat'] => $ss) {
                            
                        $statement = $pdo->prepare("SELECT * FROM de_ger_kat_branchen WHERE ueber_kat = :ueber_kat ");
                        $statement->execute(array(':ueber_kat' => $row['ueber_kat']));
                            echo "<select style=display:none;  class=unterkat id=unterkat-".str_replace(" ", "", $row['ueber_kat']).">";
                            echo "<option value=err>Bitte wählen...</option>";
                                while($row = $statement->fetch()) {
                                    echo "<option value=".str_replace(" ", "", $row['unter_kat']).">".$row['unter_kat']."</option>";
                                }
                            echo "</select>";
                        }
 

JuSeCo

Grünschnabel
Ich muss mich zu diesem Thema nochmal melden. Ich habe ein Problem damit, die aus dem 2ten Select feld geladenen Daten in einer db zu speichern. Er speichert immer err ab. es scheint als würde er die neu geladenen optionen nicht erkennen. diese werden im Quelltext jedoch angezeigt.

Die scripte sind wie oben erwähnt.

EDIT:

Ich habe versucht eine weitere JS abfrage zu erzeugen, jedoch scheitert es dann daran das ich zu dem 2ten Select keine eindeutige ID habe und ich ja keine 2te angeben kann.

mit

<script type="text/javascript">
function funktion(obj)
{
alert(obj.options[obj.selectedIndex].text)
}
</script>

wir mir bei jedem wechsel der richtige wert als alert fenster angezeigt.