Search code examples
c#htmlasp.net-mvclinqsubmenu

Unlimited multi level menu in mvc


I have created multilevel menu in mvc. it works but i want to make count of level unlimited. There are 4 levels right now so in the future if someone wants to add 5. level in the database, it will not show up in my menu. I need to add another foreach loop to display 5. level. So how can i make my menu unlimited level?

here is my menu view.

 @{       
    var myMenu = @Model;
    var navbarmenu = myMenu.Where(x => x.ParentID == null);
    var i = 0;
    <nav class="navbar navbar-default">
        <div class="container-fluid">
            <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                <ul class=" nav navbar-nav">
                    @foreach (var menuLevel1 in navbarmenu)
                    {
                        <li class="dropdown">
                            <a href="~/ADDS/Default.aspx" style="font-size:16px;">
                                @menuLevel1.MenuName
                                @if (menuLevel1.MenuName != "Home")
                                {
                                    <span class="caret"></span>
                                }
                            </a>
                            @{ var navbarsubmenu = myMenu.Where(x => x.ParentID == menuLevel1.MenuID);}
                            @if (navbarsubmenu.IsAny())
                            {
                                <ul class="dropdown-menu">
                                    @foreach (var menuLevel2 in navbarsubmenu)
                                    {
                                        <li class="dropdown-submenu">
                                            @if (!string.IsNullOrEmpty(menuLevel2.MenuLink))
                                            {
                                                <a href="@Url.Content(menuLevel2.MenuLink)">
                                                    @menuLevel2.MenuName
                                                </a>
                                            }
                                            else
                                            {
                                                <a href="~/ADDS/Default.aspx">
                                                    @menuLevel2.MenuName
                                                </a>
                                            }
                                            @{var navbarsubmenu2 = myMenu.Where(x => x.ParentID == menuLevel2.MenuID);}
                                            @if (navbarsubmenu2.IsAny())
                                            {
                                                <ul class="dropdown-menu">
                                                    @foreach (var menuLevel3 in navbarsubmenu2)
                                                    {
                                                        <li class="dropdown-submenu">
                                                            @if (!string.IsNullOrEmpty(menuLevel3.MenuLink))
                                                            {
                                                                <a href="@Url.Content(menuLevel3.MenuLink)">
                                                                    @menuLevel3.MenuName
                                                                </a>
                                                            }
                                                            else
                                                            {
                                                                <a href="~/ADDS/Default.aspx">
                                                                    @menuLevel3.MenuName
                                                                </a>
                                                            }
                                                            @{var navbarsubmenu3 = myMenu.Where(x => x.ParentID == menuLevel3.MenuID);}
                                                            @if (navbarsubmenu3.IsAny())
                                                            {
                                                                <ul class="dropdown-menu">
                                                                    @foreach (var menuLevel4 in navbarsubmenu3)
                                                                    {
                                                                        <li class="dropdown-submenu">
                                                                            @if (!string.IsNullOrEmpty(menuLevel4.MenuLink))
                                                                            {
                                                                                <a href="@Url.Content(menuLevel4.MenuLink)">
                                                                                    @menuLevel4.MenuName
                                                                                </a>
                                                                            }
                                                                            else
                                                                            {
                                                                                <a href="~/ADDS/Default.aspx">
                                                                                    @menuLevel4.MenuName
                                                                                </a>
                                                                            }
                                                                        </li>
                                                                    }
                                                                </ul>
                                                            }
                                                        </li>
                                                    }
                                                </ul>
                                            }
                                        </li>
                                    }
                                </ul>
                            }
                        </li>
                    }
                </ul>
            </div>
        </div>
    </nav>
}

Solution

  • Have you thought about trying a helper method in your view? Something more along the lines of this using recursion?

    @helper GetSubMenus(IEnumerable<menutable> siteMenu, Nullable<int> parentID)
    {
        foreach (var i in Model.Where(a => a.ParentID.Equals(parentID)))
        {
            var submenu = Model.Where(a => a.ParentID.Equals(i.MenuID)).Count();
    
            <li class="@(submenu > 0 ? "dropdown-submenu" : "dropdown")">
                <a href="@(!string.IsNullOrEmpty(i.MenuLink) ? Url.Content(i.MenuLink) : "~/default)" style="font-size:16px;">@i.MenuName</a>
                @if (submenu > 0)
                {
                    <ul class="dropdown-menu">
                        @GetSubMenus(siteMenu, i.MenuID)
                        @* Recursive  Call for Populate Sub items here*@
                    </ul>
                }
            </li>
        }
    }
    
    @{
        var mymenu = @Model;
        var menuParentID = mymenu.First().ParentID;
    }  
    @if (mymenu != null && mymenu.Count() > 0)
    {
        <nav class="navbar navbar-default">
            <div class="container-fluid">
                <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
                    <ul class=" nav navbar-nav">
                        @GetSubMenus(mymenu, menuParentID)
                    </ul>
                </div>
            </div>
        </nav>
    }