How to find the Last Menu Node on Level 1

Do something cool with CMS? Show us ...
This board is for 'Answers', and the discussion of answers... Not for questions.
Post Reply
kendo451

How to find the Last Menu Node on Level 1

Post 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}
Last edited by kendo451 on Fri May 06, 2011 12:34 am, edited 2 times in total.
kendo451

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

Post 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.
User avatar
paulbaker
Dev Team Member
Dev Team Member
Posts: 1465
Joined: Sat Apr 18, 2009 10:09 pm
Location: Maidenhead, UK
Contact:

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

Post 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.
To copy System Information to the forum:
https://docs.cmsmadesimple.org/troubles ... nformation

CMS Made Simple Geekmoots attended:
Nottingham, UK 2012 | Ghent, Belgium 2015 | Leicester, UK 2016
User avatar
webform
Power Poster
Power Poster
Posts: 503
Joined: Sat Nov 25, 2006 3:39 pm
Location: Copenhagen, Denmark

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

Post by webform »

Couldn't you use

Code: Select all

{if $smarty.foreach.items.last} class="last"{/if}
to set class for last menu item?
User avatar
Dr.CSS
Moderator
Moderator
Posts: 12711
Joined: Thu Mar 09, 2006 5:32 am
Location: Arizona

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

Post 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}
Joff
Forum Members
Forum Members
Posts: 23
Joined: Wed Jan 25, 2006 10:54 pm

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

Post 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
twitter: @joffff
kendo451

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

Post 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.
User avatar
webform
Power Poster
Power Poster
Posts: 503
Joined: Sat Nov 25, 2006 3:39 pm
Location: Copenhagen, Denmark

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

Post 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!
Post Reply

Return to “Tips and Tricks”