2008-09-30 7 views
2

Je suis en train de créer un formulaire avec php/mysql. J'ai une table avec une liste de lieux et de sous-locations. Chaque sous-location a un emplacement parent. Une colonne "parentid" fait référence à un autre identifiant de localisation dans la même table. Je veux maintenant charger ces valeurs dans un menu déroulant de la manière suivante:Liste déroulante imbriquée

--Location 1 
----Sublocation 1 
----Sublocation 2 
----Sublocation 3 
--Location 2 
----Sublocation 4 
----Sublocation 5 

etc., etc.

Quelqu'un at-il une solution élégante pour ce faire?

Répondre

1

NOTE: Ce n'est psuedo code .. Je n'ai pas essayé de l'exécuter, mais vous devriez être en mesure d'adapter les concepts à ce que vous avez besoin .

$parentsql = "SELECT parentid, parentname FROM table"; 

$result = mysql_query($parentsql); 
print "<select>"; 
while($row = mysql_fetch_assoc($result)){ 
    $childsql = "SELECT childID, childName from table where parentid=".$row["parentID"]; 
    $result2 = mysql_query($childsql); 
    print "<optgroup label=\".$row["parentname"]."\">"; 
    while($row2 = mysql_fetch_assoc($result)){ 
     print "<option value=\"".$row["childID"]."\">".$row["childName"]."</option>\n"; 
    } 
    print "</optgroup>"; 
} 
print "</select>"; 

Avec la critique valable dans l'esprit de BaileyP, voici comment faire sans les frais généraux d'appeler plusieurs requêtes dans chaque boucle:

$sql = "SELECT childId, childName, parentId, parentName FROM child LEFT JOIN parent ON child.parentId = parent.parentId ORDER BY parentID, childName"; 
$result = mysql_query($sql); 
$currentParent = ""; 

print "<select>"; 
while($row = mysql_fetch_assoc($result)){ 
    if($currentParent != $row["parentID"]){ 
     if($currentParent != ""){ 
      print "</optgroup>"; 
     } 
     print "<optgroup label=\".$row["parentName"]."\">"; 
     $currentParent = $row["parentName"]; 
    } 

    print "<option value=\"".$row["childID"]."\">".$row["childName"]."</option>\n"; 
} 
print "</optgroup>" 
print "</select>"; 
+0

J'ai voté cela parce que l'exécution d'une requête par itération de n'importe quelle boucle est un gros non-non. –

1

Vous recherchez quelque chose comme l'étiquette OPTGROUP?

0

optgroup est définitivement la solution. Il est en fait ce que c'est,

Pour l'exemple d'utilisation, voir la source de http://www.grandhall.eu/tips/submit/ - le sélecteur sous "Grandhall Grill Used".

0

Vous pouvez utiliser et insérer un espace/un tiret dans le HTML actuel. Vous aurez besoin d'une boucle de recusrive pour le construire si. Quelque chose comme:

<?php 

$data = array(
    'Location 1' => array(
     'Sublocation1', 
     'Sublocation2', 
     'Sublocation3' => array(
      'SubSublocation1', 
     ), 
    'Location2' 
); 

$output = '<select name="location">' . PHP_EOL; 

function build_items($input, $output) 
{ 
    if(is_array($input)) 
    { 
     $output .= '<optgroup>' . $key . '</optgroup>' . PHP_EOL; 
     foreach($input as $key => $value) 
     { 
      $output = build_items($value, $output); 
     } 
    } 
    else 
    { 
     $output .= '<option>' . $value . '</option>' . PHP_EOL; 
    } 

    return $output; 
} 

$output = build_items($data, $output); 

$output .= '</select>' . PHP_EOL; 

?> 

Ou quelque chose de semblable;)

0

Idéalement, vous devez sélectionner toutes ces données dans le bon ordre dès la sortie de la base de données, il suffit de faire une boucle pour la sortie. Voici mon avis sur ce que vous demandez

<?php 
/* 
Assuming data that looks like this 

locations 
+----+-----------+-------+ 
| id | parent_id | descr | 
+----+-----------+-------+ 
| 1 |  null | Foo | 
| 2 |  null | Bar | 
| 3 |   1 | Doe | 
| 4 |   2 | Rae | 
| 5 |   1 | Mi | 
| 6 |   2 | Fa | 
+----+-----------+-------+ 
*/ 

$result = mysql_query("SELECT id, parent_id, descr FROM locations order by coalesce(id, parent_id), descr"); 

echo "<select>"; 
while ($row = mysql_fetch_object($result)) 
{ 
    $optionName = htmlspecialchars((is_null($row->parent_id)) ? "--{$row->descr}" : "----{$row->desc}r", ENT_COMPAT, 'UTF-8'); 
    echo "<option value=\"{$row->id}\">$optionName</option>"; 
} 
echo "</select>"; 

Si vous n'aimez pas l'utilisation de la fonction coalesce(), vous pouvez ajouter une colonne « Display_Order » à ce tableau que vous pouvez définir manuellement, puis utiliser pour le ORDER BY.

Questions connexes