zetetes has asked for the wisdom of the Perl Monks concerning the following question:

hi fellow monks

i'm playing around with setting up a website with perl/mysql.

tables:
- t_element (there i put all my elements with title, body, etc.)
- t_father2child (there i put together the elements. (f2c_id, f2c_fatherid, f2c_childid, f2c_nodetype)
- t_nodetype (there i store the type of the node: navigation, page, promotion)

i'm stuck with the navigation.
i'd like to make it look like:
nav 1
nav 2
  nav 2.1
    nav 2.1.1
  nav 2.2
nav 3

(the sublevels only show up if you click on the above level. in the above i clicked on 'nav 2.1'. i do not want to see the sublevels of nav 1 and nav 3.)

so normally this ain't a problem. but since i do want to be flexible with the numbers of levels i'd like to do it with a recursive function.

the code i got until now:
sub doNavigation { my $root = $_[0]; my $select = "f2c_id,f2c_fatherid"; my $from = "t_father2child"; my $where = "f2c_id = $root"; my @fathers = doSelect($select,$from,$where); my $fatherId = $fathers[0][1]; loop($root,$fatherId); } # end sub sub loop { my $root = $_[0]; my $father = $_[1]; my $select = "f2c_id,f2c_fatherid,f2c_childid,element_titel"; my $from = "(t_father2child INNER JOIN t_element ON f2c_ChildId = el +ement_id)"; my $where = "f2c_fatherid = $father AND f2c_NodeTypeId = 1"; my @nodes = doSelect($select,$from,$where); foreach my $node (0..$#nodes) { print "<br><a href=?node_id=$nodes[$node][0]> - $nodes[$node][1] - + $nodes[$node][2] - $nodes[$node][3]</a>"; if ($nodes[$node][0] == $root) { my $select = "f2c_id,f2c_fatherid,f2c_childid,element_titel"; my $from = "(t_father2child INNER JOIN t_element ON f2c_ChildId += element_id)"; my $where = "f2c_fatherid = $nodes[$node][2] AND f2c_NodeTypeId += 1"; my @children = doSelect($select,$from,$where); if (@children) { loop($root,$children[0][1]); } # end children-if } # end node-if } # end node-foreach }

it kinda works, but only shows me the selected level and the level below. i guess i could work with a dynamic-growing @ or something but i'm really stuck right now. any help from someone?

thank you!

Replies are listed 'Best First'.
Re: nested navigation links
by matija (Priest) on Mar 25, 2004 at 14:21 UTC
    Well, first of all, you're going to need some way of indicating which nodes are visible. I've been going through your code and for the life of me I can't figure out where you check for anything like that. It looks to me the only output you have is not conditional at all - it is the first statement of a for loop.

    What I think you need:

    • A place in each node which indicates if it's visible or not.
    • A recursive subroutine that will, given the node and the root, climb up the tree, marking all the parents of the newly visible node as visible.(Called when a child node becomes visible)
    • Another rescursive subroutine, called when a node is made invisible, which climbs the tree, and checks which of the parents still has visible children - any parent that doesn't, should be marked not visible. (Called when a child node becomes invisible).
    • A way of displaying only visible elements. You can do that either by redrawing the whole page each time (outputing only the visible tree nodes), or through some javascript & div magic. (Setting the visibility of specific divs to off and on).
      thank you for the fast reply.

      what you're saying sounds reasonable to me, i haven't thought of that even in my dreams. well, i'm willing to learn but i do not know where to get started. i do understand what you're saying but i do not have a clue, how to put this in code...

      could you give me some more specific ideas?