1

I have the following list:

<!-- List -->
<ul class="nav nav-sm nav-tabs nav-vertical mb-4 steps-sampling">
  <li class="nav-item">
    <a class="nav-link active" id="link1" href="{{ url_for('overview') }}">
      <i class="bi-list-check nav-icon"></i>Overview
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="{{ url_for('upload') }}">
      <i class="bi-file-arrow-up nav-icon"></i> Upload file
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="{{ url_for('choose_numeric') }}">
      <i class="bi-sort-numeric-down nav-icon"></i> Choose the numeric column
    </a>
  </li>
</ul>

It starts with the first list element as active. I want to change the active state based on the list element which is clicked.

I tried:

$('.steps-sampling').on('click','a', function(){
   $(this).addClass('active').siblings().removeClass('active');
});

And (added id to anchor tag)

//on first time load set the home menu item active
$(".steps-sampling a#link1").addClass("active");

//on click remove active class from all li's and add it to the clicked li
$("a").click(function(){
   $("a").removeClass("active");
    $(this).addClass("active");
});

But both do not work.

This is the .active class I could find for nav-link. I only have access to the min.css so it is kind of hard to find (not sure if this is sufficient)

.nav-link.active{border-color:#006673}

I cannot add active to the li element since it does not seem to work with the Bootstrap template I am using.

How can I solve this?

Zal
  • 935
  • 1
  • 7
  • 17
  • could you post the style used for the .acrive class ! – Bourbia Brahim Dec 27 '21 at 10:46
  • I added the css active class to my question, not sure if that is correct / sufficient, it was kind of hard to search the `min.css` and read it correctly. – Zal Dec 27 '21 at 10:58
  • @Zal there's always a better way to handle most situations than to use an `#id`. What are you using a roaming `#id` for ? I'm guessing that you can probably reference the `.active` class instead. – zer00ne Dec 27 '21 at 11:34
  • I agree, the id was just for testing for the second solution to see if something else might work. @zer00ne – Zal Dec 27 '21 at 12:28

4 Answers4

1

Your code works well ,Except for styling ,

Just try to force style using !important to overide default bootstrap style

See below snippet :

$('.steps-sampling').on('click','a', function(){
   $(this).addClass('active').siblings().removeClass('active');
});

//on first time load set the home menu item active
$(".steps-sampling a#link1").addClass("active");

//on click remove active class from all li's and add it to the clicked li
$("a").click(function(){
   $("a").removeClass("active");
    $(this).addClass("active");
});
.active {
  color:green !important;
  font-weight:bold;
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/js/bootstrap.min.js"></script>
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.3/dist/css/bootstrap.min.css" rel="stylesheet"/>
<!-- List -->
<ul class="nav nav-sm nav-tabs nav-vertical mb-4 steps-sampling">
  <li class="nav-item">
    <a class="nav-link active" id="link1" href="#">
      <i class="bi-list-check nav-icon"></i>Overview
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">
      <i class="bi-file-arrow-up nav-icon"></i> Upload file
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">
      <i class="bi-sort-numeric-down nav-icon"></i> Choose the numeric column
    </a>
  </li>
</ul>
Bourbia Brahim
  • 14,459
  • 4
  • 39
  • 52
  • The snippet works indeed, but using it on my code still does not work, it works for 0.5 sec than it shoots back to the first element. I added `.nav-link.active{ border-color:#006673 !important; }` to my `custom.css` which loads after the `bootstrap` theme. Any further ideas maybe? Or any other information I can provide? – Zal Dec 27 '21 at 11:08
  • @Zal Seem other click event applying some default stylie or sush ,Could you show a screen capture of console html element (F12) once you click on tabs ! – Bourbia Brahim Dec 27 '21 at 11:34
  • I will try to upload a screen capture. Thanks – Zal Dec 27 '21 at 12:28
  • Thanks for helping, I found the solution if you're interested, see my answer below – Zal Dec 27 '21 at 14:18
1

Every time you set a function as listener to an event, when it fires it passes the event object to the function, you can just use it to know on which element the user has clicked:

$("a").click(function(evt){
    $("a").removeClass("active");
    $(evt.target).addClass("active");
});

I would like to suggest a more correct approach, with the same result:

$("a").on("click", function(evt){
    $("a").removeClass("active");
    $(evt.target).addClass("active");
});

Sometimes, depending on what you put inside the element that has the event bound, evt.target can be an element different from the one you bound the event on, so you must ensure that the element you style with the class is the correct one:

$("a").on("click", function(evt){
    $("a").removeClass("active");

    let tgt=evt.target;
    if(!$(tgt).is("a")) tgt = $(tgt).closest("a");
    $(tgt).addClass("active");
});
Fanfurlio
  • 216
  • 2
  • 7
  • Tried both your solutions, unfortunately they don't work. Same comment as above, it looks like for 0.5 sec the active state is set on the link I click, but it shoots back to the first element. Any further ideas maybe? – Zal Dec 27 '21 at 11:10
  • You surely have another event or other code that is reverting your runtime changes, maybe a `location` or some other CSS manipulation code, we can't tell without seeing your code. – Fanfurlio Dec 27 '21 at 11:25
  • I understand and I agree, but I am not sure how to provide a full reproducible example, since I think this hits quite some parts in our code. – Zal Dec 27 '21 at 12:29
  • Thanks for helping, I found the solution if you're interested, see my answer below – Zal Dec 27 '21 at 14:18
1

After searching other solutions I found this which works.It has to do with the fact that the page is refreshed and is set back to active on the first element:

    <script>
      $(document).ready(function() {
        $('a.active').removeClass('active');
        $('a[href="' + location.pathname + '"]').closest('a').addClass('active');
      });
    </script>
Zal
  • 935
  • 1
  • 7
  • 17
0

You can try this code :

<!DOCTYPE html>
<html>
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script>
<style>
.nav-item .nav-link {text-decoration : none;}
.nav-item .nav-link:hover{ border: 2px solid #006673 !important; }
.nav-item .nav-link.active{ border: 2px solid #006673 !important; }
</style>
<script>
$(document).ready(function(){
  $(document).on('click','.nav-link', function(){
     $('.nav-link').removeClass('active');
     $(this).addClass('active');
  });
});
</script>
</head>
<body>

<!-- List -->
<ul class="nav nav-sm nav-tabs nav-vertical mb-4 steps-sampling">
  <li class="nav-item">
    <a class="nav-link active" id="link1" href="#">
      <i class="bi-list-check nav-icon"></i>Overview
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">
      <i class="bi-file-arrow-up nav-icon"></i> Upload file
    </a>
  </li>
  <li class="nav-item">
    <a class="nav-link" href="#">
      <i class="bi-sort-numeric-down nav-icon"></i> Choose the numeric column
    </a>
  </li>
</ul>

</body>
</html>
Yagnik Sangani
  • 227
  • 1
  • 8