0

I'm using a bootstrap template for a side navbar as a partial in EJS which is then included on all pages that use it. Is was taken from their Dashboard template. The HTML is

<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
  <ul class="nav nav-pills flex-column">
    <li class="nav-item">
      <a class="nav-link active" href="/profile">Overview</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/accountdetails">Account Details</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/admin">Admin</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/transactions">Transactions</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="/contract">Contract</a>
    </li>
  </ul>
</nav>

Whichever link has the active class has particular styling with darker blue in the background. I now want to change this programatically when navigating to the different links.

They're all going to different pages so I could just change there the issue is that I'm including the whole sidebar code as an EJS partial so that wouldn't work. I also tried this answer but it didn't work (flashes the active styling but disappears - probably because it is routing to another page?).

There are plenty of questions here about changing an HTML element programatically but they usually use document.getElementById which seems like too much work (giving each an ID, checking all, etc). Is there a quicker / correct way of doing this?

mcansado
  • 2,026
  • 4
  • 25
  • 39
  • 2
    Possible duplicate of [How to getElementByClass instead of GetElementById with Javascript?](https://stackoverflow.com/questions/1933602/how-to-getelementbyclass-instead-of-getelementbyid-with-javascript) – kulaeff Aug 11 '17 at 14:54
  • It couldn't be the first time ever someone asked this question. – Jeremy Thille Aug 11 '17 at 14:54
  • ` I now want to change this programatically when navigating to the different links` How do you want to change it ? – Jason Krs Aug 11 '17 at 14:55
  • @JeremyThille New comers never try to look for old answers before posting. I did that a lot too ;-) – Jason Krs Aug 11 '17 at 14:56
  • @JasonKrs I thought I could give each an ID and then check if the ID matches the page name but (1) I'd have to give them all an ID just for that and (2) would have to include a script in every different page just for that check. Seemed like a lot of work and for something I take to be common use, just thought there should be a simpler way. – mcansado Aug 11 '17 at 14:59
  • Questions seeking help must include the desired behavior, a specific problem or error and the shortest code necessary to reproduce it in the question itself. Questions without a clear problem statement and showing no effort on solving problem, are not useful to other readers. See: https://stackoverflow.com/help/how-to-ask – serdar.sanri Aug 11 '17 at 14:59
  • @serdar.sanri which of those did I not mention? I specified the problem/desired behavior ("I now want to change this programatically when navigating to the different links."), attempt to solve ("I also tried this answer but it didn't work"), and the code to reproduce is given. – mcansado Aug 11 '17 at 15:04
  • Possible duplicate of [How to change active class while click to another link in bootstrap use jquery?](https://stackoverflow.com/questions/17975922/how-to-change-active-class-while-click-to-another-link-in-bootstrap-use-jquery) – Mister Q Aug 11 '17 at 15:09

4 Answers4

4

You could do the following:

  • Set a click event on .nav-item, to add .active class.
  • Remove .active class from any other sibling element.

$('.nav-item').on('click', function() {
  $(this).addClass('active').siblings('li').removeClass('active');
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Latest compiled and minified CSS -->
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" integrity="sha384-BVYiiSIFeK1dGmJRAkycuHAHRg32OmUcww7on3RYdg4Va+PmSTsz/K68vbdEjh4u" crossorigin="anonymous">
<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
  <ul class="nav nav-pills flex-column">
    <li class="nav-item active">
      <a class="nav-link" href="#">Overview</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">Account Details</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">Admin</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">Transactions</a>
    </li>
    <li class="nav-item">
      <a class="nav-link" href="#">Contract</a>
    </li>
  </ul>
</nav>
Syden
  • 8,425
  • 5
  • 26
  • 45
1

This is a code for helping you.

<nav class="col-sm-3 col-md-2 hidden-xs-down bg-faded sidebar">
        <ul class="nav nav-pills flex-column">
            <li class="nav-item">
                <a class="nav-link active" href="#">Overview</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Account Details</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Admin</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Transactions</a>
            </li>
            <li class="nav-item">
                <a class="nav-link" href="#">Contract</a>
            </li>
        </ul>
    </nav>


    <script type="text/javascript">
        $(function () {
            $(".nav-item").click(function () {
                $(".nav-item").each(function () {
                    $(this).find("a").removeClass("active");
                });
                $(this).find("a").addClass("active");
            });
        });
    </script>
1

Some people answering are a bit confused, thinking you are staying on the same page, and changing the class of your <a> tags. But I think your clicks on these navigate to new pages, and you want the appropriate <a> to have class active when the page loads.

This might help:

<script>
    var path = location.pathname; // ex: '/profile';
    var activeItem = document.querySelector("a[href='" + path + "']");
    activeItem.class += ' active';
</script>

And of course with jquery it's even easier:

$(function() {
    var path = location.pathname;
    $("a[href='" + path + "']").addClass('active');
})
arbuthnott
  • 3,819
  • 2
  • 8
  • 21
0

If your using EJS you can probably do something like the following

<a class="nav-link<% if (page_name === 'profile') { %> active<% } %>" href="/profile">Overview</a>

This is untested but should get you going on the right path. Just do a if statement using EJS's syntax to check if you are on the correct page and add the word active.

Steve K
  • 8,505
  • 2
  • 20
  • 35