In the default asp.net mvc project, in the Site.Master file, there is a menu navigation list:
<div id="menucontainer">
<ul id="menu">
<li><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li><%= Html.ActionLink("About Us", "About", "Home")%></li>
</ul>
</div>
This renders in the browser to:
<div id="menucontainer">
<ul id="menu">
<li><a href="/">Home</a></li>
<li><a href="/Home/About">About Us</a></li>
</ul>
</div>
I want to be able to dynamically set the active list item, based on the view that is being called. That is, when the user is looking at the home page, I would want the following HTML to be created:
<div id="menucontainer">
<ul id="menu">
<li class="active"><a href="/">Home</a></li>
<li><a href="/Home/About">About Us</a></li>
</ul>
</div>
I would expect that the way to do this would be something like:
<div id="menucontainer">
<ul id="menu">
<li <% if(actionName == "Index"){%> class="active"<%}%>><%= Html.ActionLink("Home", "Index", "Home")%></li>
<li <% if(actionName == "About"){%> class="active"<%}%>><%= Html.ActionLink("About Us", "About", "Home")%></li>
</ul>
</div>
The key bit here is the <% if(actionName == "Index"){%> class="active"<%}%>
line. I do not know how to determine what the current actionName is.
Any suggestions on how to do this? Or, if I'm on completely the wrong track, is there a better way to do this?
I made myself a helper method to handle this type of thing. In the code behind of my master page (could be pushed of to an extension method ... probably a better approach), I put the following code.
protected string ActiveActionLinkHelper(string linkText, string actionName, string controlName, string activeClassName)
{
if (ViewContext.RouteData.Values["action"].ToString() == actionName &&
ViewContext.RouteData.Values["controller"].ToString() == controlName)
return Html.ActionLink(linkText, actionName, controlName, new { Class = activeClassName });
return Html.ActionLink(linkText, actionName, controlName);
}
Then, I just call it in my page like so:
<%= ActiveActionLinkHelper("Home", "Index", "Home", "selected")%>
Inside a view, you can get the current action name with:
ViewContext.RouteData.Values["action"].ToString()
You can also try to detect which is the current selected tab from its controller name and view name, then add the class attribute.
public static string MenuActionLink(this HtmlHelper helper, string linkText, string actionName, string controllerName)
{
var htmlAttributes = new RouteValueDictionary();
if (helper.ViewContext.Controller.GetType().Name.Equals(controllerName + "Controller", StringComparison.OrdinalIgnoreCase))
{
htmlAttributes.Add("class", "current");
}
return helper.ActionLink(linkText, actionName, controllerName, new RouteValueDictionary(), htmlAttributes);
}
In MVC 3 Razor View Engine, you can do it as:
@{string ctrName = ViewContext.RouteData.Values["controller"].ToString();}
<div id="menucontainer">
<ul id="menu">
<li @if(ctrName == "Home"){<text> class="active"</text>}>@ Html.ActionLink("Home", "Index", "Home")</li>
<li @if(ctrName == "About"){<text> class="active"</text>}>@ Html.ActionLink("About Us", "About", "Home")</li>
</ul>
</div>
My sample worked when I have two pages as: Home/About and its controller has same name Index, so I get controller Name for distinction insteed of action. If you want to get action, just replace with following:
@{string ctrName = ViewContext.RouteData.Values["action"].ToString();}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With