İç içe açılan

5 Cevap php

Php / mysql ile bir form inşa ediyorum. Ben yerleri ve sublocations bir listesini içeren bir tablo var. Her sublocation bir üst konuma sahiptir. Aynı tabloda bir sütun "parentid" referanslar başka LocationID. Ben şimdi şu şekilde bir açılan bu değerler yüklemek istediğiniz:

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

vs vs

Herkes bunu yapmak için zarif bir çözüm var mı?

5 Cevap

Not: Bu yalnızca psuedo kodudur .. size ne gerek kavramları ayarlamak gerekir ama ben bunu çalıştırmayı deneyin vermedi.

$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>";

Akılda BaileyP en geçerli eleştiri, buraya her döngü içinde birden fazla sorgu çağrı yükü OLMADAN bunu nasıl bulunuyor:

$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>";

Eğer OPTGROUP etiketi gibi bir şey mi arıyorsunuz?

optgroup kesinlikle gitmek için yoludur. O, bunun için ne aslında

Örneğin kullanımı, ve http://www.grandhall.eu/tips/submit/ kaynağını görüntüle - altında seçici "Grandhall Grill el".

Sen gerçek HTML uzay / tire girinti kullanabilirsiniz. Gerçi bunu oluşturmak için bir recusrive döngü gerekir. Gibi bir şey:

<?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;

?>

Ya da ona benzer bir şey ;)

İdeal olarak, sağ veritabanından çıkışı bu aşkın sonra sadece döngü doğru sırayla tüm bu verileri seçin ediyorum. İşte size soruyorsun almak benim

<?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>";

Eğer coalesce() fonksiyonunun kullanımını beğenmezseniz, size manuel ayarlayabilirsiniz bu tabloya bir "display_order" sütunu ekleyin ve ardından ORDER BY için kullanabilirsiniz.