2

I have this array, called $nested (it's a long one, but I tried to get a comprehensive scenario):

Array
(
    [1] => Array
        (
            [id] => 1
            [parent] => 0
            [title] => Page 1
        )

    [2] => Array
        (
            [id] => 2
            [parent] => 0
            [title] => Page 2
        )

    [3] => Array
        (
            [id] => 3
            [parent] => 0
            [title] => Page 3
        )

    [4] => Array
        (
            [id] => 4
            [parent] => 0
            [title] => Page 4
        )

    [5] => Array
        (
            [id] => 5
            [parent] => 0
            [title] => Page 5
        )

    [6] => Array
        (
            [id] => 6
            [parent] => 1
            [title] => Page 1-1
        )

    [7] => Array
        (
            [id] => 7
            [parent] => 1
            [title] => Page 1-2
        )

    [8] => Array
        (
            [id] => 8
            [parent] => 1
            [title] => Page 1-3
        )

    [9] => Array
        (
            [id] => 9
            [parent] => 2
            [title] => Page 2-1
        )

    [10] => Array
        (
            [id] => 10
            [parent] => 2
            [title] => Page 2-2
        )

    [11] => Array
        (
            [id] => 11
            [parent] => 2
            [title] => Page 2-3
        )

    [12] => Array
        (
            [id] => 12
            [parent] => 3
            [title] => Page 3-1
        )

    [13] => Array
        (
            [id] => 13
            [parent] => 3
            [title] => Page 3-2
        )

    [14] => Array
        (
            [id] => 14
            [parent] => 4
            [title] => Page 4-1
        )

    [15] => Array
        (
            [id] => 15
            [parent] => 6
            [title] => Page 1-1-1
        )

    [16] => Array
        (
            [id] => 16
            [parent] => 6
            [title] => Page 1-1-2
        )

    [17] => Array
        (
            [id] => 17
            [parent] => 6
            [title] => Page 1-1-3
        )

    [18] => Array
        (
            [id] => 18
            [parent] => 7
            [title] => Page 1-2-1
        )

    [19] => Array
        (
            [id] => 19
            [parent] => 7
            [title] => Page 1-2-2
        )

    [20] => Array
        (
            [id] => 20
            [parent] => 7
            [title] => Page 1-2-3
        )

    [21] => Array
        (
            [id] => 21
            [parent] => 9
            [title] => Page 2-1-1
        )

    [22] => Array
        (
            [id] => 22
            [parent] => 9
            [title] => Page 2-1-2
        )

    [23] => Array
        (
            [id] => 23
            [parent] => 9
            [title] => Page 2-1-3
        )

)

With this recursive function:

function recursive($parent, $array) {
    $has_children = false;
    foreach($array as $key => $value) {
        if ($value['parent'] == $parent) {       
            if ($has_children === false && $parent) {
                $has_children = true;
                echo '<ul>' ."\n";
            }
            echo '<li>' . "\n";
                echo '<a href="/page.php?id=' . $value['id'] . '">' . $value['title'] . '</a>' . " \n";
            echo "\n";
                recursive($key, $array);
            echo "</li>\n";
        }
    }
    if ($has_children === true && $parent) echo "</ul>\n";
}

<ul><?php echo recursive(0, $nested); ?></ul>

I easily get this output:

So far so good.

Now, I would like NOT to show the whole tree at once, but going deeper when the user clicks on a page/subpage, like this:

URL: http://www.example.com/page.php, initial state ("expand" all items with parent = 0)


URL: http://www.example.com/page.php?id=1 (expand all items with parent = 1)


URL: http://www.example.com/page.php?id=6 (expand all items with parent = 6)

And so on

Seems a mission impossible to me, any help, please? Thanks in advance

Ivan
  • 2,463
  • 6
  • 39
  • 51
  • Shouldn't it be javascript/css question? You have nice html structure for this tree, all you have to do is to hide nested ul and show the while parent node was clicked. – dev-null-dweller Aug 10 '13 at 15:44
  • This should be in javascript. – Homer6 Aug 10 '13 at 15:45
  • sorry, it's not javascript... it's something like this: http://stackoverflow.com/questions/9537502/display-tree-menu-of-selected-parent (but the accepted answer doesn't work, I reproduced in my computer but the output is not right) – Ivan Aug 10 '13 at 17:00

2 Answers2

0

You're almost there. Just one small problem: instead of recursive($key, $array) you need recursive($key + 1, $array). Still, as said by others, this would be a lot nicer if you just generated the entire output with PHP and then controlled it all with javascript. Having the page reload every time the user clicks an item is really not a good user experience.

SaganRitual
  • 3,143
  • 2
  • 24
  • 40
  • I did the recursive($key + 1, $array), but it doesn't work... javascript would be fine if non-dead-end links (Page 1, Page 1-1, etc.) would have the only job to open their children, but it's not so: a click on Page 1 should open the Page 1 with it's text, images, etc, AND show its related children in the menu to go further... – Ivan Aug 10 '13 at 17:48
  • It works fine for me. Check out this [phpfiddle](http://phpfiddle.org/main/code/spf-8bx). You must be doing something differently. ***Edit:*** oh, I see. Yeah, you'll have to add code to show the higher branches of the tree. Still, not a mission impossible. You'll have to add a parameter to your `recursive()` function to tell it where to start expanding, and make the function show siblings and ancestors of that node. – SaganRitual Aug 10 '13 at 18:00
  • yeah, this is just what I can't do and why I posted here :-) – Ivan Aug 10 '13 at 18:28
  • Add another function, like `buildHierarchy()`, that takes the id of the node that you want to see and makes an array of that node's ancestors. Then pass that array into `recursive()`. Then `recursive()` fully expands nodes in its ancestry but leaves non-ancestor nodes unexpanded. – SaganRitual Aug 10 '13 at 18:52
0

At last that's what I did, it works very fine:

// create array of ancestors' ID from current page
function path($page = 0) {
    global $database_connApp, $connApp;
    // let's create arrays
    do {
        mysql_select_db($database_connApp, $connApp);
        $query_rsPage = "SELECT pages.pag_id FROM pages WHERE pages.pag_id = " . $page;
        $rsPage = mysql_query($query_rsPage, $connApp) or die(mysql_error());
        $row_rsPage = mysql_fetch_assoc($rsPage);
        $bid[] = $row_rsPage['pag_id'];
        $page = $row_rsPage['pag_parent'];
    } while ($page > 0);

    // move to the last array index
    end($bid);
    $output = $bid;
    return $output;
}

// create the menu
function fmenu($parent, $array, $path) {
    $has_children = false;
    foreach($array as $key => $value) {
        if (in_array($value['parent'], $path)) {
            if ($value['parent'] == $parent) {
                if ($has_children === false && $parent) {
                    $has_children = true;
                    echo '<ul>' ."\n";
                }
                $active = ($_GET['iData'] == $value['id']) ? ' class="active"' : '';
                echo '<li' . $active . '>' . "\n";
                    echo '<a href="../pagine/' . $value['id'] . '/' . slugify($value['title']) . '.htm">' . html($value['title']) . '</a>' . " \n";
                echo "\n";
                    fmenu($key, $array, $path);
                echo "</li>\n";
            }
        }
    }
    if ($has_children === true && $parent) echo "</ul>\n";
}

echo fmenu(0, $nested, path($row_rsEdit['pag_id']));
Ivan
  • 2,463
  • 6
  • 39
  • 51