views:

486

answers:

2

When I run this code:

foreach ($tree as $node) {
    echo str_repeat(' ', $node->tree_depth * 4) . $node->id . PHP_EOL;
}

I get well formatted text like:

Food
 Fruit
   Red
     Cherry
     Strawberry
               Cool
               Not cool
   Yellow
     Banana
 Meat
   Beef
   Pork

But I want to create a list with <ul><li>...:

I tried with:

echo '<ul>';
$prev_depth = 0;
foreach($table->fetchTree() as $row) {
    if ($row->tree_depth > $prev_depth) {
        echo '<li><ul>';
    } else if ($row->tree_depth < $prev_depth) {
        echo '</li></ul>';
    }
    echo '<li>' . $row->name . '</li>';
    $prev_depth = $row->tree_depth;
}
echo '</ul>';

But I have some extra ul tags and so on. I lost 2 days on this so if you can help me please post here...

A: 

Try this code instead:

<?php
echo "<ul>\n";

$tree = array(
    array('Food', 0),
    array('Fruit', 1),
    array('Red', 5),
    array('Cherry', 3),
    array('Strawberry', 3),
    array('Cool', 4),
    array('Not cool', 4),
    array('Yellow', 2),
    array('Banana', 3),
    array('Meat', 0),
    array('Beef', 4),
    array('Pork', 2),
);

$depth = 0;

foreach ($tree as $node) {
  if ($node[1] > $depth)
    echo str_repeat("<ul>\n", $node[1] - $depth);
  if ($node[1] < $depth)
    echo str_repeat("</ul>\n", $depth - $node[1]);
  $depth = $node[1];

  echo "<li>" .  $node[0] . "\n";
}
echo str_repeat("</ul>\n", $depth+1);
?>

I've updated it to output fewer <li> tags, thereby reducing the number of bullets. But on the other hand, this will generate HTML that wont validate since a jump of more than one level will result in a <ul><ul> being generated.

Martin Geisler
Dude this is giving me the pretty much the same output as code that I posted in my question, so this isn't a solution...
Splendid
It was quite hard to see what you were really asking... I thought your problem was the jumps in more than one level, which my code handles.
Martin Geisler
I think, that my question maybe isn't perfectly clear, but the code which I posted is clear like milk :DAnyway thank you for help, I appreciate it, really...
Splendid
Great, I'm glad to hear that!
Martin Geisler
+3  A: 

Try this algorithm:

$tree = array(
    array('Food', 0),
    array('Fruit', 1),
    array('Red', 2),
    array('Cherry', 3),
    array('Strawberry', 3),
    array('Cool', 4),
    array('Not cool', 4),
    array('Yellow', 2),
    array('Banana', 3),
    array('Meat', 0),
    array('Beef', 1),
    array('Pork', 1),
);

$depth = -1;
$flag = false;
foreach ($tree as $row) {
    while ($row[1] > $depth) {
        echo "<ul>\n", "<li>";
        $flag = false;
        $depth++;
    }
    while ($row[1] < $depth) {
        echo "</li>\n", "</ul>\n";
        $depth--;
    }
    if ($flag) {
        echo "</li>\n", "<li>";
        $flag = false;
    }
    echo $row[0];
    $flag = true;
}
while ($depth-- > -1) {
    echo "</li>\n", "</ul>\n";
}

Here you just need to replace $tree by $table->fetchTree(), $row[0] by $row->name and $row[1] by $row->tree_depth.

Gumbo
Dude your are fuckin GENIUS, if I meet u one day I must drink few bears with u! Thank u so much!
Splendid
Gumbo, believed or not I found a problem with your algorithm but unfortunately, I am not able to solve it, problem is that your algorithm isn't generating valid ul li structure and u have some extra non necessary tags, can u solve it !?
Splendid
I don’t see any errors. Do you have an example where the output is invalid?
Gumbo
Yes I do actually, how do u want me to send it!? Also I can send u an email if u want. Here is the output, it looks ok in browser but if u analyze the source u will see the problem http://jsbin.com/oliya
Splendid
There is somewhere a `</l>` instead of a `</li>` in your code. But mine is correct.
Gumbo
Nope! Am I blind or what!? Here is my code: http://pastebin.com/mdc024f2
Splendid
Gumbo
I am sorry, but thats irrelevant, I probably deleted somehow that one line when I was posting and editing the code on js bin. But that's not the php output take a look at new version with closed l tag http://jsbin.com/icela
Splendid
Ah, I got it. I think I found the error. Should be fixed now.
Gumbo
Well Gumbo u are one amazing dude :D Tell me are u available for some freelance work and/or cooperation and how can I contact u!?
Splendid
Sorry I didn't saw that u edited the code! But I must tell u that your code is working horrible now :( It ain't creating what it should be creating! Now each now is child of first printed row :D
Splendid
Then it’s your data that’s wrong.
Gumbo
It isn't try it and u will see what am I talking about! I can send my complex array if u want. But your code was working in first place and everything was fine except few not necessary tags! Now it simply ain't working!
Splendid
Did you consider that my depth count begins with 0 as the first level?
Gumbo
Yes I did, and I was changing the deep but without results. Can u tell me one thing, how I can get this output as string!? Not to echo it so I can remove the extra tags with some classic function!?
Splendid
Replace the `echo` by `$str.=` and the `,` inside the `echo` by `.`.
Gumbo