Dropdown-Feld aus Datenbank füllen

ShadowMan

Erfahrenes Mitglied
Hi zusammen!

Ich sitze gerade schon mehrere Stunden vor einem Problem und im Netz konnte ich leider auch keine passende Antwort dazu finden. Javascript ist nicht gerade meine Stärke, daher frage ich jetzt einfach mal.

Folgendes möchte ich machen:
Ich habe ein Dropdown-Feld. Dieses wird durch eine Datenbank in php gefüllt. Wenn sich nun der Wert dieses Feldes ändert, also onchange, soll ein weiteres dropdown-Feld erscheinen. Soweit auch kein Problem. In diesem Dropdown-Feld sollen nun weitere Werte aus einer Datenbank ausgelesen werden. Wenn ich nun also einen Wert aus dem ersten Feld auswähle, soll eine Datenbankabfrage mit WHERE = aktuellerWert gestartet werden. Diese Daten sollen dann wie beim ersten Feld in die Dropdownliste geschrieben werden.

Mein Problem liegt größtenteils darin, den aktuellen Wert zu übergeben. Wie ich ihn herausfinde ist weniger das Problem. Dazu kommt, dass die Dropdownliste dann natürlich gefüllt werden muss. Ich denke das muss dann auch via Javascript geschehen, da es ja keinen Sinn macht, das Feld in PHP zu füllen, da sich der Inhalt ja erst zur Laufzeit ändert.

Ich bin dankbar für jeden Hinweis,
Manuel ;-]
 
Die unkomplizierteste Sache wäre wohl eine Serveranfrage per XMLHttpRequest.

Also folgendermassen:
die Auswahl ändert sich => du fragst ein PHP-Skript ab, welchem du als Parameter den Wert der Auswahl übergibst. Das macht sodann die Datenbankabfrage und antwortet mit dem HTML-Code für die neue Liste. Diesen fügst du ein, indem du an der jeweiligen Stelle zuerst einen Knoten einfügst(z.B. per appendChild())...und dann dessen innerHTML-Eigenschaft die Antwort des PHP-Skriptes zuweist.
 
Okay, darunter kann ich mir jetzt nur sehr schwierig etwas vorstellen. Ich mache das ja über "onchange" und darüber rufe ich doch ein JS auf, nicht eine PHP-Funktion, oder doch?

Und du meinst ich soll darüber eine php-Funktion aufrufen, diese macht dann die Datenbankanfrage und mit den Daten soll ich dann einfach die Dropdownliste über JS füllen?

Hättest du dafür vielleicht ein klitzekleines Beispiel *gaaaaanz nett frag*

Lieben Gruß und vielen Dank,
Manuel ;-]
 
So...wie gewohnt bei mir später als versprochen :-(

erstmal der PHP-Teil(statt ner DB hab ich hier nen Array genommen, damit mans einfacher selbst probieren kann)
PHP:
//box.php-Ausgabe der <select>

<?php
//die "Datenbank"...2. Array-Element ist immer der Index der "Elternliste"
$db=array(
  array('Zeugs',-1),
  array('Drinks',0),
  array('Essen',0),
  array('Bier',1),
  array('Budweiser',3)
  //usw.
);


//Ausgabe der Liste, erwartet als Parameter den Index der Liste in $db

function make_box($parent)
{
  global $db;
  if(@!isset($db[$parent]))return;
  
  $items=0;
  
  $box='<select name="box['.$db[$parent][0].']" onchange="request_data(this) ">
        <option value="-1">Auswahl</option>';
        
  
      foreach($db as $key => $arr)
        {
          if($parent==$arr[1] )
            {
              $items=1;
              $box.='<option value="'.$key.'">';
              $box.=htmlentities($arr[0]);
              $box.='</option>';
            }
        }
  
  $box.='</select>';
  
  return(($items)?$box:'');
}

//wurde dem Skript per GET ein Parameter "box" übergeben, 
//gibt es die entsprechende Liste aus

@print(make_box($_GET['box']));
  
?>

Die JS-Sachen:
Code:
 lock = false;//sperre bei laufendem request
 req  = false;//request-objekt
 objLayer=false;//container für die boxen
	
 if(window.XMLHttpRequest) 
  {
   try 
    {
     req = new XMLHttpRequest();
    } 
   catch(e) 
    {
     req = false;
    }
   } 
  else if(window.ActiveXObject) 
   {
    try 
     {
      req = new ActiveXObject("Msxml2.XMLHTTP");
     } 
    catch(e) 
     {
      try 
       {
        req = new ActiveXObject("Microsoft.XMLHTTP");
       } 
      catch(e) 
       {
        req = false;
       }
     }
   }

Die Variablen eingangs habsch drinnen kommentiert, im Teil danach wird versucht, ein XMLHttpRequest-Objekt zu erzeugen.
Die vorgehensweise ist je nach Browser/Browserversion unterschiedlich, deshalb so viel Code.

Die Funktion für onchange
Code:
function request_data(objBox) 
{
 if(!req)
  {
   alert('dein Browser kann das nicht :o(');
   return;
  }
        
 if(lock)
  {
   alert('Warte bitte, bis die letzte Anfrage verarbeitet wurde');
   return;
  }
    //Elternknoten der Liste in Variable speichern für bequemeren Zugriff  
   objLayer=objBox.parentNode;
   
    //für weitere Requests sperren
   lock = true;
   
   for(i=objLayer.childNodes.length-1;i>0;--i)
    {
      if(objLayer.childNodes[i]==objBox)break;
        //alle Listen nach der aktuellen entfernen
      objLayer.removeChild(objLayer.childNodes[i]);
    }
   
    //Funktionsaufruf beim Ändern des Status der Anfrage
   req.onreadystatechange = new Function('f','get_http_response()');
    
    //Verbindung zum Server öffnen
   req.open("GET", 
            'box.php?box='+ objBox.value + '&amp;' + new Date().getTime(), true);
    
    //Anfrage senden
   req.send(true);
  
}

Übergeben wird als Parameter die Liste selbst.
Zuerst 2 Abfragen, ob XMLHttpRequest verfügbar ist und nicht grad ein Request läuft.
Der Rest ist wieder im Skript kommentiert.

Funktion, welche die Antwort des Servers verarbeitet:
Code:
//Antwort verarbeiten
function get_http_response()
{
 //Wenn Anfrage fertig
 if(req.readyState == 4)
  {   
   //Wenn Status OK
   if(req.status == 200)
    {
     //Antwort ausgeben
     objLayer.appendChild(document.createElement('span'));
     objLayer.lastChild.innerHTML=req.responseText;
                
     //sperre entfernen
     lock=false
    }
   //Ansonsten
   else
    {
     //Statuscode ausgeben
     alert(req.statusText);
    }
   //Request beenden
   if(document.all && !window.opera)
    {
     req.abort();
    }
   lock = false;
  }
}

Das wars schon... falls die Erläuterung nicht ausführlich genug gewesen sein sollte, frag nach :)

Hier das Ganze zum Testen incl. Sourcen:dynamische Comboboxen mit XMLHttpRequest
 
Hier noch mal das Beispiel mit ner DB, weil das nachgefragt wurde...Prinzip ist dasselbe:
Code:
#
# Tabellenstruktur für Tabelle `tabelle`
#

CREATE TABLE tabelle (
  id smallint(6) NOT NULL auto_increment,
  pid smallint(6) NOT NULL default '0',
  title varchar(64) NOT NULL default '',
  PRIMARY KEY  (id),
  UNIQUE KEY id (id),
  KEY id_2 (id)
) TYPE=MyISAM;

#
# Daten für Tabelle `tabelle`
#

INSERT INTO tabelle VALUES (1,0,'Zeugs');
INSERT INTO tabelle VALUES (2,1,'Drinks');
INSERT INTO tabelle VALUES (3,1,'Essen');
INSERT INTO tabelle VALUES (4,2,'Bier');
INSERT INTO tabelle VALUES (5,4,'Budweiser');
INSERT INTO tabelle VALUES (6,4,'Zäpfle');
INSERT INTO tabelle VALUES (7,4,'Edelstoff');
INSERT INTO tabelle VALUES (8,2,'Sprit');
INSERT INTO tabelle VALUES (9,8,'Wodka');
INSERT INTO tabelle VALUES (10,8,'Tequila');
INSERT INTO tabelle VALUES (11,8,'Whisky');
INSERT INTO tabelle VALUES (12,2,'Wein');
INSERT INTO tabelle VALUES (13,12,'Chardonnay');
INSERT INTO tabelle VALUES (14,12,'Beaujolais');
#uswusf.

PHP:
<?php
//box.php

mysql_pconnect('dbhost', 'dbuser','dbpwd')or die(mysql_error());
mysql_select_db('dbname')or die(mysql_error());
		
	
function make_box($parent)
{
  $items=0;
  $box='';
  
  if($parent)
    {
      $sql= mysql_query("SELECT id,pid,title FROM tabelle WHERE id = $parent OR pid = $parent order by pid ASC" )
            or die(mysql_error());
      
      
      while($res=mysql_fetch_assoc($sql))
            {
              switch($res['id']==$parent)
                {
                  case TRUE:
                        $box='<select name="box['.$res['title'].']" onchange="request_data(this) ">
                              <option value="-1">Auswahl</option>';
                    continue;
                  
                  
                  case FALSE:
                        $items=1;
                        $box.='<option value="'.$res['id'].'">';
                        $box.=htmlentities($res['title']);
                        $box.='</option>';
                    continue;

                }
            }
            
            return(($items) 
              ? $box.'</select>'
              : '<input type="submit">');
    }
    
    return('');
  
}

@print(make_box((int)$_GET['box']));
  
?>
 
hallo,
Mit PhP würd ichs ganz einfach machen :

PHP:
 <select name="Name" id="Id">
<?
	$query=sprintf("SELECT `FELD` FROM Tabelle where Kondition");
	$rst = mysql_query($combo,$connect);
	while ($zeile=mysql_fetch_assoc($rst))  {
                     echo "<option>".$zeile['FELD']." </option>"
     } ?>

Ich hoffe da is jetzt kein Fehler ;)
 
Hallo Sven,
danke erstmal ;)

Aber irgendwie will das noch nicht ganz klappen bei mir. Ich habe den Code so übernommen wie du ihn ins Forum gestellt hast und habe die Datenbank angelegt usw aber wenn ich die Seite aufrufen will dann bekomme ich ne weiße Seite. Woran kann das liegen?

Ich weiß jetzt nicht ob ich da richtig liege aber wo definierst du den Wert für $parent?

gruß
philstrike
 
Zuletzt bearbeitet:
Der Wert für $parent wird der box.php zum einen per GET übergeben(wenn sie per JS angefragt wird)...zum anderen beim includen in der index.php per Hand im Aufruf.

Da dürfte auch der Fehler liegen, in der index.php muss es nun
PHP:
print(make_box(1));
..heissen, da der Array-Index bei 0 beginnt, der DB-Index aber bei 1.

@kne
...da fehlt dann aber noch das <select>...und wenn man am Ende angelangt ist, kommt auch kein submit-button ;)
 
Zurück