Page 1 of 1

How to find the Last Menu Node on Level 1

Posted: Fri Nov 06, 2009 1:10 am
by kendo451
What to do if your menu css requires you to identify the last element of the 1st depth in order to add a special class to it?

I encountered that problem.  The menu manager node list is indexed by order, so how do you find the last 1st depth node?

My solution was to do a foreach loop of the node in advance.  If the node is depth one, assign it to a variable.  It gets assigned to the same variable every time, so after the loop completes, the last depth one node is in the variable.

Code: Select all

{* CSS classes used in this template:
#menuwrapper - The id for the <div> that the menu is wrapped in. Sets the width, background etc. for the menu.
#primary-nav - The id for the <ul>
.menuparent - The class for each <li> that has children.
.menuactive - The class for each <li> that is active or is a parent (on any depth) of a child that is active. *}
{if $count > 0}

{* find last first depth node *}
{foreach from=$nodelist item='node'}
{if $node->depth == 1}
{assign var='lastnode' value=$node->id}
{/if}
{/foreach}

<ul id="primary-nav">
{foreach from=$nodelist item=node}
{if $node->depth > $node->prevdepth}
{repeat string='<ul class="unli">' times=$node->depth-$node->prevdepth}
{elseif $node->depth < $node->prevdepth}
{repeat string='</li><li class="separator once" style="list-style-type: none;"> </li></ul>' times=$node->prevdepth-$node->depth}
</li>
{elseif $node->index > 0}</li>
{/if}
{if $node->parent == true or ($node->current == true and $node->haschildren == true)}
<li class="menuactive menuparent{if $node->index == 0} first{elseif $node->id == $lastnode} last{/if}">
<a class="menuactive menuparent" {elseif $node->current == true}
<li class="menuactive{if $node->index == 0} first{elseif $node->id == $lastnode} last{/if}">
<a class="menuactive" {elseif $node->haschildren == true}
<li class="menuparent{if $node->index == 0} first{elseif $node->id == $lastnode} last{/if}">
<a class="menuparent" {elseif $node->type == 'sectionheader' and $node->haschildren == true}
<li class="sectionheader{if $node->index == 0} first{elseif $node->id == $lastnode} last{/if}"><span class="sectionheader">{$node->menutext}</span> {elseif $node->type == 'separator'}
<li style="list-style-type: none;" {if $node->index == 0}class="first"{elseif $node->id == $lastnode}class="last"{/if} > <hr class="menu_separator" />{else}
<li>
<a {/if}
{if $node->type != 'sectionheader' and $node->type != 'separator'}
{if $node->target}target="{$node->target}" {/if}
href="{$node->url}"><span>{$node->menutext}</span></a>
{elseif $node->type == 'sectionheader'}
><span class="sectionheader">{$node->menutext}</span></a>
{/if}
{/foreach}
{repeat string='</li><li class="separator once" style="list-style-type: none;"> </li></ul>' times=$node->depth-1}
</li>
</ul>
<div class="clearb"></div>
{/if}

Re: How to find the Last Menu Node on Level 1

Posted: Wed Dec 02, 2009 5:09 pm
by kendo451
In the original version I had put $node->level where it should have been $node->depth

It has been corrected now and works for me.

Re: How to find the Last Menu Node on Level 1

Posted: Wed Mar 03, 2010 1:23 am
by paulbaker
Thanks for posting   8)

I have just used some of the techniques here to modify a dropdown menu - I had to repeat the main menu option as the first item in the dropdown because users were not realising that the main option was clickable.

Re: How to find the Last Menu Node on Level 1

Posted: Sat Mar 20, 2010 10:04 pm
by webform
Couldn't you use

Code: Select all

{if $smarty.foreach.items.last} class="last"{/if}
to set class for last menu item?

Re: How to find the Last Menu Node on Level 1

Posted: Sat Mar 20, 2010 10:39 pm
by Dr.CSS
What is being assigned to the last top node?...

This assigns last as a class to it no matter what type of node it is, I don't like using the code thing as it makes the text small and hard to read...

{* CSS classes used in this template:
#menuwrapper - The id for the that the menu is wrapped in. Sets the width, background etc. for the menu.
#primary-nav - The id for the
.menuparent - The class for each that has children.
.menuactive - The class for each that is active or is a parent (on any level) of a child that is active. *}
{if $count > 0}

{assign var='last_top' value=''}
{foreach from=$nodelist item=node}
{if $node->depth == 1}
  {assign var='last_top' value=$node->id}
{/if}
{/foreach}




{foreach from=$nodelist item=node name='menu'}

{assign var='last' value=''}
{if $last_top == $node->id}
  {assign var='last' value='last '}
{/if}

{if $node->depth > $node->prevdepth}
{repeat string='' times=$node->depth-$node->prevdepth}
{elseif $node->depth prevdepth}
{repeat string=' ' times=$node->prevdepth-$node->depth}

{elseif $node->index > 0}
{/if}
{if $node->parent == true or ($node->current == true and $node->haschildren == true)}

current == true}

haschildren == true}

type == 'sectionheader'}
{$node->menutext} {elseif $node->type == 'separator'}

{elseif empty($last)}

type != 'sectionheader' and $node->type != 'separator'}
{if $node->target}target="{$node->target}" {/if}
href="{$node->url}">{$node->menutext}
{elseif $node->type == 'sectionheader'}
>{$node->menutext}
{/if}
{/foreach}
{repeat string=' ' times=$node->depth-1}




{/if}

Re: How to find the Last Menu Node on Level 1

Posted: Thu Mar 25, 2010 10:56 pm
by Joff
kendo451 There's a slight error in the code in your first post.  The additional foreach you've created should be:

Code: Select all

{foreach from=$nodelist item=node}
{if $node->depth == 1}
{assign var='lastnode' value=$node->id}
{/if}
{/foreach}
You had the "from=" as 'nodelist' when it should have been $nodelist.  Otherwise, it works great!  ;D

Re: How to find the Last Menu Node on Level 1

Posted: Thu Mar 25, 2010 11:17 pm
by kendo451
webform wrote: Couldn't you use

Code: Select all

{if $smarty.foreach.items.last} class="last"{/if}
to set class for last menu item?
That would work if you only had a one-level menu depth.  However, if you have a complete fly-out or mega menu and your design requires a special class for the last top level element, then your method would not work.

Alternatively, it would be easier to use css :last-child and let the client's browser to the work.

Re: How to find the Last Menu Node on Level 1

Posted: Fri Mar 26, 2010 9:36 am
by webform
Alternatively, it would be easier to use css :last-child and let the client's browser to the work.
That is what i do (3 Level menu). Letting CSS handle the different levels!