Twitter Bootstrap add active class to li

JqueryMenuTwitter Bootstrap

Jquery Problem Overview


Using twitter bootstrap, and I need to initiate active class to the li portion of the main nav. Automagically. We use php not ruby.

Sample nav :

<ul class="nav">
    <li><a href="/">Home</a></li>
    <li><a href="/forums">Forums</a></li>
    <li><a href="/blog">Blog</a></li>
    <li><a href="/faqs.php">FAQ's</a></li>
    <li><a href="/item.php">Item</a></li>
    <li><a href="/create.php">Create</a></li>
</ul>

Bootstrap code is as follows:

<li class="active"><a href="/">Home</a></li>

So just need to figure out how to append the class active to the current page. Have looked thru nearly every answer on Stack, with no real joy.

I had played with this:

/*menu handler*/
$(function(){
    var url = window.location.pathname;  
    var activePage = url.substring(url.lastIndexOf('/')+1);
    $('.nav li a').each(function(){  
        var currentPage = this.href.substring(this.href.lastIndexOf('/')+1);

        if (activePage == currentPage) {
            $(this).parent().addClass('active'); 
        } 
    });
})

But no joy.

Jquery Solutions


Solution 1 - Jquery

For Bootstrap 3:

var url = window.location;
// Will only work if string in href matches with location
$('ul.nav a[href="'+ url +'"]').parent().addClass('active');

// Will also work for relative and absolute hrefs
$('ul.nav a').filter(function() {
    return this.href == url;
}).parent().addClass('active');

#Update For Bootstrap 4:

var url = window.location;
// Will only work if string in href matches with location
$('ul.navbar-nav a[href="'+ url +'"]').parent().addClass('active');

// Will also work for relative and absolute hrefs
$('ul.navbar-nav a').filter(function() {
	return this.href == url;
}).parent().addClass('active');

Solution 2 - Jquery

We managed to fix in the end:

/*menu handler*/
$(function(){
  function stripTrailingSlash(str) {
    if(str.substr(-1) == '/') {
      return str.substr(0, str.length - 1);
    }
    return str;
  }

  var url = window.location.pathname;  
  var activePage = stripTrailingSlash(url);

  $('.nav li a').each(function(){  
    var currentPage = stripTrailingSlash($(this).attr('href'));

    if (activePage == currentPage) {
      $(this).parent().addClass('active'); 
    } 
  });
});

Solution 3 - Jquery

You don't really need any JavaScript with Bootstrap:

 <ul class="nav">
     <li><a data-target="#" data-toggle="pill" href="#accounts">Accounts</a></li>
     <li><a data-target="#" data-toggle="pill" href="#users">Users</a></li>
 </ul>

To do more tasks after the menu item is selected you need JS as explained by other posts here.

Hope this helps.

Solution 4 - Jquery

Solution 5 - Jquery

This did the job for me including active main dropdowns and the active childrens (thanks to 422):

$(document).ready(function () {
    var url = window.location;
    // Will only work if string in href matches with location
    $('ul.nav a[href="' + url + '"]').parent().addClass('active');
    
    // Will also work for relative and absolute hrefs
    $('ul.nav a').filter(function () {
        return this.href == url;
    }).parent().addClass('active').parent().parent().addClass('active');
});

Solution 6 - Jquery

If you are using an MVC framework with routes and actions:

$(document).ready(function () {
    $('a[href="' + this.location.pathname + '"]').parent().addClass('active');
});

As illustrated in this answer by Christian Landgren: https://stackoverflow.com/a/13375529/101662

Solution 7 - Jquery

Try this.

// Remove active for all items.
$('.page-sidebar-menu li').removeClass('active');

// highlight submenu item
$('li a[href="' + this.location.pathname + '"]').parent().addClass('active');

// Highlight parent menu item.
$('ul a[href="' + this.location.pathname + '"]').parents('li').addClass('active');

Solution 8 - Jquery

This works fine for me. It marks both simple nav elements and dropdown nav elements as active.

$(document).ready(function () {
   var url = window.location;
       
   $('ul.nav a[href="' + this.location.pathname + '"]').parent().addClass('active');

   $('ul.nav a').filter(function() {
      return this.href == url;
   }).parent().parent().parent().addClass('active');
});

Passing this.location.pathname to $('ul.nav a[href="'...'"]') marks also simple nav elements. Passing url did'nt work for me.

Solution 9 - Jquery

Just in case you are using Boostrap in Angulajs: this is a simple directive that works for me (because data-toggle cited by Kam is not included in Angular-ui). Hope can help.

app.directive("myDataToggle", function(){
    function link(scope, element, attrs) {
        var e = angular.element(element);
        e.on('click', function(){
            e.parent().parent().children().removeClass('active');
            e.parent().addClass("active");
        })
    }
    return {
        restrict: 'A',
        link: link
    };
});

<ul class="nav nav-sidebar">
    <li><a href="#/page1" my-data-toggle>Page1</a></li>
    <li><a href="#/page2" my-data-toggle>Page2</a></li>
    <li><a href="#/page3" my-data-toggle>Page3</a></li>
</ul>

Solution 10 - Jquery

The solution is simple and there is no need for server side or ajax, you only need jQuery and Bootstrap. On every page add an id to the body tag. Use that id to find a tag that contains the page name (value of a tag).

Example:

page1.html

<body id="page1">
    <ul class="nav navbar-nav">
        <li><a href="page1.html">Page1</a></li>
        <li><a href="page2.html">Page2</a></li>
    </ul>
    <script src="script.js"></script>
</body>

page2.html

<body id="page2">
    <ul class="nav navbar-nav">
        <li><a href="page1.html">Page1</a></li>
        <li><a href="page2.html">Page2</a></li>
    </ul>
    <script src="script.js"></script>
</body>

script.js

<script>
    $(function () {
        $("#page1 a:contains('Page1')").parent().addClass('active');
        $("#page2 a:contains('Page2')").parent().addClass('active');
     });
</script>

Big thanks to Ben! YouTube

Solution 11 - Jquery

I had the same problem, and this is what I added in my app launch script, and it worked smoothly. Here is the javascript

$(document).ready(function($){
  var navs = $('nav > ul.nav');

  // Add class .active to current link
  navs.find('a').each(function(){

    var cUrl = String(window.location).split('?')[0];
    if (cUrl.substr(cUrl.length - 1) === '#') {
      cUrl = cUrl.slice(0,-1);
    }

    if ($($(this))[0].href===cUrl) {
      $(this).addClass('active');

      $(this).parents('ul').add(this).each(function(){
        $(this).parent().addClass('open');
      });
    }
  });
});

And the corresponding HTML is shown below. I'm using CoreUI, a phenomenal open source admin template and has support for many front end frameworks like Angular, plain bootstrap, Angular 4 etc.

<div class="sidebar">
<nav class="sidebar-nav open" >
    <ul class="nav" id="navTab" role="tablist">
        <li class="nav-item">
            <a class="nav-link"    href="/summary"><i class="icon-speedometer"></i> Dashboard </a>
        </li>
        <li class="nav-item">
            <a class="nav-link"    href="/balanceSheet"><i class="icon-chart"></i> Balance Sheet </a>
        </li>
        <li class="divider"></li>
        <li class="nav-title border-bottom">
            <p class="h5 mb-0">
                <i class="icon-graph"></i> Assets
            </p>
        </li>
     </ul>
  </nav>
</div>

Solution 12 - Jquery

There is a hitch with the accepted answer in some rare cases for bootstrap 4: In order to use the solution for relative paths like:

<ul class="navbar-nav nav-t">
   <li class="nav-item"><a href="index.php" class="nav-link">Home</a></li>
   <li class="nav-item"><a href="about.php" class="nav-link">About</a></li>
   <li class="nav-item"><a href="blog.php" class="nav-link">Blog</a></li>
   <li class="nav-item"><a href="info.php" class="nav-link">Info</a></li>
</ul>

Then you will find out that the code for:

 if (activePage == currentPage) {
      $(this).parent().addClass('active'); 
    } 

active page returns the whole url and current location returns the current href DOM Element value which is filename.php. To solve this just tweak the code a little by adding a method to correct this:

//... other js/jquery code
var activeMenuItemChanges=function () {
	function stripTrailingSlash(str) {
		if(str.substr(-1)=='/'){
			return str.substr(0, str.length -1);
		}
		return str;
	}
	// for cases where we do not use full url but relative file names in the href of ul>li>a tags:
	function getRelativeFileName(str){
		let page=str.substr(str.lastIndexOf('/')+1);
		if(page.length > 0){
			return page;
		}
		return 'index'|'index.php';
	}

	let url=window.location.pathname;

	let activeLocation=stripTrailingSlash(url);

	let activeFileName=getRelativeFileName(activeLocation);

	$('.nav-item a').each(function() {
		let currentLocation=stripTrailingSlash($(this).attr('href'));
		if(activeFileName==currentLocation){
			$(this).parent().addClass('active');
		}
	});
}
activeMenuItemChanges();

//... other js/jquery code

Solution 13 - Jquery

Here is complete Twitter bootstrap example and applied active class based on query string.

Few steps to follow to achieve correct solution:

  1. Include latest jquery.js and bootstrap.js javascript file.

  2. Include latest bootstrap.css file

  3. Include querystring-0.9.0.js for getting query string variable value in js.

  4. HTML:

JQuery in Script Tag:

$(function() {
    $(".nav li").click(function() {
        $(".nav li").removeClass('active');
        setTimeout(function() {
            var page = $.QueryString("page");
            $(".nav li:eq(" + page + ")").addClass("active");
        }, 300);

    });
});

I have done complete bin, so please click here http://codebins.com/bin/4ldqpaf

Solution 14 - Jquery

None of these worked for me. My Bootstrap setup navigates to separate pages (so I can't do it on a click action, but the active class is removed on the navigation to a new page), and my urls don't match exactly. So here's what I did, based on my exception-based situation. Hope it helps others:

//Adding the active class to Twitter bootstrap navs, with a few alternate approaches

$(document).ready(function() {
  var rawhref = window.location.href; //raw current url	
  var newpage = ((window.location.href.match(/([^\/]*)\/?$/)[1]).substring(1)); //take only the last part of the url, and chop off the first char (substring), since the contains method below is case-sensitive. Don't need to do this if they match exactly.
  if (newpage == 'someNonMatchingURL') {  //deal with an exception literally
	newpage = 'matchingNavbarText'
	}
  if (rawhref.indexOf('somePartofURL') != -1) { //look for a consistent part of the path in the raw url to deal with variable urls, etc.
	newpage = "moreMatchingNavbarText"
	}
  $(".nav li a:contains('" + newpage + "')").parent().addClass('active'); //add the active class. Note that the contains method requires the goofy quote syntax to insert a variable.

});

Solution 15 - Jquery

To activate the menus and submenus, even with params in the URL, use the code bellow:

// Highlight the active menu
$(document).ready(function () {
    var action = window.location.pathname.split('/')[1];

    // If there's no action, highlight the first menu item
    if (action == "") {
        $('ul.nav li:first').addClass('active');
    } else {
        // Highlight current menu
        $('ul.nav a[href="/' + action + '"]').parent().addClass('active');

        // Highlight parent menu item
        $('ul.nav a[href="/' + action + '"]').parents('li').addClass('active');
    }
});

This accepts URLs like: > /posts
> /posts/1
> /posts/1/edit

Solution 16 - Jquery

$(function() {
// Highlight the active nav link.
var url = window.location.pathname;
var filename = url.substr(url.lastIndexOf('/') + 1);
$('.navbar a[href$="' + filename + '"]').parent().addClass("active");

});

For more details Click Here!

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Question422View Question on Stackoverflow
Solution 1 - JqueryImtiazView Answer on Stackoverflow
Solution 2 - Jquery422View Answer on Stackoverflow
Solution 3 - JqueryKamView Answer on Stackoverflow
Solution 4 - Jqueryuser2045474View Answer on Stackoverflow
Solution 5 - JquerySebastian ViereckView Answer on Stackoverflow
Solution 6 - JqueryOliverView Answer on Stackoverflow
Solution 7 - JqueryDurga PrasadView Answer on Stackoverflow
Solution 8 - JqueryIlker CatView Answer on Stackoverflow
Solution 9 - JquerymvillegasView Answer on Stackoverflow
Solution 10 - JqueryFilip GjorgjevikjView Answer on Stackoverflow
Solution 11 - JqueryKrishna VedulaView Answer on Stackoverflow
Solution 12 - Jquerybriancollins081View Answer on Stackoverflow
Solution 13 - Jquerygaurang171View Answer on Stackoverflow
Solution 14 - JqueryawvidmerView Answer on Stackoverflow
Solution 15 - JquerySeraltoView Answer on Stackoverflow
Solution 16 - JqueryKanon ChowdhuryView Answer on Stackoverflow