How do I create tabbed navigation with the "Current" tab highlighted in the UI?
-
Please phrase these in the form of a question first, and then provide the answer as a separate post. I'll remove my downvote when I see you've fixed it. Otherwise I'll have to close it as 'not a real question'. – Joel Coehoorn Nov 13 '08 at 17:54
-
The question was so big and now so small :P haha – Patrick Desjardins Nov 13 '08 at 18:01
-
1Did he wrote the question and the answer in the sames post? – Patrick Desjardins Nov 13 '08 at 18:02
-
@PatrickDesjardins Yes... – Cloud Jun 17 '19 at 13:05
4 Answers
Before MVC I looked at the file path and figured out which tab was currrent. Now it's a lot easier, you can assign the current tab based on the current controller.
Check it out ...
Most of the work happens in the usercontrol.
public partial class AdminNavigation : ViewUserControl
{
/// <summary>
/// This hold a collection of controllers and their respective "tabs." Each Tab should have at least one controller in the collection.
/// </summary>
private readonly IDictionary<Type, string> dict = new Dictionary<Type, string>();
public AdminNavigation()
{
dict.Add(typeof(BrandController), "catalog");
dict.Add(typeof(CatalogController), "catalog");
dict.Add(typeof(GroupController), "catalog");
dict.Add(typeof(ItemController), "catalog");
dict.Add(typeof(ConfigurationController), "configuration");
dict.Add(typeof(CustomerController), "customer");
dict.Add(typeof(DashboardController), "dashboard");
dict.Add(typeof(OrderController), "order");
dict.Add(typeof(WebsiteController), "website");
}
protected string SetClass(string linkToCheck)
{
Type controller = ViewContext.Controller.GetType();
// We need to determine if the linkToCheck is equal to the current controller using dict as a Map
string dictValue;
dict.TryGetValue(controller, out dictValue);
if (dictValue == linkToCheck)
{
return "current";
}
return "";
}
}
Then in your .ascx part of the usercontol call into the SetClass method to check the link against the dict. Like so:
<li class="<%= SetClass("customer") %>"><%= Html.ActionLink<CustomerController>(c=>c.Index(),"Customers",new{@class="nav_customers"}) %></li>
All you need now is the CSS to highlight your current tab. There are a bunch of different ways to do this, but you can get started with some ideas here: http://webdeveloper.econsultant.com/css-menus-navigation-tabs/ Oh, and don't forget to put the usercontrol on your page (or MasterPage) ...
<% Html.RenderPartial("AdminNavigation"); %>
-
Does IDictionary work? It looks like it should be Dictionary instead. – Anthony Potts Nov 14 '08 at 16:30
-
-
1@Anthony - this code works, it's in production now. @Anthony2 - you mean you want a different tab highlighted per controller action? This won't help that. I'd suggest putting your controller specific nav in a user control and declare which tab to make active when embedding the UC in the page. – Kyle West Nov 25 '08 at 20:27
I wrote some simple helper classes to solve this problem. The solution looks att both which controller that is used as well as which action in the controller.
public static string ActiveTab(this HtmlHelper helper, string activeController, string[] activeActions, string cssClass)
{
string currentAction = helper.ViewContext.Controller.
ValueProvider.GetValue("action").RawValue.ToString();
string currentController = helper.ViewContext.Controller.
ValueProvider.GetValue("controller").RawValue.ToString();
string cssClassToUse = currentController == activeController &&
activeActions.Contains(currentAction)
? cssClass
: string.Empty;
return cssClassToUse;
}
You can the call this extension method with:
Html.ActiveTab("Home", new string[] {"Index", "Home"}, "active")
This will return "active" if we are on the HomeController in either the "Index" or the "Home" action. I also added some extra overloads to ActiveTab to make it easier to use, you can read the whole blog post on: http://www.tomasjansson.com/blog/2010/05/asp-net-mvc-helper-for-active-tab-in-tab-menu/
Hope this will help someone.
Regards, --Tomas

- 22,767
- 13
- 83
- 137
-
@tomas-jansson It seems the URL no longer resolves...is it now http://blog.2mas.xyz/asp-net-mvc-helper-for-active-tab-in-tab-menu/ (?) – iokevins Jan 24 '18 at 18:10
One method I am using on a current project - this also helps for other page-specific CSS needs.
First, an HTML helper that returns a string that represents the current controller and action:
public static string BodyClass(RouteData data) {
return string.Format("{0}-{1}", data.Values["Controller"], data.Values["Action"]).ToLower();
}
Then, add a call to this helper in your master page:
<body class="<%=AppHelper.BodyClass(ViewContext.RouteData) %>">
...
</body>
Now, you can target specific pages with your CSS. To answer your exact question about navigation:
#primaryNavigation a { ... }
.home-index #primaryNavigation a#home { ... }
.home-about #primaryNavigation a#about { ... }
.home-contact #primaryNavigation a#contact { ... }
/* etc. */

- 8,343
- 2
- 31
- 38
MVC's default Site.css
comes with a class named 'selectedLink'
which should be used for this.
Add the following to your ul
list in _Layout.cshtml
:
@{
var controller = @HttpContext.Current.Request.RequestContext.RouteData.Values["controller"].ToString();
}
<ul id="menu">
<li>@Html.ActionLink("Home", "Index", "Home", null, new { @class = controller == "Home" ? "selectedLink" : "" })</li>
...
</ul>
I know this is not clean. But just a quick and dirty way to get things rolling without messing with partial views or any of that sort.

- 11,199
- 1
- 48
- 63