One way to solve this solution would be to add another property to each view to specify the sub-menu item page name, pass the sub-menu item page name to the TopMenu
view component then set the active
CSS class for the appropriate sub-menu item.
There are many other ways to solve this question but this approach seems to be fairly quick and easy given the template has already created the framework to use for the root-level navigation; we are simply extending it.
The following steps will walk you though this approach:
Step 1
Add a property to each view that specifies the currently active sub-menu item name. The following snippet is an example of what the top of each view page could look like.
@{
ViewBag.CurrentPageName = "Reporting";
ViewBag.CurrentSubPageName = "Activity Report";
}
Step 2
Add a property, in this case ActiveSubMenuItemName
, to the TopMenuViewModel
class to store the currently active sub-menu item name.
public class TopMenuViewModel
{
public UserMenu MainMenu { get; set; }
public string ActiveMenuItemName { get; set; }
public string ActiveSubMenuItemName { get; set; }
}
Step 3
Add a parameter to the InvokeAsync
method in the TopMenuViewComponent
class to accept the currently active sub-menu item name.
public async Task<IViewComponentResult> InvokeAsync(string activeMenu = "", string activeSubMenu = "")
{
var model = new TopMenuViewModel
{
MainMenu = await _userNavigationManager.GetMenuAsync("MainMenu", _abpSession.ToUserIdentifier()),
ActiveMenuItemName = activeMenu,
ActiveSubMenuItemName = activeSubMenu
};
return View(model);
}
Step 4
Pass the property we set at the top of each view in step 1 into the method we updated in step 4.
<ul class="nav navbar-nav">
@await Component.InvokeAsync(typeof(TopMenuViewComponent), new { activeMenu = ViewBag.CurrentPageName, activeSubMenu = ViewBag.CurrentSubPageName })
</ul>
Step 5
Update the Views/Shared/Components/TopMenu/Default.cshtml
view to set the active
class within the dropdown-menu
for the currently active sub-menu item.
<ul class="dropdown-menu">
@foreach (var subMenuItem in menuItem.Items) {
<li class="@(Model.ActiveSubMenuItemName == subMenuItem.Name ? "active" : "")">
<a href="@calculateMenuUrl(subMenuItem.Url)">
@if (!string.IsNullOrWhiteSpace(subMenuItem.Icon))
{
<i class="@subMenuItem.Icon"></i>
}
@subMenuItem.DisplayName
</a>
</li>
}
</ul>