Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

MVC with Bootstrap Navbar - Set Selected Item to Active

I'm learning Bootstrap and can't get the selected item into an "active" state. The active state remains on the default item. The newly selected/clicked item changes to active briefly, but reverts back. I've read all the posts and still can't get this code to work. I'm using MVC5 and JQuery 2.1.

EDIT: If I change the li's hrefs to href="#", then the active class gets applied properly. What's happening when a new view gets loaded? I think Sebastian's response is close, but gets messy with Areas.

Markup

<div class="navbar-wrapper">     <div class="container">         <div class="navbar navbar-inverse navbar-fixed-top">              <div class="navbar-header">                 <a class="navbar-toggle" data-toggle="collapse" data-target=".nav-collapse">                     <span class="icon-bar"></span>                     <span class="icon-bar"></span>                     <span class="icon-bar"></span>                 </a>                 <a class="navbar-brand" href="#">Test</a>             </div>             <div class="btn-group pull-right">                 <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">                     <i class="icon-user"></i>Login           <span class="caret"></span>                 </a>                 <ul class="dropdown-menu">                     <li><a href="#">Profile</a></li>                     <li class="divider"></li>                     <li><a href="#">Sign Out</a></li>                 </ul>             </div>             <div class="navbar-collapse collapse">                 <ul class="nav navbar-nav">                     <li class="active"><a href="~/Home">Home</a></li>                     <li><a href="~/Home/About">About</a></li>                     <li><a href="~/Student">Students Sample</a></li>                     <li class="dropdown">                         <a href="#" class="dropdown-toggle" data-toggle="dropdown">Dropdown <b class="caret"></b></a>                         <ul class="dropdown-menu">                             <li><a href="~/Admin/Home/Index"">Admin</a></li>                             <li><a href="#">Another action</a></li>                             <li><a href="#">Something else here</a></li>                             <li class="divider"></li>                             <li><a href="#">Separated link</a></li>                             <li><a href="#">One more separated link</a></li>                         </ul>                     </li>                 </ul>             </div>          </div>     </div>     <!-- /container --> </div> <!-- /navbar wrapper --> 

Script

<script type="text/javascript">      $(function () {         $('.navbar-nav li').click(function () {             $(this).addClass('active').siblings().removeClass('active');         });     });  </script> 

EDIT: Here's what I ended up doing with the help of the posted answers and some research.

public static string MakeActive(this UrlHelper urlHelper,string action, string controller, string area = "")         {             string result = "active";             string requestContextRoute;             string passedInRoute;              // Get the route values from the request                        var sb = new StringBuilder().Append(urlHelper.RequestContext.RouteData.DataTokens["area"]);             sb.Append("/");             sb.Append(urlHelper.RequestContext.RouteData.Values["controller"].ToString());             sb.Append("/");             sb.Append(urlHelper.RequestContext.RouteData.Values["action"].ToString());             requestContextRoute = sb.ToString();              if (string.IsNullOrWhiteSpace(area))             {                 passedInRoute = "/" + controller + "/" + action;             }             else             {                 passedInRoute = area + "/" + controller + "/" + action;             }              //  Are the 2 routes the same?             if (!requestContextRoute.Equals(passedInRoute, StringComparison.OrdinalIgnoreCase))             {                 result = null;             }              return result;         } 
like image 408
Big Daddy Avatar asked Mar 14 '14 14:03

Big Daddy


2 Answers

You have to check in your controller or view which menu item is active based on the current url:

I have an extension method similar to this:

public static string MakeActiveClass(this UrlHelper urlHelper, string controller) {     string result = "active";      string controllerName = urlHelper.RequestContext.RouteData.Values["controller"].ToString();      if (!controllerName.Equals(controller, StringComparison.OrdinalIgnoreCase))     {         result = null;     }      return result; } 

You can use it in your view like this:

<!-- Make the list item active when the current controller is equal to "blog" --> <li class="@Url.MakeActive("blog")">    <a href="@Url.Action("index", "blog")">....</a> </li> 
like image 195
SebastianStehle Avatar answered Oct 03 '22 10:10

SebastianStehle


The JavaScript isn't working because the page is getting reloaded after it runs. So it correctly sets the active item and then the page loads because the browser is following the link. Personally, I would remove the JavaScript you have because it serves no purpose. To do this client side (instead of the server side code you have), you need JavaScript to set the active item when the new page loads. Something like:

$(document).ready(function() {     $('ul.nav.navbar-nav').find('a[href="' + location.pathname + '"]')         .closest('li').addClass('active'); }); 

I recommend adding an id or other class to your navbar so you can be sure you have selected the correct one.

like image 33
Jeff Walker Code Ranger Avatar answered Oct 03 '22 12:10

Jeff Walker Code Ranger