【问题标题】:Nested dropdown嵌套下拉
【发布时间】:2019-10-16 15:50:48
【问题描述】:

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

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

等等。等等

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

【问题讨论】:

    标签: php mysql html forms


    【解决方案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>";
    

    【讨论】:

    • 我投了反对票,因为在任何循环的每次迭代中执行查询都是一个很大的禁忌。
    【解决方案2】:

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

    【讨论】:

      【解决方案3】:

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

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

      【讨论】:

        【解决方案4】:

        您可以在实际 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;
        
        ?>
        

        或类似的东西;)

        【讨论】:

          【解决方案5】:

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

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

          【讨论】:

            猜你喜欢
            • 2015-12-20
            • 1970-01-01
            • 1970-01-01
            • 2019-01-23
            • 2021-02-12
            • 1970-01-01
            • 1970-01-01
            • 2017-03-06
            • 2011-10-05
            相关资源
            最近更新 更多