Reputation: 12716
I am trying to create a menu that highlights the current page. I have found a few answers here, but the problem is I can't see that anyone handles submenus.
There is an answer here that looks enticingly simple: active menu item - asp.net mvc3 master page
But as far as I can tell, that one will highlight only the sub menu item if you click on a submenu. I want the submenu item to be highlighted, as well as its parent in the top menu.
E.g. if someone clicks Services, and then Consulting, I would want both of these to be highlighted - Services in the top menu, and Consulting in the submenu. How can I do this?
BTW, I would like to be able to render the submenu both as a dropdown using CSS, and also as a sidebar. How can I take the submenu ul and render it as a sidebar?
Upvotes: 2
Views: 7672
Reputation: 6832
It's fairly simple to determine which menu element to highlight by simply using the ViewContext.RouteData.Values
dictionary, specifically the Action
and Controller
keys.
Here's a quick helper method :
public static string IsSelected(this RouteValueDictionary dictionary, string controller, string action)
{
string cssClass = "selected";
string routeValueController = dictionary["Controller"] as string;
string routeValueAction = dictionary["Action"] as string;
return string.IsNullOrEmpty(action) ?
routeValueController == controller ? cssClass : string.Empty :
routeValueController == controller && routeValueAction == action ? cssClass : string.Empty;
}
And can be used from the view as such :
<ul id="menu">
<li class="@this.ViewContext.RouteData.Values.IsSelected("Default", "Index")">
<a href="@Url.Action("Index", "Default")">Accueil</a>
</li>
</ul>
It's hard to get into a more specific solution as I'm not familiar with your application structure, but this should give you an idea to get started.
Upvotes: 1
Reputation: 427
Here is a simple thing, you can modify it according to your needs but basics are here. http://developerstyle.posterous.com/highlighting-current-page-in-mvc-3-slick-tric
This above link might be down soon as posterous is closing, here is an update link http://bhavinsurela.com/highlighting-current-page-in-mvc-3-slick-tric/
Upvotes: 2
Reputation: 400
I have a solution which I in part also found here in SO and modified, but still as to be improved in order to handle any number of submenus... right now it works for a submenu.
namespace PhotoBuss.Web.Back.Controllers
{
public class NavigationController : BaseAdministrationController
{
//
// GET: /Common/
[ChildActionOnly]
public ActionResult HeaderMenu()
{
// http://stackoverflow.com/questions/4653226/asp-net-mvc-menu-selected-item
var items = new List<MenuItemViewModel>
{
new MenuItemViewModel{ Text = "home", Action="Index", Controller="Administration", Selected=false},
new MenuItemViewModel{Text = "manage", Action="Index", Controller="Manage", Selected=false,
SubMenu =
new List<MenuItemViewModel>
{
new MenuItemViewModel{ Text= "photos", Action="Index", Controller="Photos", Selected = false },
new MenuItemViewModel { Text = "collections", Action="Index", Controller="Collections", Selected=false},
new MenuItemViewModel { Text = "keywords", Action="Index", Controller="Keywords", Selected=false},
new MenuItemViewModel { Text = "users", Action="Index", Controller="Users", Selected=false},
new MenuItemViewModel { Text = "user groups", Action="Index", Controller="Roles", Selected=false}
}
},
new MenuItemViewModel{Text="cms", Action="Index", Controller="CMS", Selected=false}
};
string action = ControllerContext.ParentActionViewContext.RouteData.Values["action"].ToString();
string controller = ControllerContext.ParentActionViewContext.RouteData.Values["controller"].ToString();
foreach (var item in items)
{
if (item.Controller == controller && item.Action == action)
{
item.Selected = true;
}
foreach(var subItem in item.SubMenu)
if (subItem.Controller == controller && subItem.Action == action)
{
item.Selected =
subItem.Selected = true;
}
}
return PartialView(items);
}
}
The ViewModel
public class MenuItemViewModel
{
public MenuItemViewModel()
{
SubMenu = new List<MenuItemViewModel>();
}
public string Text { get; set; }
public string Controller { get; set; }
public string Action { get; set; }
public bool Selected { get; set; }
public List<MenuItemViewModel> SubMenu { get; set; }
}
}
The View
@model List<PhotoBuss.Web.Back.Models.Navigation.MenuItemViewModel>
<link href="@Url.Content("~/Areas/Admin/Content/CSS/menu.css")" rel="stylesheet" type="text/css" />
<div class="headerMenu">
<ul>
@foreach (var menuItem in Model)
{
<li>@Html.ActionLink(menuItem.Text, menuItem.Action, menuItem.Controller, null,
new { @class = menuItem.Selected ? "selected" : "" })
@if (menuItem.SubMenu.Count >0)
{
<ul class="@(menuItem.Selected ? "selected" : "")">
@foreach (var subMenu in menuItem.SubMenu)
{
<li>@Html.ActionLink(subMenu.Text, subMenu.Action, subMenu.Controller, null,
new { @class = subMenu.Selected ? "selected" : "" })</li>
}
</ul>
}
</li>
}
</ul>
</div>
The CSS I'm using with this at the moment:
.headerMenu *
{
padding: 0;
margin: 0;
}
.headerMenu
{
position: relative;
background-color: #78C8FA;
width: 100%;
text-align: center;
color: #FFFFFF;
clear: both;
float: left;
margin-top: 10px;
}
.headerMenu ul
{
display: block;
list-style: none;
line-height: 3em;
height: 3em;
}
.headerMenu ul li
{
display: inline-block;
margin-left: 15px;
margin-right: 15px;
}
.headerMenu ul li a
{
display: block;
text-decoration: none;
color: white;
font-size: 1.5em;
padding-left:2em;
padding-right:2em;
}
.headerMenu ul li a:visited
{
color: white;
}
.headerMenu ul li a:hover, .menu ul li
{
color: #333333;
}
.selected
{
color: #333333 !important;
display:block !important;
background-color: #999999;
}
.headerMenu ul ul
{
display: none;
position: absolute;
width: 100%;
right: 50%;
left: 0;
background-color: #999999;
}
.headerMenu li:hover > ul, .selected
{
display: block;
}
Upvotes: 1
Reputation: 3997
Here is a example where they handle the submenus and highlight it.
http://users.tpg.com.au/j_birch/plugins/superfish/#sample4
It uses superfish-navbar.css where you can see how it is done. It is a very good plugin for menus.
Upvotes: 0