Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Razor recursive tree menu structure

I think I need a little help here with rendering af recursive tree menu structure in Umbraco using the Razor viewengine.

I need to render the following tree menu structure:

Page 1
     Page 2
         Page 3
         Page 4
              Page 5
     Page 6
     Page 7

So when I am on Page 5 I need to use CSS class "open" on the parent nodes: Page 4, Page 2 and Page 1 and the CSS class "active" on the node I am standing on.

I have got the structure to render the correct nodes when clicking on a link in the menu, but I simply can't figure how to apply the correct classes :-(

My code is as follows:

@{
        DynamicNode current = Model;
        var nodes = Model.AncestorOrSelf(2).Children.Where("Visible");        
        if(nodes.Any())
        {
            <ul class="side-nav-list">
                @foreach(var node in nodes)
                {
                    bool isDescendantOrSelf = current.IsDescendantOrSelf(node);
                    <li>
                        <a href="@node.Url">@node.Name</a>
                        @if(isDescendantOrSelf)
                        {
                            @RenderSubMenuRecursive(node)
                        }
                    </li>
                }
            </ul>
        }
    }

@helper RenderSubMenuRecursive(DynamicNode node)
{
    if(node.Children.Any(x => x.GetPropertyValue("umbracoNaviHide").Equals("0") && Model.IsDescendantOrSelf(node)))
    {        
         var childNodes = node.Children.Where(x => x.GetPropertyValue("umbracoNaviHide").Equals("0"));
         string css = node.IsAncestor(Model) ? "open" : "";
         <ul>

            @foreach(var childNode in childNodes)
            {
                <li class="@css">                    
                    <a href="@childNode.Url">@childNode.Name</a>
                    @if (childNode.IsDescendantOrSelf(node))
                    {
                        @RenderSubMenuRecursive(childNode)
                    }
                </li>
            }
        </ul>
    }
}

Any help/hint on this is greatly appreciated! :-) Thanks in advance!

like image 948
bomortensen Avatar asked Jan 13 '23 21:01

bomortensen


1 Answers

Solved it myself by moving around some code etc. Final solution:

 @{
        DynamicNode current = Model;
        var nodes = Model.AncestorOrSelf(2).Children.Where("Visible");        
        if(nodes.Any())
        {
            <ul class="side-nav-list">
                @foreach(var node in nodes)
                {                        
                    @RenderSubMenuRecursive(node)                                           
                }
            </ul>
        }
    }

@helper RenderSubMenuRecursive(DynamicNode node)
{    
    var childNodes = node.Children.Where(x => x.GetPropertyValue("umbracoNaviHide").Equals("0"));
string css = node.IsAncestor(Model) ? "open" : "";

if(node.Id == Model.Id)
{
    css = "active";
}

<li class="@css">
    <a href="@node.Url">@node.Name</a>

    <ul>            
        @foreach (var childNode in childNodes.Where(childNode => Model.IsDescendantOrSelf(node)))
        {
            @RenderSubMenuRecursive(childNode)
        }
    </ul>
</li>    
}
like image 85
bomortensen Avatar answered Jan 19 '23 10:01

bomortensen