Reputation: 1612
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
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
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