Nakres
Nakres

Reputation: 1612

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>
}

Upvotes: 4

Views: 6583

Answers (2)

Leonardo Wildt
Leonardo Wildt

Reputation: 2599

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>
} 

Upvotes: 3

Darren
Darren

Reputation: 70728

I would make a MultiLevelMenu model which would be populated by the database in a service layer, you could then use Partial Views.

public class MultiLevelMenu
{
   public string MenuName { get; set; }
   public MultiLevelMenu NestedMenu { get; set; }
}

Then in your main view have:

@model MultiLevelMenu;

<div>@Model.MenuName</div>

@Html.Partial("_MultiLevelMenu", Model);

Then for the partial view:

@if (Model.MultiLevelMenu != null) 
{
    <div>@Model.MenuName</div>
    @Html.Partial("_MultiLevelMenu", Model);
}

Upvotes: 3

Related Questions