Setting list anchor to active based on click - javascript

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?

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>

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");
});

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>

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>

Related

bootstrap 4 pills not changing color when clicked

I'm trying to use this bootstrap pills example but there is no javascript or css that goes along with it. How do I go about highlighting the pills that is clicked. In the example when the pill is clicked it turns purple. I am trying something like the below but it does not work. Thank you.
$('#nav-link').on('click', function(e) {
this.backgroundColor = 'black';
});
You should toggle a class that sets background.
js
$('#navbar #nav-link').removeClass("active");
$(this).addClass('active');
#navbar is id of your nav-bar.
css
.active { 
background: black;
}
$("#navbar").on("click", "li", function(e) {
$('#navbar ul li').removeClass("active");
$(this).addClass('active');
});
.active {
background: red;
}
<link href="https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.5.0/css/bootstrap.min.css" rel="stylesheet" />
<script src="https://code.jquery.com/jquery-3.3.1.slim.min.js"></script>
<nav class="navbar navbar-light navbar-expand-sm" id="navbar">
<div class="collapse navbar-collapse" id="navbar-list-2">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#">Home <span class="sr-only">(current)</span></a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">About Us</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Blog</a>
</li>
</ul>
</div>
</nav>

How to pull active tab first int the position and push the another after the active one?

I have 2 nav tabs i need when click one and become active to be first tab and the other come after it
$(".nav-tabs a").click(function() {
if ($(this).hasClass('active')) {
$(this).css('margin-right', '0px');
$(this).css('margin-left', '-139px');
}
});
if (!$(".nav-tabs a").hasClass('active')) {
$(this).css('margin-right', '-139px');
$(this).css('margin-left', '0px');
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="nav nav-tabs">
<li class="nav-item ">
<a class="nav-link active" data-toggle="tab" href="#home">
<i class="fa fa-clock-o"></i> زيارة بالساعة</a>
</li>
<li class="nav-item">
<a class="nav-link" data-toggle="tab" href="#menu1">
<i class="fa fa-calendar"></i> زيارة بالشهر</a>
</li>
</ul>
I'd advise you to use more elegant solution, without direct css mutations. You can on tab click just prepend() current tab to the parent's div and it will be first. I've prepared a sample fiddle for you.
$(".nav-item").click(function() {
$(this).parent().prepend(this);
});

Bootstrap Navbar Active State Switching Bootstrap (Javascript Related)

I use the class="active" on my navbar navigation items with the most current version of bootstrap (4) and it does not switch when I click on the links. I found similar questions to this and tried to make the javascript fit my own code, but it didn't work. Note: These links on my navbar are all on the same page. The goal is to make the clicked on nav-item link active so that the user knows what they're currently viewing on the page.
Here is what my javascript code looks like:
$(".nav .nav-link").on("click", function(){
$(".nav").find(".active").removeClass("active");
$(this).addClass("active");
});
Here is what my html navbar code looks like:
<header>
<nav class="navbar navbar-expand-md navbar-dark fixed-top bg-dark">
<img class="logo" src="images/logo.png" width="55px" align="left">
<a class="navbar-brand" href="index.html">ROWAN AEΠ</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarCollapse" aria-controls="navbarCollapse" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarCollapse">
<!--Div for Alignment Purposes Below -->
<div class="navig-align">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link active" href="#HOME">HOME</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#ABOUT">ABOUT</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">BOARD</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">RECRUITMENT</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">FAQ</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">CONTACT</a>
</li>
<li class="nav-item">
<a id="donatebutton" class="nav-link" href="http://www.example.org" target="_blank">DONATE
<img class="donateimg" src="images/externallink.png" alt=""></a>
</li>
</ul>
</div>
</div>
</nav>
</header>
If someone can look at my html and figure out a solution to for the script, I will be very grateful.
You dont appear to have an ancestor to the nav list with the class of "nav" - also the nav-link li's are what should get the 'active' class - not the 'a' within it.
Also - you can target the active item directly to remove the active class - whether its the li or the a.
if you want to keep the active class on the a - then just change the click handler
$(".nav-link").on("click", function(){
$(".nav-link.active").removeClass("active");
$(this).addClass("active");
});
If you want the active class on the li - then
if you want to keep the active class on the a - then just change the click handler
$(".nav-item").on("click", function(){
$(".nav-item.active).removeClass("active");
$(this).addClass("active");
});
You do not have a class .nav which you are referencing in your jQuery selector.
Update your jQuery too:
$(".nav-link").on("click", function(){
$(".nav-link.active").removeClass("active");
$(this).addClass("active");
});
Link to example: https://jsfiddle.net/Lb3u9c5d/

Adding second child to dropdown menu

Im experiencing an issue adding a second child to the drop-down-menu.
here is my html code:
<ul class="sidenav sidenav-fixed" id="nav-mobile">
<li>
<a onclick="load('file-name')"><i class="material-
icons">home</i>TEXT
</a>
</li>
<div class="divider"></div>
<li><a onclick="load('file-name')"><i class="material-
icons">apps</i>TEXT</a>
</li>
<li><a onclick="load('file-name')"><i class="material-
icons">copyright</i>Copyright</a>
</li>
<li class="button-dropdown">
<a onclick="load('file-name') class="dropdown-toggle"><i class="material-
icons">assignment</i>Unit A<i class="fa fa-angle-right changed"></i>
</a>
<ul class="dropdown-menu" style="display: none;">
<li>
<a onclick="load('file-name')">Menu 1</a>
</li>
</ul>
<ul class="dropdown-menu" style="display: none;">
<li>
<a onclick="load('file-name')">Menu 2</a>
</li>
</ul>
</li>
</ul>
and here is my js:
jQuery(document).ready(function (e) {
$(".dropdown-toggle").click(function () {
$(this).parents(".button-dropdown").children(".dropdown-
menu").toggle().parents(".button-dropdown").children(".dropdown-
toggle").addClass("active")
});
$('.dropdown-toggle').on('click', function () {
$(this)
.find('.changed')
.toggleClass('fa-angle-down')
.toggleClass('fa-angle-right');
});
});
Here are the styles applied for drop-down-menu:
.dropdown-menu li > a {
text-align: center;
}
.dropdown-menu li:hover > a {
background-color: #385170 !important;
color: #fff !important;
}
.changed {
margin-left: 5px;
}
I need to add another child under Menu 1 and Menu 2.
Thanks a lot for your help.
The first issue I found in your code is that you are defining the same event twice, which means that only the last one will be executed.
To append items with jQuery inside an event listener is as easy as:
Keeping code clean.
Globals at the beginning of your code:
var buttonDropdown = $(".button-dropdown");
And then your event listener for dropdown-toggle click:
$('.dropdown-toggle').on('click', function () {
buttonDropdown.append("<li>new item</li>");
});
This will append a new item to button-dropdown everytime you click dropdown-toggle.
Here is an example:
var buttonDropdown = $(".button-dropdown");
jQuery(document).ready(function (e) {
$('.dropdown-toggle').on('click', function (event) {
let itemNumber = buttonDropdown.children().length;
buttonDropdown.append("<ul><li>Menu "+itemNumber+"</li></ul>");
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<ul class="sidenav sidenav-fixed" id="nav-mobile">
<li>
<a onclick="load('file-name')">
<i class="material- icons">home</i>TEXT
</a>
</li>
<div class="divider"></div>
<li>
<a onclick="load('file-name')">
<i class="material- icons">apps</i>TEXT
</a>
</li>
<li>
<a onclick="load('file-name')">
<i class="material- icons">copyright</i>Copyright
</a>
</li>
<li class="button-dropdown">
<a onclick="load('file-name')" class="dropdown-toggle">
<i class="material- icons">assignment</i>Unit A
<i class="fa fa-angle-right changed"></i>
</a>
<ul class="dropdown-menu" style="display: block;">
<li>
<a onclick="load('file-name')">Menu 1</a>
</li>
</ul>
<ul class="dropdown-menu" style="display: block;">
<li>
<a onclick="load('file-name')">Menu 2</a>
</li>
</ul>
</li>
</ul>
Note: This example is made from the context you provided. If it still not solves your entire issue, feel free to edit your question and comment here so I can update mine with the requirements for your question.
And also, you did not provide any styles for your code, that's why it looks so plain.

How to change element's class to active?

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?
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>
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');
})
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>
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.

Categories