Nick
Nick

Reputation: 191

Why do I have an extra <ul> within an <li> tag?

If I have a table of data (describing a tree structure) loaded into an array ($data) like below:

----------------------
| id | name | parent |
----------------------
| 1  | Jack | 0      | //this is the root/top level of tree
| 2  | ...  | 1      | //name column is irrelevant to problem
| 3  | ...  | 1      |
| 4  | ...  | 2      |
| 5  | ...  | 2      |
| 6  | ...  | 2      |
| 7  | ...  | 5      |
| 8  | ...  | 6      |
| 9  | ...  | 4      |
| 10 | ...  | 9      |
----------------------

And I want to generate a ul/li html tree using recursion, like below:

public function get_tree($data, $parent, $depth){
if ($depth > 1000) return ''; // Make sure not to have an endless recursion
$tree = '<ul>';
for($i=0, $ni=count($data); $i < $ni; $i++) {
    if($data[$i]['parent'] == $parent){
        $tree .= '<li>';
        $tree .= '<span>' . $data[$i]['name'] . '</span>';
        $tree .= $this->get_tree($data, $data[$i]['id'], $depth+1);
        $tree .= '</li>';
    }
}
$tree .= '</ul>';
return $tree;
}

For some reason I get an extra ul after each li. How do I fix this?

Upvotes: 0

Views: 76

Answers (2)

ElefantPhace
ElefantPhace

Reputation: 3814

function get_tree($data, $parent, $depth){
    if ($depth > 1000) return '';
    $tree = str_pad(' ',$depth);
    for($i=0, $ni=count($data); $i < $ni; $i++) {
        if($data[$i]['parent'] == $parent){
            $tree .= '<ul>'.PHP_EOL;
            $tree .= str_pad(' ',$depth+2);
            $tree .= '<li>';
            $tree .= '<span>' . $data[$i]['name'] . '</span>';
            $tree .= '</li>'.PHP_EOL;
            $tree .= get_tree($data, $data[$i]['id'], $depth+1);
            $tree .= '</ul>'.PHP_EOL;
        }
    }
    $tree .= str_pad(' ',$depth);
    return $tree;
}

I only added the padding and EOLs so that on a simple test, you can easily see the tree

  • one
    • two
      • four
        • nine
          • ten

      • five
        • seven
      • six
        • eight

    • three

 <ul>
  <li><span>one</span></li>
 <ul>
   <li><span>two</span></li>
  <ul>
    <li><span>four</span></li>
   <ul>
     <li><span>nine</span></li>
    <ul>
      <li><span>ten</span></li>
          </ul>
    </ul>
   </ul>
<ul>
    <li><span>five</span></li>
   <ul>
     <li><span>seven</span></li>
        </ul>
   </ul>
<ul>
    <li><span>six</span></li>
   <ul>
     <li><span>eight</span></li>
        </ul>
   </ul>
  </ul>
<ul>
   <li><span>three</span></li>
    </ul>
 </ul>

Upvotes: 1

MiDri
MiDri

Reputation: 747

Because you're generating <ul> inside your recursive function. You need to do the <ul> and </ul> parts either on the outside or have the function check if it is the first call of it self and the last call of itself (to do the </ul>)

Upvotes: 1

Related Questions