1

I am trying to add an active class dynamically on <a> tag based on the location pathname.

Both pathname and href values are the same. However, I can't see active class being added based on the jquery code I have written. I can't figure out what exactly I am missing.

$(document).ready(function() {
  var pathname = window.location.pathname;
  $('.br-sideleft .br-sideleft-menu').find('.active').removeClass('active');
  $('.br-sideleft .br-sideleft-menu li a').each(function() {
    if (this.href == pathname) {
      $(this).addClass('active');
    }
  });
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<div class="br-sideleft">
  <ul class="br-sideleft-menu">
    <li class="br-menu-item">
      <a class="br-menu-link active" asp-area="" asp-controller="Home" asp-action="Index">Link 1</a>
    </li>
  </ul>

  <ul class="br-sideleft-menu">
    <li class="br-menu-item">
      <a class="br-menu-link" asp-area="" asp-controller="Home" asp-action="Page2">Link 2</a>
    </li>
    <li class="br-menu-item">
      <a class="br-menu-link" asp-area="" asp-controller="Home" asp-action="Page3">Link 3</a>
    </li>
  </ul>

  <ul class="br-sideleft-menu">
    <li class="br-menu-item">
      <a class="br-menu-link" asp-area="" asp-controller="Home" asp-action="Page4">Link 4</a>
    </li>
    <li class="br-menu-item">
      <a class="br-menu-link" asp-area="" asp-controller="Home" asp-action="Page5">Link 5</a>
    </li>
  </ul>
</div>
mplungjan
  • 169,008
  • 28
  • 173
  • 236
0xburned
  • 2,625
  • 8
  • 39
  • 69

3 Answers3

2

your if condition is not correct:

$('.br-sideleft .br-sideleft-menu li a').each(function() {
    if (this.href == pathname) { //this is wrong
        $(this).addClass('active');
    }
});

change it to:

$('.br-sideleft .br-sideleft-menu li a').each(function() {
    if ($(this).attr('href') == pathname) {
        $(this).addClass('active');
    }
});
messerbill
  • 5,499
  • 1
  • 27
  • 38
0

An approach i would take is to add a data attribute to anchor onto, this gives you the freedom to define routes that your list items link to and style them accordingly based on route...

(() => {
  $('li')
  .filter((i, li) => $(li).data('route') === window.location.pathname)
  .addClass('active')
})()
<li data-route="/">HOME</li>
<li data-route="/friends">Friends</li>
<li data-route="/profile">Profile</li>
<li data-route="/blog">Blog</li>

As you can see, i run over all the list-items and filter out all the items that do not have data-route attributes that match the window.location.pathname, after i am left with the filtered list, i apply an active class to the matched items.

note this is a generalised answer, hopefully the learning curve taken from the example translates into your answer :-)

mplungjan
  • 169,008
  • 28
  • 173
  • 236
Francis Leigh
  • 1,870
  • 10
  • 25
  • this produces an error due to you have not added `jQuery` to the playground – messerbill Feb 06 '18 at 16:31
  • My aim was for the code to be read and learned from and then maybe drop in a fiddle to check functionally works. not: click run, copy/paste into project & commit all. – Francis Leigh Feb 06 '18 at 16:33
0

A simple console.log(this.href) would show you that reading the href returns the whole url, not what you see in the attribute. So just read the pathname when you are comparing

$('.br-sideleft .br-sideleft-menu li a').filter(function() {
  return this.pathname == pathname
}).addClass('active');
epascarello
  • 204,599
  • 20
  • 195
  • 236