ASP.NET MVC Dynamically set CSS Class to list item based on route

ASP.NET MVC Dynamically set CSS Class to list item based on route

I'm looking at the StackOverflow website and I've noticed that there is a Class="youarehere" attribute set to the buttons of active views. This results in the orange styling instead of the grey styling.

Can anybody tell me how they're doing this? What's the easiest way to dynamically set the class based on the URL?

MVC2 and Session Start Event


Test Function in MVC Project
Writing an html helper for those buttons could be one way of doing it.

WebHost4Life host migrated my .NET MVC site and now membership functionality does not work
Assuming the standard routing is set:.
SSI-like feature in ASP.NET / ASP.NET MVC
routes.IgnoreRoute("{resource}.axd/{*pathInfo}"); routes.MapRoute(     "Default",     "{controller}/{action}/{id}",     new { controller = "Home", action = "Index", id = UrlParameter.Optional } ); 
here's how the helper might look like:.
how do i load thousands of rows in my mvc project from database into slickgrid?
public static MvcHtmlString MyButton(this HtmlHelper htmlHelper, string id, string text) {     var button = new TagBuilder("input");     button.MergeAttribute("type", "button");     button.MergeAttribute("value", text);     // get the id from the current route:     var routeId = htmlHelper.ViewContext.RouteData.Values["id"] as string;     if (id == routeId)     {         button.MergeAttribute("class", "active");     }     return MvcHtmlString.Create(button.ToString(TagRenderMode.SelfClosing)); } 
and finally add to your view:.
HTML.DropDownList values from multiple sources?
<%= Html.MyButton("questions", "Questions") %> <%= Html.MyButton("tags", "Tags") %> <%= Html.MyButton("users", "Users") %> 
To further improve the helper you could add additional parameters that will contain the action and the controller this button will redirect to when clicked..
Authentication for IIS content in virtual directory under ASP.NET MVC website

How can I get the client side date and currency formats?


I would assume the simplest possible way is to place the information in the ViewData from the controller/action telling the view where it is, which is what I do.. In the view, you would get that data from the ViewData, then figure out which class name to associate to which location.

Be sure to use an HTML Helper.. Action under Questions controller:.
public ActionResult Index() {       ViewData["CurrentPage"] = "Questions"; } 
Html Helper:.
public static string GetLocationCssClassName(this HtmlHelper html) {          string cssClass = string.Empty;          if(html.ViewData["CurrentPage"] != null)          {              string currentPage = (string)html.ViewData["CurrentPage"];              switch(currentPage)              {                   case "Questions":                        cssClass = "question_css_class";                        break;                  case "Tags":                        cssClass = "tags_css_class";                        break;                  case "Users":                        cssClass = "users_css_class";                        break;               }          }          return cssClass; } 
View Page:.
<div id="main" class="<%: Html.GetLocationCssClassName() %>">     <a href="Questions/Index" class="questions">Questions</a>    <a href="Tags/Index" class="tags">Tags</a>    <a href="Users/Index" class="users">Users</a>  </div> 
.question_css_class a.questions {     background-color: Orange; } 
The code can be improved endlessly, but you get the gist.

Your view has access to ViewData.

Designate a specific key that will hold the current page and output the proper class based on the value inside that specific key..


I have an alternative solution.

Rather than having the helper class decide which "menu" is the active menu.

Decide that in your controller's action.

. Your Controller.
public ActionView Questions() {     MyViewModel model = new MyViewModel ();     model.CurrentMenu = "Questions";      ViewData.Model = model; }  public ActionView Tags() {     MyViewModel model = new MyViewModel ();     model.CurrentMenu = "Tags";      ViewData.Model = model; } 
In the View (a strongly typed view).
<div id="menu">         <ul>     <li class="<%= Html.IsSelectedMenu(Model.CurrentMenu,'Questions') %>"<a href="/Home/Questions">Questions</a></li>      <li class="<%= Html.IsSelectedMenu(Model.CurrentMenu,'Tags') %>"<a href="/Home/Tags">Tags</a></li>      </ul> </div>     
In your css.
li.youarehere {     background-color: orange;     color: #ffffff; } 
In your helper class.
public static class MyHtmlExtensions {     public static MvcHtmlString IsSelectedMenu(this HtmlHelper helper, string currentMenu, string menu2)     {         return currentMenu.Equals (menu2)? "youarehere" : "";     } } 


Here's the answer I needed (In VB) Thanks @Darin.
Imports System.Web.Mvc Imports System.Web.Mvc.Html  Namespace Utilities.HtmlHelpers     Public Module PagingHelpers         Sub New()         End Sub          <System.Runtime.CompilerServices.Extension()> _         Public Function CustomLink( _                 ByVal htmlHelper As HtmlHelper, _                 ByVal linkText As String, _                 ByVal actionName As String, _                 ByVal controllerName As String) As MvcHtmlString               Dim currentAction As String = TryCast(htmlHelper.ViewContext.RouteData.Values.Item("action"), String)             Dim currentController As String = TryCast(htmlHelper.ViewContext.RouteData.Values.Item("controller"), String)             If ((actionName = currentAction) AndAlso _                 (controllerName = currentController)) Or _                 ((controllerName = currentController) AndAlso _                 Not controllerName = "Events") Then                 Return htmlHelper.ActionLink( _                     linkText, _                     actionName, _                     controllerName, _                     Nothing, _                     New With { _                         .class = "youarehere" _                     })             End If             Return htmlHelper.ActionLink(linkText, actionName, controllerName)         End Function     End Module  End Namespace 


you could create a HtmlHelper to return the value, that way you can use it anywhere. Create a “HtmlHelpers” folder in your project Create a static class Define a static method with the first parameter “this HtmlHelper helper“.
using System; using System.Collections.Generic; using System.Web; using System.Web.Mvc;  namespace ThisMVCApp.WebUI.HtmlHelpers {   public static class HtmlHelperExtensions   {     public static string IfActive(this HtmlHelper helper, string controller, string action)     {       string classValue = "";        string currentController = helper.ViewContext.Controller.ValueProvider.GetValue("controller").RawValue.ToString();       string currentAction = helper.ViewContext.Controller.ValueProvider.GetValue("action").RawValue.ToString();        if (currentController == controller && currentAction == action)       {         classValue = "youarehere";       }        return classValue;     }   } } 
Add this to your web.config file (the one in your Views folder!!).
<system.web.webPages.razor>   <host ... 

/> <pages pageBaseType="System.Web.Mvc.WebViewPage"> <namespaces> ...

<add namespace="ThisMVCApp.WebUI.HtmlHelpers" /> </namespaces> </pages> </system.web.webPages.razor>
now you can just apply the above method as any class or attribute on buttons or any element like so :.
<nav>   <ul id="menu">     <li class="@Html.IfActive("Home", "Index")">@Html.ActionLink("Home", "Index", "Home")</li>     <li class="@Html.IfActive("Home", "About")">@Html.ActionLink("About", "About", "Home")</li>  </ul> </nav> 

58 out of 100 based on 23 user ratings 348 reviews