Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Adding "active" tag to navigation list in an asp.net mvc master page

Tags:

asp.net-mvc

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?

like image 309
dp. Avatar asked Oct 18 '08 04:10

dp.


4 Answers

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")%>
like image 199
Adam Carr Avatar answered Oct 20 '22 13:10

Adam Carr


Inside a view, you can get the current action name with:

ViewContext.RouteData.Values["action"].ToString()
like image 22
Craig Stuntz Avatar answered Oct 20 '22 14:10

Craig Stuntz


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);
}
like image 10
labilbe Avatar answered Oct 20 '22 13:10

labilbe


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();}
like image 10
Telvin Nguyen Avatar answered Oct 20 '22 12:10

Telvin Nguyen