I need to highlight active link in the menu. My menu is in the master page by the way. I'm looking for the best way to implement this? Any ideas?
The best way to handle this is to write an HTML helper. You could use RouteData.Values["action"]
to get the currently executing action and compare to the menu name and if they match apply a CSS class that will highlight it.
public static MvcHtmlString MenuItem(
this HtmlHelper htmlHelper,
string action,
string text
)
{
var menu = new TagBuilder("div");
var currentAction = (string)htmlHelper.ViewContext.RouteData.Values["action"];
if (string.Equals(
currentAction,
action,
StringComparison.CurrentCultureIgnoreCase)
)
{
menu.AddCssClass("highlight");
}
menu.SetInnerText(text);
return MvcHtmlString.Create(menu.ToString());
}
And then use this helper to render the menu items:
<%: Html.MenuItem("about", "About us") %>
<%: Html.MenuItem("contact", "Contact us") %>
...
I am always using this solution Html Part
<ul>
@Html.ListItemAction("Home Page","Index","Home")
@Html.ListItemAction("Manage","Index","Home")
</ul>
Helper Part
public static class ActiveLinkHelper
{
public static MvcHtmlString ListItemAction(this HtmlHelper helper, string name, string actionName, string controllerName)
{
var currentControllerName = (string)helper.ViewContext.RouteData.Values["controller"];
var currentActionName = (string)helper.ViewContext.RouteData.Values["action"];
var sb = new StringBuilder();
sb.AppendFormat("<li{0}", (currentControllerName.Equals(controllerName, StringComparison.CurrentCultureIgnoreCase) &&
currentActionName.Equals(actionName, StringComparison.CurrentCultureIgnoreCase)
? " class=\"active\">" : ">"));
var url = new UrlHelper(HttpContext.Current.Request.RequestContext);
sb.AppendFormat("<a href=\"{0}\">{1}</a>", url.Action(actionName, controllerName), name);
sb.Append("</li>");
return new MvcHtmlString(sb.ToString());
}
}
I use this solution:
First - add attribute data-menuPageId to your menu links
<ul class="menu">
<li data-menuPageId="home">
@(Html.Link<HomeController>(x => x.Index(), "Home"))
</li>
<li data-menuPageId="products">
@(Html.Link<ProductsController>(x => x.Index(), "Products"))
</li>
</li>
Next - add hidden field for current page Id to Layout.cshtml
<input type="hidden" id="currentPageId" value="@(ViewBag.Page ?? "home")" />
Add ViewBag.Page initializtion at your pages like Home or Products
@{
ViewBag.Page = "products";
}
And last thing you should reference this javascipt from yor Layout.cshtml
$(function() {
var pageIdAttr = "data-menuPageId";
var currentPage = $("#currentPageId").attr("value");
var menu = $(".menu");
$("a[" + pageIdAttr + "]").removeClass("selected");
$("a[" + pageIdAttr + "=\"" + currentPage + "\"]", menu).addClass("selected");
});
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