2

我正在用 php/mysql 构建一个表单。我有一张包含位置和子位置列表的表格。每个子位置都有一个父位置。列“parentid”引用同一个表中的另一个 locationid。我现在想通过以下方式将这些值加载到下拉列表中:

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

等等等等

有没有人为此得到一个优雅的解决方案?

4

5 回答 5

1

您在寻找类似OPTGROUP标签的东西吗?

于 2008-09-30T21:26:21.150 回答
1

注意:这只是伪代码。我没有尝试运行它,但您应该能够根据需要调整概念。

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

考虑到 BaileyP 的有效批评,以下是如何在没有在每个循环中调用多个查询的开销的情况下做到这一点:

$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>";
于 2008-09-30T21:37:23.417 回答
0

optgroup 绝对是要走的路。其实就是为了这个

例如用法,查看http://www.grandhall.eu/tips/submit/的源代码- “Grandhall Grill Used”下的选择器。

于 2008-09-30T21:30:09.020 回答
0

您可以在实际 HTML 中使用空格/破折号缩进。不过,您需要一个 recusive 循环来构建它。就像是:

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

?>

或类似的东西;)

于 2008-09-30T21:30:19.690 回答
0

理想情况下,您应该从数据库中以正确的顺序选择所有这些数据,然后循环输出。这是我对您所要求的内容的看法

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

如果您不喜欢该coalesce()功能的使用,可以在此表中添加一个“display_order”列,您可以手动设置,然后用于ORDER BY.

于 2008-09-30T23:10:22.040 回答