I have the following side bar menu code. Upon click on any of the nav items it highlights / makes the class active.
$(document).ready(function() {
$(".nav li").click(function() {
if ($(".nav li").removeClass("active")) {
$(this).removeClass("active");
}
$(this).addClass("active");
});
});
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Now I have similar items at the top of the page presented as a connected circle:
<div class="connected-line">
<ul>
<li class="active">1
<p> System </p>
</li>
<li id="hosts">2
<p> Hosts </p>
</li>
<li>3
<p> Cards </p>
</li>
<li>4
<p> Devices </p>
</li>
</ul>
</div>
See jsfiddle:
https://jsfiddle.net/vk3qw09f/345/
Now if the user clicks on the side bar menu, it should also set corresponding class as active on the "connected-line" list elements.
For eg: Cliking on navbar "System Settings" should also add a class 'active' to the li item inside the circled li "System"
I know it's not recommednded to have the same 2 ids on the same page. So looking for a smarter way to achieve this.
EDIT: my current code will only make that class active: $(this).addClass("active");
I probably want to make all classes that share the same name active
I assume this is what you're looking for.
$(document).ready(function() {
$(".nav li a").click(function(e) {
e.preventDefault();
$(".nav li").removeClass("active");
$(".connected-line li").removeClass("active");
$($(this).attr('href')).addClass('active');
$(this).addClass("active");
});
});
Full working snippet here. Haven't added snippet in answer because:
a) SO doesn't yet support SCSS,
b) i'm lazy.
Also note I made minor mods to your CSS and markup. Another note: duplicate ids are illegal in HTML. You have them? Expect your JavaScript to break. It's as simple as that.
Replace the code in your code. I hope, you can do it. Let me know, If any problem.
$(document).ready(function() {
$(".nav li a").click(function() {
$(".connected-line ul li").removeClass("active");
id = $(this).prop('id');
$("#" + id).addClass("active")
});
});
<div class="connected-line">
<ul>
<li class="active" id="system-settings">1
<p> System </p>
</li>
<li id="hosts">2
<p> Hosts </p>
</li>
<li id="card-range">3
<p> Cards </p>
</li>
<li id="pinpads">4
<p> Devices </p>
</li>
<li id="xmls" >5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
It is best not you have two elements with the same id attribute. This is because native functions such as getElementById will never be able to select the second instance of the element with that id.
That being said to get your demo to work I changed the js to use classes instead of ids on the second set of elements. This can be achieved in many other ways as well:
$(document).ready(function() {
$(".nav li").click(function() {
$('li').removeClass("active");
$(this).removeClass("active");
$(this).addClass("active");
const clickedId = $(this).children()[0].id;
$(`.${clickedId}`).addClass('active');
});
});
and then in the html
<div class="connected-line">
<ul>
<li class="system-settings">1
<p> System </p>
</li>
<li class="hosts">2
<p> Hosts </p>
</li>
<li class="card-range">3
<p> Cards </p>
</li>
<li class="pinpads">4
<p> Devices </p>
</li>
<li class="xmls">5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item ">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Rewrite the html code as follows
<div class="connected-line">
<ul>
<li class="system active">1
<p> System </p>
</li>
<li class="host" id="hosts">2
<p> Hosts </p>
</li>
<li class="card">3
<p> Cards </p>
</li>
<li class="device">4
<p> Devices </p>
</li>
<li class="lane">5
<p> Lanes </p>
</li>
</ul>
</div>
<ul class="nav">
<li class="nav-item system">
<a data-target="#system-settings" data-toggle="pill" class="nav-link" href="#system-settings" id="system-settings">System Settings</a>
</li>
<li class="nav-item host">
<a class="nav-link" href="#hosts" id="hosts" data-parent="#hosts">Hosts</a>
</li>
<li class="nav-item card">
<a class="nav-link" href="#card-range" id="card-range">Cards</a>
</li>
<li class="nav-item printer">
<a class="nav-link" id="pinpads" href="#pinpads">Printer</a>
</li>
<li class="nav-item pinpad">
<a class="nav-link" id="xmls" href="#xmls">Pinpad</a>
</li>
</ul>
Make sure to add same class name to matching li. Then modify the js code as follows,
$(document).ready(function() {
$(".nav li").click(function() {
//Make sure to add class name immediately after "nav-item". For eg."nav-item printer"
var calss=$(this).attr('class').split(' ')[1];
console.log(calss);
$(".nav li").removeClass("active");
$(".connected-line ul li").removeClass("active");
$("li." + calss).addClass("active");
});
});
Related
I have made a one-page website using HTML, CSS/Tailwind, and Vanilla JavaScript. The issue is that when I click on one of the navbar links sometimes it works, and sometimes it gets stuck; where it does not respond until I click multiple times on the link(The number of times is not consistent). Not sure what the issue could be.
HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link">
<a onclick="scrollToSection('#main-container')">Hjem</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#services')">Tjenster</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#pricing')">Priser</a>
</li>
<li class="nav-link">
<a onclick="scrollToSection('#contact')">Kontakt</a>
</li>
</ul>
JavaScript Code:
function scrollToSection(element) {
var element = document.getElementById(element);
element.scrollIntoView({behavior: "smooth", block: "start", inline: "nearest"})
}
I was able to fix this thanks to the comment made by Rana; where it was pointed out that only the text(a tag) is clickable rather than the entire li element.
New HTML markup:
<ul class="hidden sm:flex uppercase items-center space-x-10">
<li class="nav-link" onclick="scrollToSection('#main-container')">
<a>Hjem</a>
</li>
<li class="nav-link" onclick="scrollToSection('#services')">
<a >Tjenster</a>
</li>
<li class="nav-link" onclick="scrollToSection('#pricing')">
<a >Priser</a>
</li>
<li class="nav-link" onclick="scrollToSection('#contact')">
<a >Kontakt</a>
</li>
</ul>
How can I go to href on tag with hide attribute value?
here is my navigation bar
$(function() {
$('#p10').hide();
$('#p11').hide();
$('#p12').hide();
$('#p13').hide();
$('#p14').hide();
$('#p15').hide();
$('#p16').hide();
$('#p17').hide();
$('#p18').hide();
$('#p19').hide();
$('#p20').hide();
$('#p21').hide();
$('#hideshow').click(function() {
$('#p10').toggle();
$('#p11').toggle();
$('#p12').toggle();
$('#p13').toggle();
$('#p14').toggle();
$('#p15').toggle();
$('#p16').toggle();
$('#p17').toggle();
$('#p18').toggle();
$('#p19').toggle();
$('#p20').toggle();
$('#p21').toggle();
});
$('#navbarNav').click(function() {
console.log($(this));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link " href="#section2">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p1">Subway congestion prediction app</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p2">Image classification</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p3">Community site</a>
</li>
...
<li class="nav-item">
<a class="nav-link" href="#p17">Assembly</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p18">Data structure</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p19">Concave</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#p20">Contact</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#section5">Contact</a>
</li>
</ul>
</div>
When loading the page here, p10 to p21 are hidden.
In this situation, if you click from 10 to 21 of the navigation bar, it is hidden and you cannot move to href.
How can I remove the hide attribute when clicking p10 to p21 of the navigation bar (click the #hideshow button at the time of the hide attribute) and move to p10 to p21?
<button type="button" class="btn btn-dark btn-lg " style="font-size:3rem; margin-bottom:100px; background-color:#3e454e" id="hideshow">Want to see more?</button>
#showhide button is between #p9 #p10
The jquery-selector is used in this way:
$('#<id>').hide();
-> the <id> (after the #) must be the id of the element. In your HTML it is the given href.
In your given code the #hideshow button is missing.
You try to select with jQuery IDs (10 - 21) but the HTML doesn't contain these IDs. Furthermore: The click event listener is assigned to the button #hideshow which doesn't exist.
If you define the IDs and add the button #hideshow it works:
$(function() {
$('#p10').hide();
$('#p11').hide();
$('#p12').hide();
$('#p13').hide();
$('#p14').hide();
$('#p15').hide();
$('#p16').hide();
$('#p17').hide();
$('#p18').hide();
$('#p19').hide();
$('#p20').hide();
$('#p21').hide();
$('#hideshow').click(function() {
$('#p10').toggle();
$('#p11').toggle();
$('#p12').toggle();
$('#p13').toggle();
$('#p14').toggle();
$('#p15').toggle();
$('#p16').toggle();
$('#p17').toggle();
$('#p18').toggle();
$('#p19').toggle();
$('#p20').toggle();
$('#p21').toggle();
});
$('#navbarNav').click(function() {
console.log($(this));
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<div class="collapse navbar-collapse" id="navbarNav">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link " href="#section2">Home</a>
</li>
<li id="1p17" class="nav-item">
<a class="nav-link" href="#p1">Subway congestion prediction app</a>
</li>
<li id="p2" class="nav-item">
<a class="nav-link" href="#p2">Image classification</a>
</li>
<li id="p3" class="nav-item">
<a class="nav-link" href="#p3">Community site</a>
</li>
...
<button type="button" id="hideshow">Want to see more?</button>
...
<li id="p17" class="nav-item">
<a class="nav-link" href="#p17">Assembly</a>
</li>
<li id="p18" class="nav-item">
<a class="nav-link" href="#p18">Data structure</a>
</li>
<li id="p19" class="nav-item">
<a class="nav-link" href="#p19">Concave</a>
</li>
<li id="p20" class="nav-item">
<a class="nav-link" href="#p20">Contract</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#section5">Contact</a>
</li>
</ul>
</div>
This is my Navbar code:
<div class="navbar-collapse offcanvas-collapse justify-content-md-center" id="navbarsExampleDefault">
<ul class="navbar-nav">
<li class="nav-item active">
<a class="nav-link" href="#Url.Action(" DashBoard ","Admin ")">Dashboard</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" SectionsList ","Admin ")">Sections</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" DifficultyList ","Admin ")">Difficulty</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" QuestionsList ","Admin ")">Questions</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" AssessmentList ","Admin ")">Assessments</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#Url.Action(" UsersList ","Admin ")">User's</a>
</li>
<li class="nav-item dropdown">
<a class="nav-link dropdown-toggle" href="#" id="navbarDropdown" role="button" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">Students</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="nav-link" href="#Url.Action(" StudentResult ","Admin ")">Student Results</a>
</div>
</li>
</ul>
</div>
This is my click function:
$("#navbarsExampleDefault li a").click(function() {
$(this).parent().addClass('active').siblings().removeClass('active');
});
I need to highlight the selected navbar with active class. I have tried this one but not working
public ActionResult SectionsList()
{
return view();
}
This is one of my action method
Place the below edited piece of code which is tested
$(document).ready(function(){
$(".navbar-nav .nav-link").click(function (e) {
e.preventDefault();
$('.nav-item').removeClass('active');
$(this).closest('.nav-item').addClass('active');
});
});
var change = function () {
var url = window.location.pathname;
$('ul.navbar-nav a[href="' + url + '"]').parent().addClass('active');
};
change();
Load this function in the js file which is common to every page and remove class active from li.
Works even when the page reloads.
I hope it works for you! Thanks!
Please use below code
$("#navbarsExampleDefault li a").click(function () {
$('.nav-item').removeClass('active');
$(this).parent().addClass('active');
});
Hope it works for you Thanks!
I have a navigation which can have up to two sub menus. Means, I have to open the li above (add class "open" to class "arrow") two times if the current page is a href in a sub sub navigation.
However, I am struggling on how to do this, how to solve this problem. My idea was to solve it via jQuery. Is there a better solution?
This is my navigation:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
<span class="selected"></span>
</a>
</li>
<li class="nav-item">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
<span class="selected"></span>
</li>
<li class="nav-item">
Kundenverwaltung
<span class="selected"></span>
</li>
</ul>
</li>
</ul>
</li>
</ul>
Example:
The current page is this one: my-domain.com/kundenverwaltung. That means, I have to add the class "active open" to both li elements of the ul sub menus as well as the class "open" to the class "arrow" of the li elements.
This is how it should be:
<ul class="page-sidebar-menu page-header-fixed page-sidebar-menu-light">
<li class="nav-item start">
<a href="my-domain.com/dashboard" class="nav-link nav-toggle">
<i class="icon-home"></i>
<span class="title">Dashboard</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<i class="icon-people"></i>
<span class="title">Kontakte</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item">
<a href="my-domain.com/kontaktverwaltung" class="nav-link ">
<span class="title">Kontaktverwaltung</span>
</a>
</li>
<li class="nav-item **active open**">
<a href="javascript:void(0)" class="nav-link nav-toggle">
<span class="title">Kunden</span>
<span class="arrow **open**"></span>
</a>
<ul class="sub-menu">
<li class="nav-item ">
Kundendetails
</li>
<li class="nav-item">
Kundenverwaltung
</li>
</ul>
</li>
</ul>
</li>
</ul>
I have marked the changes on the classes with ** before and after the class name. This is my jQuery so far:
<script>
$("a.nav-link").each(function(index){
if($(this).attr("href") == window.location.href) {
$(this).parent().addClass("active open");
if ($(this).parent().parent().is("ul")) {
$(this).parent().parent().parent().addClass("active open");
var li = $(this).parent().parent().parent();
$(li[0].nodeName + " .arrow").addClass("open");
}
}
});
</script>
However, I don't think this is the best solution.. is there any better way? Kind regards
If you change the structure of HTML, your code will not be work, so - don't use parent(), try to use closest() https://api.jquery.com/closest, by reason that the closest() is a more reliable method
Cache data. U can use
http://api.jquery.com/attribute-equals-selector:
var $a = jQuery('a[href*="' + window.location.href + '"]');
$a.addClass("active open");
For adding a class to active page you should try added this by backend side, different kind of templating - can do it. But your approach also can be use
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.