Local Storage is not working as expected - javascript

I am trying to use themes for one of my websites wherein the user can select the theme color dynamically. Once the theme color is stored, it has to retain the color value and has to get updated in other pages too. But, the color does not get updated in my other pages
<body>
<div class="btn-group">
<button type="button" class="btn btn-default dropdown-toggle" data-toggle="dropdown" aria-expanded="false">
Theme <span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu">
<li>red</li>
<li>green</li>
<li>blue</li>
</ul>
</div>
next page
</body>
AND MY JQUERY CODE IS:
$(document).ready(function(){
$(document).on('click', '.dropdown-menu li a', function () {
var color=($(this).text());
if(color == "red"){
$('body').css("background-color","red");
}
else
if(color == "green"){
$('body').css("background-color","green");
}
else
if(color == "blue"){
$('body').css("background-color","blue");
}
localStorage.setItem("value", color);
});
var name = localStorage.getItem("value");
$('body').css("background-color","name");
});

Please remove apostrophe when using the variable name:
var name = localStorage.getItem("value");
$('body').css("background-color",name);

You have missed
var name = localStorage.getItem("value");
$('body').css("background-color", name);
Working Demo

Related

How to add class 'reverse' to dropdown-menu dynamically on dropdown click?

I am looking for a solution to add class reverse from ts file to show dropdown upward when it's near or in the bottom position.
On dropdown click, it gives me null for dropdown-menu in the console.
For now I am adding it through html, in addition it require a boolean variable to check for it's position. So, I am using many dropdowns in my project and I do not want to add such redundent approach every where.
Further, after its solution, I have to make a directive to use globally in my project.
Below is my code:
app.component.ts
upwardFlag = false
dropdownStatus() {
this.showDropDown = !this.showDropDown;
var scrollTop = document.documentElement.scrollTop;
var dropdown = document.querySelector('.dropdown-toggle')
var bodyRect = document.body.getBoundingClientRect().top,
offset = dropdown.getBoundingClientRect().top,
topOffset = offset - bodyRect;
var relativeOffset = topOffset - scrollTop;
var windowHeight = window.innerHeight;
var dropdownMenu = document.querySelector('.dropdown-menu')
if (relativeOffset > (windowHeight/2)) {
console.log('show upward', dropdownMenu);
this.upwardFlag = true
} else {
this.upwardFlag = false
console.log('show downward', dropdownMenu);
}
}
app.component.html
<div id="container">
<div class="dropdown">
<button class="btn btn-default dropdown-toggle" type="button" id="dropdownMenu1" data-toggle="dropdown" #dp (click)="dropdownStatus()">
Cool dropdown
<span class="caret"></span>
</button>
<ul class="dropdown-menu open" role="menu" aria-labelledby="dropdownMenu1" *ngIf="showDropDown" [ngClass]="{'showDropDown': 'open'}" [class.reverse]="upwardFlag===true">
<li role="presentation">Action</li>
<li role="presentation">Another action</li>
<li role="presentation">Something else here</li>
<li role="presentation" class="divider"></li>
<li role="presentation">Separated link</li>
</ul>
</div>
</div>
You can check it in this stackblitz
Angular has not yet created the HTML element when you query it, your code is faster than Angular template checking ;)
Two solutions
Make a reverse variable and do [class.reverse]="reverse" on your component.
Use [hidden]="!showDropdown" rather than *ngIf, then it will be available in the DOM.
By the way, you could use a #ViewChild('.myClass') dropdown : ElementRef; to access the element in a more "Angular Way".

Pass unordered List selected item to ASP.NET Web Forms using jQuery

I asked a question earlier but didn't phrase it correctly.
I am working with jQuery and Bootstrap for pretty much the first time and need some help.
I have an .aspx webpage that has this code:
<form method="POST" action="Search.aspx">
<div>
<input type="text" class="form-control" name="srchterm" id="srchterm" style="width: 300px" />
<button id="Submit" class="btn btn-primary" type="submit">
GO!</button>
</div>
<br />
<div>
<div class="btn-group">
<a id="reportType" class="btn btn-default dropdown-toggle btn-select" data-toggle="dropdown" href="#"
name="rptType">Select report type<span class="caret"></span></a>
<ul class="dropdown-menu">
<li id="1">All</li>
<li id="2">Some</li>
<li id="3">None</li>
</ul>
</div>
<div class="btn-group">
<a id="reportStatus" class="btn btn-default dropdown-toggle btn-select" data-toggle="dropdown" href="#">
Report Status<span class="caret"></span></a>
<ul class="dropdown-menu">
<li id="1">Active</li>
<li id="2">Archived</li>
<li id="3">All</li>
</ul>
</div>
</div>
</div>
</form>
What I would like to know is how I can pass the value of the selected unordered list item to the code behind using JQuery or AJAX. Neither method I know much (or to be totally honest) anything about.
When I hit the submit button it takes the text box value and passes that back to Request.Form("srchTerm") but i cant seem to get anything else to pass.
I have seen this link here at fiddle but cant seem to get it to work for me.
I am wondering if its because how I have declared my listbox, but do need help in order to get this to work.
If I am missing a tag, please let me know. But I would very much appreciate the help with the JavaScript to get this wired up to pass the data so I can call the information from my database.
====================================
edit 1
I've tried various methods, none of which i have kept, but this is that i have right now and cant get anything to pass a value across.
$(".dropdown-menu li a").click(function () {
var selText = $(this).text();
$(this).parents('.btn-group').find('.dropdown-toggle').html(selText + ' <span class="caret"></span>');
});
$('.reportType li').click(function () {
value1 = $(this).attr('value');
});
$('.reportStatus li').click(function () {
value2 = $(this).attr('value');
});
$('#Submit').click(function () {
alert('value1 = ' + value1 + ' | value2 = ' + value2);
});
If you must have dropdown list and you want to maintain this type of functionality, then i'd simply use hidden input fields something like this:
<div class="btn-group">
<input type="hidden" id="reportStatus" name="reportStatus" />
<a class="btn btn-default dropdown-toggle btn-select"
data-toggle="dropdown" href="#">
Report Status
<span class="caret"></span>
</a>
<ul class="dropdown-menu">
<li data-val="1">Active</li>
<li data-val="2">Archived</li>
<li data-val="3">All</li>
</ul>
</div>
JS will be something like:
//$(function () {
// $("#reportStatus").parents("div").find("li").click(function () {
// value = $(this).attr("data-val");
// $("#reportStatus").val(value);
// })
//});
//or something more general:
$(function () {
$(".btn-group").each(function (index, item) {
myInput = $(item).children("input");
$(item).find("li").click(function () {
value = $(this).attr("data-val");
myInput.val(value);
});
});
});
fiddle here

How to get current value of a bootstrap dropdown

What I want to do is:
Select drop-down-list drp0 first and then select drp1.
When you select drp1, if drp0 has no value selected, alert("Please select Leave Type Dropdown first").
Then set drp1 to default value and set focus on drp0.
These are my two dropdowns:
<div class="col-sm-6">
<label>Select Leave Type</label>
<div class="dropdown">
<i class="dropdown-arrow dropdown-arrow-inverse"></i>
<button class="btn btn0 btn-default dropdown-toggle" type="button" id="menu0" data-toggle="dropdown">
--Select--
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-inverse0" role="menu" aria-labelledby="menu0" id="drp0">
<li role="presentation"><a data-myAttribute0="casual" class="list0" href="#">Casual Leave</a></li>
<li role="presentation"><a data-myAttribute0="annual" class="list0" href="#">Annual Leave</a></li>
<li role="presentation"><a data-myAttribute0="medical" class="list0" href="#">Medical Leave</a></li>
</ul>
</div>
</div>
<div class="col-sm-6">
<label>Select Employee Name</label>
<div class="dropdown">
<i class="dropdown-arrow dropdown-arrow-inverse"></i>
<button class="btn btn1 btn-default dropdown-toggle hide-button" type="button" id="menu1" data-toggle="dropdown">
--Select--
<span class="caret"></span>
</button>
<ul class="dropdown-menu dropdown-inverse1" role="menu" aria-labelledby="menu1" id="drp1">
<c:forEach items="${personList}" var="person">
<li role="presentation"><a data-myAttribute1="${person.getId()}" class="list1" href="#">${person.getName()}</a></li>
</c:forEach>
</ul>
</div>
</div>
The second dropdown is populating pretty well. No problem in that.
Actually I found a way to check is dropdown1 is selected or not, While selecting dropdown2? But the problem is when dropdown1 has selected value I get this undefined error alert?
Looks like its not taking the current value of dropdown1.
Here is my code.
<script>
$(document).ready(function () {
$('.dropdown-inverse1 li > a').click(function () {
var $person_id = $(this).attr("data-myAttribute1");
var $leave_type = $(this).attr("data-myAttribute0");
if (typeof $leave_type === 'undefined') {
alert("Empty");
} else {
alert("Not Empty");
}
});
});
</script>
My problem is I get "Empty" alert whether dropdown1 has a value or not. How to fix this? Thank you.
Here is the DEMO and most simplified and better version for your solution:
$('.dropdown-inverse1 li > a').click(function () {
$(".btn1").html($(this).text() + ' <span class="caret"></span>');
});
$('.dropdown-inverse2 li > a').click(function (e) {
var s = $(".btn1").text().trim();
if(s=="Button1"){
alert("Empty");
$(".btn2").html('Button2 <span class="caret"></span>');
setTimeout(function(){
$(".btn1").trigger('click');
},100); //set a timeout of 100ms to trigger the click so as to open the required dropdown
return;
}
$(".btn2").html($(this).text() + ' <span class="caret"></span>');
});
You had some problems in your solution like once you select dropdown the caret i.e. arrow used to get replaced since you were replacing text of .btn1. Now it will replace with caret and content as html. Hope it helps.
$(document).ready(function () {
var $leave_type = "";
$('.dropdown-inverse0 li > a').click(function () {
$leave_type = $(this).attr("data-myAttribute0");
if (typeof $leave_type === 'undefined') {
alert("Empty");
} else {
alert("Not Empty");
}
});
$('.dropdown-inverse1 li > a').click(function () {
var $person_id = $(this).attr("data-myAttribute1");
if (typeof $leave_type === 'undefined') {
if (typeof $person_id === 'undefined') {
alert($leave_type);
} else {
alert("Not Empty");
}
}else{
$('#menu0').trigger('click');
alert("Please select Leave Type");
}
});
});
Heeeyyyy try thiss......
Hi Lots of kind people tried to help me. Thank you for that. As they say best thing is to use bootstrap select but I wanted to use ul li bootstrap dropdown. So if any one interested in that. I found this.
$('document').ready(function () {
$('.dropdown-inverse1 li > a').click(function () {
$(".btn1").text($(this).text());
});
$('.dropdown-inverse2 li > a').click(function () {
$(".btn2").text($(this).text());
var s = $(".btn1").text();
if(!(s=='HTML' || s=='CSS' || s=='JavaScript') ){
alert("Empty");
}
});
});
<head>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/css/bootstrap.min.css">
</head>
<body>
<div class="container">
<div class="dropdown">
<button class="btn btn1 btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Button1
<span class="caret"></span></button>
<ul class="dropdown-menu dropdown-inverse1">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</div>
<br/>
<div class="dropdown">
<button class="btn btn2 btn-primary dropdown-toggle" type="button" data-toggle="dropdown">Button2
<span class="caret"></span></button>
<ul class="dropdown-menu dropdown-inverse2">
<li>A</li>
<li>B</li>
<li>C</li>
</ul>
</div>
</div>
</body>

Bootstrap Dropdown + Angular data-ng-repeat

I'm having a little issue while trying to show some data (Villains/Villanos) in a drop down with a ng-repeat. I've been looking around and trying but I can't make it work. I have the following HTML:
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.7/angular.min.js" </script>
<script src="http://ajax.googleapis.com/ajax/libs/angularjs/1.3.0-beta.7/angular-animate.js"></script>
<script>
// This function lets the dropdown button save the name of the Villain that it's selected.
$(function(){
$(".dropdown-menu li a").click(function(){
$(".dropdown-toggle:first-child").text($(this).text());
$(".dropdown-toggle:first-child").val($(this).text());
});
});
</script>
<div class="dropdown">
<button class="btn btn-default dropdown-toggle dropdown-suspects-sides" type="button" id="dropdownMenu1" data-toggle="dropdown">
Suspects
<span class="caret"></span>
</button>
<ul class="dropdown-menu" role="menu" aria-labelledby="dropdownMenu1">
<li class="suspect" role="presentation" data-ng-repeat = "villain in villains">
<a role="menuitem" tabindex="-1" href="#">
<span class="glyphicon glyphicon-user"></span> {{villain}}
</a>
</li>
</ul>
</div>
/* Controllers */
...
$scope.getVillains = function() {
$http.get("/getVillains")
.success(function(data) {
$scope.villains = data
}
)
};
...
As you can see, I'm trying to make a dropdown to show all the Villains I have. The items appear correctly if they're showed in a normal list so the items can be "used", but they're not appearing if I try to show them this way. I'm pretty sure I'm doing something wrong here but I can't guess what is it. Thanks in advance!

Bootstrap navbar Active State not working

I have bootstrap v3.
I use the class="active" on mynavbar and it does not switch when I press menu items. I know how to do this with jQuery and build a click function but I'm thinking this functionality should be included in bootstrap? So maybe it is a JavaScript issue?
Here is my header with my js/css/bootstrap files I have included:
<!-- Bootstrap CSS -->
<link rel="stylesheet" href= "/bootstrap/css/bootstrap.css" />
<link rel="stylesheet" href="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css" />
<link rel="stylesheet" href= "/stylesheets/styles.css" />
<!--jQuery -->
<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.1/jquery.min.js">
<script src="//ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/jquery-ui.min.js"></script>
<!-- Bootstrap JS -->
<script src="/bootstrap/js/bootstrap.min.js"></script>
<script src="/bootstrap/js/bootstrap-collapse.js"></script>
<script src="/bootstrap/js/bootstrap-transition.js"></script>
Here is my navbar code:
<nav class="navbar navbar-default navbar-fixed-top" role="navigation">
<div class="container-fluid">
<div class="navbar-header">
<button type="button" class="navbar-toggle" data-toggle="collapse" data-target=".navbarCollapse">
<span class="icon-bar"></span>
<span class="icon-bar"></span>
<span class="icon-bar"></span>
</button>
<a class="navbar-brand" href="/index.php">MyBrand</a>
</div>
<div class="collapse navbar-collapse navbarCollapse">
<ul class="nav navbar-nav navbar-right">
<li class="active">
Home
</li>
<li>
Links
</li>
<li>
About
</li>
<li>
Contact
</li>
<li>
Login
</li>
</ul>
</div>
</div>
</nav>
Am I setting this up right?
(On an unrelated note, but possible related? When the menu goes mobile, I click the menu button and it collapses. Pushing it again does not un-collapse it though. So this issue,. with the other, both signify wrong JavaScript setup perhaps?)
You have included the minified Bootstrap js file and collapse/transition plugins while the docs state that:
Both bootstrap.js and bootstrap.min.js contain all plugins in a single file.
Include only one.
and
For simple transition effects, include transition.js once alongside
the other JS files. If you're using the compiled (or minified)
bootstrap.js, there is no need to include this—it's already there.
So that could well be your problem for the minimize problem.
For the active class, you have to manage it yourself, but it's just a line or two.
Bootstrap 3:
$(".nav a").on("click", function(){
$(".nav").find(".active").removeClass("active");
$(this).parent().addClass("active");
});
Bootply: http://www.bootply.com/IsRfOyf0f9
Bootstrap 4:
$(".nav .nav-link").on("click", function(){
$(".nav").find(".active").removeClass("active");
$(this).addClass("active");
});
Here was my solution for switching active pages
$(document).ready(function() {
$('li.active').removeClass('active').removeAttr('aria-current');
$('a[href="' + location.pathname + '"]').closest('li').addClass('active').attr('aria-current', 'page');
});
This worked perfectly for me, because "window.location.pathname" also contains data before the real page name, e.g. directory/page.php. So the actual navbar link will only be set to active if the url contains this link.
$(document).ready(function() {
$.each($('#navbar').find('li'), function() {
$(this).toggleClass('active',
window.location.pathname.indexOf($(this).find('a').attr('href')) > -1);
});
});
With version 3.3.4 of bootstrap, on long html pages you can refer to sections of the pg. by class or id to manage the active navbar link with spy-scroll with the body element:
<body data-spy="scroll" data-target="spy-scroll-id">
The data-target will be a div with the id="spy-scroll-id"
<div id="spy-scroll-id" class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li class="active">Home</li>
<li>About</li>
<li>SlideShow</li>
</ul>
</div>
This should activate links by clicking without any javascript functions needed and will also automatically activate each link as you scroll through the corresponding linked sections of the page which a js onclick() will not.
All you need to do is simply add data-toggle="tab" to your link inside bootstrap navbar like this:
<ul class="nav navbar-nav">
<li class="active"><a data-toggle="tab" href="#">Home</a></li>
<li><a data-toggle="tab" href="#">Test</a></li>
<li><a data-toggle="tab" href="#">Test2</a></li>
</ul>
If you don't use anchor links, you can use something like this:
$(document).ready(function () {
$.each($('#navbar').find('li'), function() {
$(this).toggleClass('active',
'/' + $(this).find('a').attr('href') == window.location.pathname);
});
});
With Bootstrap 4 you can use this:
$(document).ready(function() {
$(document).on('click', '.nav-item a', function (e) {
$(this).parent().addClass('active').siblings().removeClass('active');
});
});
This elegant solution did the trick for me. Any new ideas/suggestions are welcome.
$( document ).on( 'click', '.nav-list li', function ( e ) {
$( this ).addClass( 'active' ).siblings().removeClass( 'active' );
} );
You can use jQuery's "siblings()" method to keep only the accessed item active and its siblings inactive.
I use this. It's short, elegand and easy to understand.
$(document).ready(function() {
$('a[href$="' + location.pathname + '"]').addClass('active');
});
I've been struggling with this today, data-togle only worked if I'm on a single page application.
I'm not using ajax to load the content i'm actually making post request for other pages so the first js script was useless too. I solve it with this lines:
var active = window.location.pathname;
$(".nav a[href|='" + active + "']").parent().addClass("active");
Bootstrap 4: navbar Active State working, just use .navbar-nav .nav-link classes
$(function () {
// this will get the full URL at the address bar
var url = window.location.href;
// passes on every "a" tag
$(".navbar-nav .nav-link").each(function () {
// checks if its the same on the address bar
if (url == (this.href)) {
$(this).closest("li").addClass("active");
//for making parent of submenu active
$(this).closest("li").parent().parent().addClass("active");
}
});
});
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.2.1/jquery.min.js"></script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/css/bootstrap.min.css" integrity="sha384-Gn5384xqQ1aoWXA+058RXPxPg6fy4IWvTNh0E263XmFcJlSAwiGgFAW/dAiS6JXm" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js" integrity="sha384-ApNbgh9B+Y1QKtv3Rn7W3mgPxhU9K/ScQsAP7hUibX39j7fakFPskvXusvfa0b4Q" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0/js/bootstrap.min.js" integrity="sha384-JZR6Spejh4U02d8jOt6vLEHfe/JQGiRRSQQxSfFWpi1MquVdAyjUar5+76PVCmYl" crossorigin="anonymous"></script>
<nav class="navbar navbar-expand-lg navbar-light bg-light">
<a class="navbar-brand" href="#">Navbar</a>
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbarSupportedContent" aria-controls="navbarSupportedContent" aria-expanded="false" aria-label="Toggle navigation">
<span class="navbar-toggler-icon"></span>
</button>
<div class="collapse navbar-collapse" id="navbarSupportedContent">
<ul class="navbar-nav mr-auto">
<li class="nav-item">
<a class="nav-link" href="#">Home</a>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Link</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">
Dropdown
</a>
<div class="dropdown-menu" aria-labelledby="navbarDropdown">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</li>
<li class="nav-item">
<a class="nav-link" href="#">Other</a>
</li>
</ul>
<form class="form-inline my-2 my-lg-0">
<input class="form-control mr-sm-2" type="search" placeholder="Search" aria-label="Search">
<button class="btn btn-outline-success my-2 my-sm-0" type="submit">Search</button>
</form>
</div>
</nav>
I'm hope this will help to solve this problem.
var navlnks = document.querySelectorAll(".nav a");
Array.prototype.map.call(navlnks, function(item) {
item.addEventListener("click", function(e) {
var navlnks = document.querySelectorAll(".nav a");
Array.prototype.map.call(navlnks, function(item) {
if (item.parentNode.className == "active" || item.parentNode.className == "active open" ) {
item.parentNode.className = "";
}
});
e.currentTarget.parentNode.className = "active";
});
});
I had some pain with this, using a dynamically generated list items - WordPress Stack.
Added this and it worked:
$(document).ready(function () {
$(".current-menu-item").addClass("active");
});
Will do it on the fly.
I've been looking for a solution that i can use on bootstrap 4 navbars and other groups of links.
For one reason or another most solutions didn't work especially the ones that try to add 'active' to links onclick because of course once the link is clicked if it takes you to another page then the 'active' you added won't be there because the DOM has changed.
Many of the other solutions didn't work either because they often did not match the link or they matched more than one.
This elegant solution is fine for links that are different ie: about.php, index.php, etc...
$(function() {
$('nav a[href^="' + location.pathname.split("/")[2] + '"]').addClass('active');
});
However when it came to the same links with different query strings such as index.php?tag=a, index.php?tag=b, index.php?tag=c it would set all of them to active whichever was clicked as it's matching the pathname not the query as well.
So i tried this code which matched the pathname and the query string and it worked on all the links with query strings but when a link like index.php was clicked it would set the similar query string links active as well. This is because my function is returning an empty string if there is no query string in the link, again just matching the pathname.
$(function() {
$('nav a[href^="' + location.pathname.split("/")[2] + returnQueryString(location.href.split("?")[1]) + '"]').addClass('active');
});
/** returns a query string if there, else an empty string */
function returnQueryString (element) {
if (element === undefined)
return "";
else
return '?' + element;
}
So in the end i abandoned this route and kept it simple and wrote this.
$('.navbar a').each(function(index, element) {
//console.log(index+'-'+element.href);
//console.log(location.href);
/** look at each href in the navbar
* if it matches the location.href then set active*/
if (element.href === location.href){
//console.log("---------MATCH ON "+index+" --------");
$(element).addClass('active');
}
});
It works on all links with or without query strings because element.href and location.href both return the full path. For other menus etc you can simply change the parent class selector (navbar) for another ie:
$('.footer a').each(function(index, element)...
One last thing which also seems important and that is the js & css library's you are using however that's another post perhaps.
I hope this helps and contributes.
Vanilla JS solution for Bootstrap 5
document.addEventListener("DOMContentLoaded", function () {
// make all currently active items inactive
// (you can delete this block if you know that there are no active items when loading the page)
document.querySelectorAll("a.nav-link.active").forEach(li => {
li.classList.remove("active");
li.attributes.removeNamedItem("aria-current");
});
// find the link to the current page and make it active
document.querySelectorAll(`a[href="${location.pathname}"].nav-link`).forEach(a => {
a.classList.add("active");
a.setAttribute("aria-current", "page");
});
});
Class "active" is not managed out of the box with bootstrap. In your case since you're using PHP you can see:
How add class='active' to html menu with php
to assist you with a method of mostly automating it.
For bootstrap mobile menu un-collapse after clicking a item you can use this
$("ul.nav.navbar-nav li a").click(function() {
$(".navbar-collapse").removeClass("in");
});
I m using bootstrap bare theme, here is the sample navbar code. Note the class name of the element -> .nav - as this is referred in java script.
/ Collect the nav links, forms, and other content for toggling
#bs-example-navbar-collapse-1.collapse.navbar-collapse
%ul.nav.navbar-nav
%li
%a{:href => "/demo/one"} Page One
%li
%a{:href => "/demo/two"} Page Two
%li
%a{:href => "/demo/three"} Page Three
in the view page (or partial) add this :javascript,
this needs to be executed every time page loads.
haml view snippet ->
- content_for :javascript do
:javascript
$(function () {
$.each($('.nav').find('li'), function() {
$(this).toggleClass('active',
$(this).find('a').attr('href') == window.location.pathname);
});
});
In the javascript debugger make sure you have value of 'href' attribute matches with window.location.pathname. This is slightly different than the solution by #Zitrax which helped me fixing my issue.
For AngularJS, you can use ng-class with a function like this:
HTML ->
<nav class="navbar navbar-default" ng-controller="NavCtrl as vm">
<div class="container">
<div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav" >
<li ng-class="vm.Helper.UpdateTabActive('Home')"><a href="#" ng-click>Home</a></li>
<li ng-class="vm.Helper.UpdateTabActive('About')">About</li>
<li ng-class="vm.Helper.UpdateTabActive('Contact')">Contact</li>
</ul>
</div>
</nav>
And controller
app.controller('NavCtrl', ['$scope', function($scope) {
var vm = this;
vm.Helper = {
UpdateTabActive: function(sTab){
return window.location.hash && window.location.hash.toLowerCase() == ("#/" + sTab).toLowerCase() ? 'active' : '';
}
}
}]);
If you are using $location, then there won't be hash. So you can extract the required string from URL using $location
Following will not work in all cases -->
Using a scope variable like following will work only when clicked, but if the transition is done using $state.transitionTo or window.location or manually updating the URL, the Tab value will not be updated
<ul class="nav navbar-nav" ng-init="Tab='Home'">
<li ng-class="Tab == 'Home' ? 'active' : ''">Home</li>
<li ng-class="Tab == 'About' ? 'active' : ''">About</li>
</ul>
Add this JavaScript on your main js file.
$(".navbar a").on("click", function(){
$(".navbar").find(".active").removeClass("active");
$(this).parent().addClass("active");
});
I had to go a step forward because my file names were not the same as my nav bar titles. i.e. my first nav bar link was HOME but the file name is index..
So just grab the pathname and match it.
Obviously this is a crude example and could be more efficient but it is highly custom need.
var loc_path = location.pathname;
$('li.active').removeClass('active');
if(loc_path.includes('index')){
$('li :eq(0)').addClass('active');
}else if(loc_path.includes('blog')){
$('li :eq(2)').addClass('active');
}else if(loc_path.includes('news')){
$('li :eq(3)').addClass('active');
}else if(loc_path.includes('house')){
$('li :eq(4)').addClass('active');
}
Bootstrap 4 solution that worked for me:
$(document).ready(function() {
//You can name this function anything you like
function activePage(){
//When user lands on your website location.pathname is equal to "/" and in
//that case it will add "active" class to all links
//Therefore we are going to remove first character "/" from the pathname
var currentPage = location.pathname;
var slicedCurrentPage = currentPage.slice(1);
//This will add active class to link for current page
$('.nav-link').removeClass('active');
$('a[href*="' + location.pathname + '"]').closest('li').addClass('active');
//This will add active class to link for index page when user lands on your website
if (location.pathname == "/") {
$('a[href*="index"]').closest('li').addClass('active');
}
}
//Invoke function
activePage();
});
This will only work if href contains location.pathname!
If you are testing your site on your own pc (using wamp, xampp, lamp, etc...) and your site is located in some subfolder then your path is actually "/somefolder/something.php", so don't get confused.
I would suggest if you are unsure to use following code so you can make sure what is the correct location.pathname:
$(document).ready(function() {
alert(location.pathname);
});
the next answer is for those who have a multi-level menu:
var url = window.location.href;
var els = document.querySelectorAll(".dropdown-menu a");
for (var i = 0, l = els.length; i < l; i++) {
var el = els[i];
if (el.href === url) {
el.classList.add("active");
var parent = el.closest(".main-nav"); // add this class for the top level "li" to get easy the parent
parent.classList.add("active");
}
}
As someone who doesn't know javascript, here's a PHP method that works for me and is easy to understand. My whole navbar is in a PHP function that is in a file of common components I include from my pages. So for example in my 'index.php' page I have...
`
<?php
$calling_file = basename(__FILE__);
include 'my_common_includes.php'; // Going to use my navbar function "my_navbar"
my_navbar($calling_file); // Call the navbar function
?>
Then in the 'my_common_includes.php' I have...
<?php
function my_navbar($calling_file)
{
// All your usual nabvbar code here up to the menu items
if ($calling_file=="index.php") { echo '<li class="nav-item active">'; } else { echo '<li class="nav-item">'; }
echo '<a class="nav-link" href="index.php">Home</a>
</li>';
if ($calling_file=="about.php") { echo '<li class="nav-item active">'; } else { echo '<li class="nav-item">'; }
echo '<a class="nav-link" href="about.php">About</a>
</li>';
if ($calling_file=="galleries.php") { echo '<li class="nav-item active">'; } else { echo '<li class="nav-item">'; }
echo '<a class="nav-link" href="galleries.php">Galleries</a>
</li>';
// etc for the rest of the menu items and closing out the navbar
}
?>
Bootstrap 4 requires you to target the li item for active classes. In order to do that you have to find the parent of the a. The 'hitbox' of the a is as big as the li but due to bubbeling of event in JS it will give you back the a event. So you have to manually add it to its parent.
//set active navigation after click
$(".nav-link").on("click", (event) => {
$(".navbar-nav").find(".active").removeClass('active');
$(event.target).parent().addClass('active');
});
I tried about first 5 solutions and different variations of them, but they didn't work for me.
Finally I got it working with these two functions.
$(document).on('click', '.nav-link', function () {
$(".nav-item").find(".active").removeClass("active");
})
$(document).ready(function() {
$('a[href="' + location.pathname + '"]').closest('.nav-item').addClass('active');
});
when use header.php for every page for the navbar code, the jquery does not work, the active is applied and then removed, a simple solution, is as follows
on every page set variable
<?php $pageName = "index"; ?> on Index page and similarly
<?php $pageName = "contact"; ?> on Contact us page
then call the header.php (ie the nav code is in header.php)
<?php include('header.php'); >
in the header.php ensure that each nav-link is as follows
<a class="nav-link <?php if ($page_name == 'index') {echo "active";} ?> href="index.php">Home</a>
<a class="nav-link <?php if ($page_name == 'contact') {echo "active";} ?> href="contact.php">Contact Us</a>
hope this helps cause i have spent days to get the jquery to work but failed,
if someone would kindly explain what exactly is the issue when the header.php is included and then page loads... why the jquery fails to add the active class to the nav-link..??
For Bootstrap 5 I use the folowing to keep the dropdown items active after navigating to a url.
<li class="nav-item dropdown text-center ">
<a class="nav-link dropdown-toggle dropdown-toggle-split" href="#" id="navbarDropdown1" role="button" data-bs-toggle="dropdown" aria-expanded="false">
Clienten
</a>
<ul class="dropdown-menu" aria-labelledby="navbarDropdown1">
<li><h6 class="dropdown-header">Iedereen</h6></li>
<li><a class="dropdown-item " aria-current="page" href="/submap/IndexClients.php">Overzicht</a></li>
<li><hr class="dropdown-divider"></li>
<li><h6 class="dropdown-header">Persoonlijk</h6></li>
<li><a class="dropdown-item" aria-current="page" href="/submap/IndexClientsP.php">Overzicht (<?= $usernamesession ?>)</a></li>
</ul>
</li>
<script>
$(document).ready(function() {
$('a.active').removeClass('active');
var active = window.location.pathname;
$('a[href="' + active + '"]').closest('.dropdown-item').addClass('active');
});
</script>
Bootstrap 5.1
This is already implemented in bootstrap, and explained neatly in the documentation under the scrollspy section. Link to documentation
Steps to fix active state toggle:
set position:relative on your body element
add id="navbar" to your navbar section.
include this in your js file, or inside in the html:
var scrollSpy = new bootstrap.ScrollSpy(document.body, {
target: '#navbar'
})
With bootstrap 4 I missed from the documentation that I needed to also add
$('#myList a').on('click', function (e) {
e.preventDefault()
$(this).tab('show')
})
https://getbootstrap.com/docs/4.0/components/list-group/

Categories