How to recursively build a <select> with unknown tree depth

后端 未结 8 599
栀梦
栀梦 2020-12-15 01:49

I have a MySQL table with a tree data structure. The fields are _id, name and parentId. When the record hasn\'t a parent, parent

相关标签:
8条回答
  • 2020-12-15 02:07

    Your problem is already solved within the SPL. The RecursiveIteratorIteratorDocs has the information about one's item's depth:

    $it = new RecursiveIteratorIterator(new RecursiveArrayIterator($array), SELF_FIRST);
    foreach ($it as $key => $element)
    {
        if ($key !== 'name') continue;
        $inset = str_repeat('--', $it->getDepth());
        printf('<option>%s %s</option>', $inset, $element);
    }
    
    0 讨论(0)
  • 2020-12-15 02:07

    My final solution (thanks to Starx and varan):

    function toSelect ($arr, $depth=0) {    
        $html = '';
        foreach ( $arr as $v ) {
    
            $html.= '<option value="' . $v['_id'] . '">';
            $html.= str_repeat('--', $depth);
            $html.= $v['name'] . '</option>' . PHP_EOL;
    
            if ( array_key_exists('children', $v) ) {
                $html.= toSelect($v['children'], $depth+1);
            }
        }
    
        return $html;
    }
    
    echo '<select>';
    echo toSelect($array);
    echo '</select>';
    

    Even the RecursiveIteratorIterator solution is good (thanks hakre).

    0 讨论(0)
  • 2020-12-15 02:18

    You could pass the length to the function and increment it when you call recursively and then use the variable $length to determine the depth

    function toUL ($arr, $length = 0) {
    
        $html = '<ul>' . PHP_EOL;
    
        foreach ( $arr as $v ) {
    
            $html.= '<li>' . $v['name'] . '</li>' . PHP_EOL;
    
            if ( array_key_exists('children', $v) ) {
                $html.= toUL($v['children'], $length++);
            }
    
        }
    
        $html.= '</ul>' . PHP_EOL;
    
        return $html;
    }
    

    This is what i do usually to keep track of recursion depth and it usually get the job done

    0 讨论(0)
  • 2020-12-15 02:19

    Pass a parameter to count the iteration like $pass

    function toUL ($arr, $pass = 0) {
    
        $html = '<ul>' . PHP_EOL;
    
        foreach ( $arr as $v ) {           
    
            $html.= '<li>';
            $html .= str_repeat("--", $pass); // use the $pass value to create the --
            $html .= $v['name'] . '</li>' . PHP_EOL;
    
            if ( array_key_exists('children', $v) ) {
                $html.= toUL($v['children'], $pass+1);
            }
    
        }
    
        $html.= '</ul>' . PHP_EOL;
    
        return $html;
    }
    
    0 讨论(0)
  • 2020-12-15 02:21

    you can use optgroup as an iterator. For Example:

    <select name="list">
      <option value=1>1st option</option>
      <optgroup>
        <option value=10>1st on 1st group</option>
      </optgroup>
    </select>
    

    if you want php, you can try this one:

    <?PHP
    function toSELECT($arr,$depth=0)
    {
    $html="";
    if(is_array($arr))
        {
        $html.=($depth==0)?"<select name='html'>\n":"";
        foreach ($arr as $key=>$value)
            {
            if(is_array($arr[$key]))
                {
                $html.=str_repeat("\t",$depth)."<optgroup>\n";
                $html.=str_repeat("\t",$depth).toHTML($arr[$key],$depth+1);
                $html.=str_repeat("\t",$depth)."</optgroup>\n";
                }
            else
                {
                $html.=str_repeat("\t",$depth)."<option value='".$value."'>".$key."</option>\n";
                }
            }
        $html.=($depth==0)?"</select>\n":"";
        }
    return $html;
    }
    
    ?>
    
    0 讨论(0)
  • 2020-12-15 02:23
    function toSelect($arr, $depth = 0) {
    
        $html = '';
    
        foreach ( $arr as $v ) {           
    
            $html.= '<option>' . str_repeat("--", $depth) . $v['name'] . '</option>' . PHP_EOL;
    
            if ( array_key_exists('children', $v) ) {
                $html.= toSelect($v['children'], $depth++);
            }
    
        }
    
    
        return $html;
    }
    
    0 讨论(0)
提交回复
热议问题