Bootstrap navbar Active State not working - javascript

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/

Related

scrolling id# on the same page does not work correctly when jquery page fading on load is included

I'm having problems with the id# linking on the same page when I include a jquery page fade out and fade in. When I just had the plain html it worked fine.
To Clarify: I have a section on the same and have a link in the nav area at the top that scrolls down to the lower half of the page. When the jquery code is included either as a separate js file or part of the html page that link scrolls down ( which I want to do) but it also fades out which I don't want it to do.
Hears the jquery fade code:
jQuery('body').css('display','none');
jQuery(document).ready(function() {
jQuery('body').fadeIn();
jQuery('a').on('click',function(event){
var thetarget = this.getAttribute('target')
if (thetarget != "_blank"){
var thehref = this.getAttribute('href')
event.preventDefault();
jQuery('body').fadeOut(function(){
window.location = thehref
});
}
});
});
setTimeout(function(){
jQuery('fade').fadeIn();
},1000)
Html code thats not working
<li class="nav-item">
<a class="nav-link js-scroll-trigger"
href="#portfolio">Portfolio</a>
</li>
<li class="nav-item">
<a class="nav-link js-scroll-trigger" href="about.html">About</a>
</li>
Am I targeting the wrong element. I also tried to make change to no avail.
Need help please!
Tip: Do not bind the event listener (onclick) to all <a></a> tags. Just bind it to a single one using it's specific ID or class name!
So I've edited this line:
jQuery('a').on('click', function(event)
to
jQuery('#about').on('click', function(event)
and added the ID="about" tag to your link.
jQuery('body').css('display', 'none');
jQuery(document).ready(function() {
jQuery('body').fadeIn();
jQuery('#about').on('click', function(event) {
var thetarget = this.getAttribute('target')
if (thetarget != "_blank") {
var thehref = this.getAttribute('href')
event.preventDefault();
jQuery('body').fadeOut(function() {
window.location = thehref
});
}
});
});
setTimeout(function() {
jQuery('fade').fadeIn();
}, 1000)
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<li class="nav-item">
<a class="nav-link js-scroll-trigger" href="#portfolio">Portfolio</a>
</li>
<li class="nav-item">
<a id="about" class="nav-link js-scroll-trigger" href="https://google.com">About</a>
</li>
If you do not want this result, an edit would help your question. Because at least you have completely confused me. Just let me know what your problem is. :)

Is it possible to add links to bootstrap 4 nav-pills tab-panel from a different page?

I have a service page that using bootstrap 4's pills .nav-pills navigation (this is not the main navigation navbar), which is working very well. My challenge is that i want to be able to click on a link on the home page that should open the targeted tab-panel on the service page. Haven't been able to find a way for almost a week now. How can i achieve this?
Service.html
<div class="nav flex-column nav-pills col-md-3" id="v-pills-tab" role="tablist" aria-orientation="vertical">
<ul class="list-group list-unstyled">
<li class="nav-item">
<a class="nav-link list-group-item" id="v-pills-manpower-tab" data-toggle="pill" href="#v-pills-manpower" role="tab" aria-controls="v-pills-manpower" aria-selected="false">Manpower Supply</a>
</li>
</ul>
</div>
<div class="tab-content col-md-8" id="v-pills-tabContent">
<div class="tab-pane fade" id="v-pills-manpower" role="tabpanel" aria-labelledby="v-pills-manpower-tab">
<h5>Man Power Supply</h5>
</div>
Home.html
<a href="services.html#v-pills-manpower" data-toggle="tab" >
My code in home.html doesn't work but that's one of my many attempts.
On the home page, configure data attributes to help. I've added data-tab-name to the anchor and it defines the desired, selected tab for the service page.
When the page loads, it re-configures the onclick of the link so that the tab name can be stored in localStorage before redirecting the user to the service page.
Home.html
<a href="services.html" data-tab-name="v-pills-manpower" data-toggle="tab" >
<script type="text/javascript">
window.onload = function() {
document.querySelectorAll('[data-toggle="tab"]').forEach(function(item, index){
item.addEventListener('click', function(e){
e.preventDefault();
localStorage.selectedTabName = item.getAttribute('data-tab-name');
window.location.href = item.href;
});
});
};
</script>
When the service page loads, the javascript looks for the saved tab name in localStorage, identifies that tab and then makes it the active tab by applying the "active" class to the appropriate element.
Service.html
<script type="text/javascript">
window.onload = function() {
document.querySelectorAll('.nav-link').forEach(function(item, index){
var isActive = (item.className.indexOf('active')>-1);
if (item.id==localStorage.selectedTabName) {
if (!isActive) {
item.className += ' active';
}
item.setAttribute('aria-selected', 'true');
} else {
item.setAttribute('aria-selected', 'false');
if (isActive) {
item.className = item.className.replace('active', '');
}
}
});
};
</script>

How to select bootstrap tabs using "next" button. I have followed other answers but not working

I have below code in asp.net page to show tabs using bootstrap. I can click tabs without any problems. But now I want to select them one by one using a next ">" button. So, when page loads Price_1 is active and when i click ">" price_2 should be selected and so on. Please give me some suggestions.
Code is here
https://codeshare.io/4SA8A
<style>
.next-tab {
font-weight: bold;
font-size: 18px;
}
</style>
<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/css/bootstrap.min.css">
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1.12.0/jquery.min.js"></script>
<script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.6/js/bootstrap.min.js"></script>
<script type = "text/javascript" src = "http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js"></script>
<script>
$('.next-tab').click(function (e) {
if ($('#tabs > .active').next('li').hasClass('next-tab')) {
$('#tabs > li').first('li').find('a').trigger('click');
} else {
$('.nav-tabs > .active').next('li').find('a').trigger('click');
}
e.preventDefault();
});
</script>
<ul class="nav nav-tabs" style="border-bottom:none">
<li class="active"><a data-toggle="tab" href="#menu1">Price_1</a></li>
<li><a data-toggle="tab" href="#menu2">Price_2</a></li>
<li><a data-toggle="tab" href="#menu3">Price_3</a></li>
<li><a data-toggle="tab" href="#menu4">Price_4</a></li>
<li><a data-toggle="tab" href="#menu5">Price_5</a></li>
<li><a data-toggle="tab" href="#menu6">Price_6</a></li>
<li class="next-tab">></li>
</ul>
I tried this solution as well but it doesn't work. When I click ">" it is going to homepage in IE and in google chrome its not selecting the next tab and also refreshing the page which I don't want. I think this is because the href tag is empty
<li class="next-tab">></li>
Bootstrap: next button should display next tab
Please help.
The problem is that you're including jQuery twice which can cause a conflict, and 1.6.x is too old for Bootstrap 3. Remove the 1.6.x link..
http://ajax.aspnetcdn.com/ajax/jQuery/jquery-1.6.1.min.js
Old jQuery doesn't work: http://bootply.com/gzlsfVTNq9
jQuery 1.9.x or greater works: http://bootply.com/XYpxMIgink#
You load the script before the <a> tag loads, so the events are not getting bound. Enclose your script this way:
<script>
$(function () {
$('.next-tab').click(function (e) {
if ($('#tabs > .active').next('li').hasClass('next-tab')) {
$('#tabs > li').first('li').find('a').trigger('click');
} else {
$('.nav-tabs > .active').next('li').find('a').trigger('click');
}
e.preventDefault();
});
});
</script>
And also, you need to add the id="tabs" here:
<ul class="nav nav-tabs" id="tabs" style="border-bottom:none">
The $(function () {}); is a short hand code for $(document).ready(function () {});. This ensures that the code is executed after the DOM is loaded.

GET Basename of URL then put active class to navbar

Example Link: http://localhost/test/page.php
I have a JavaScript code that will put an active class to a navbar if the url of that href ==== current_url.
Current JavaScript (Only puts active class to sidebar)
<script type="text/javascript">
jQuery(function($) {
var path = window.location.href; // because the 'href' property of the DOM element is the absolute path
$('ul a').each(function() {
if (this.href === path) {
$(this).addClass('sub-menu active');
$(this).parent().closest("li").addClass('active');
$(this).parent().parent().closest("li").addClass('active');
}
});
});
</script>
I want to make it work also if the link has a page.php?success. There will also be an active class as long as the page.php is there regardless of what is after the ?.
I've tried the following script below to extract the basename but now it doesn't work at all, pages with or without ?.
Tried script (Supposed to put active class to sidebar even if the url has page.php?success in it.
<script type="text/javascript">
jQuery(function($) {
var patharray = window.location.pathname.split( '/' );
var reallink = patharray[2];
$('ul a').each(function() {
if (this.href === reallink) {
$(this).addClass('sub-menu active');
$(this).parent().closest("li").addClass('active');
$(this).parent().parent().closest("li").addClass('active');
}
});
});
</script>
With the example link above. The script returns page.php And the href's inside the navbar are just page1.php, page2.php etc... So I know it should work since the retrieved reallink is equal to the href of the navbar.
My sidebar
<li class="sub-menu"> // Sidebar with no submenu
<a class="" href="page1.php">
<i class="icon-calendar"></i>
<span>This is page 1</span>
</a>
</li>
<li class="sub-menu"> // Sidebar with a submenu
<a href="javascript:;" class="">
<i class="icon-group"></i>
<span>This has sub pages</span>
<span class="arrow"></span>
</a>
<ul class="sub">
<li><a class="" href="page2.php">This is page 2</a></li>
<li><a class="" href="page3.php">This is page 3</a></li>
</ul>
</li>
So the first JavaScript puts an active class both to the parent and the child if the href = url is met. But with the 2nd script nothing works.
I guess changing this line in the First script will make it work
var path = window.location.href.split( '?' )[0];

Avoid dropdown menu close on click inside

I have a Twitter Bootstrap dropdown menu. As all Twitter Bootstrap users know, the dropdown menu closes on click (even clicking inside it).
To avoid this, I can easily attach a click event handler on the dropdown menu and simply add the famous event.stopPropagation().
<ul class="nav navbar-nav">
<li class="dropdown mega-dropdown">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-list-alt"></i> Menu item 1
<span class="fa fa-chevron-down pull-right"></span>
</a>
<ul class="dropdown-menu mega-dropdown-menu">
<li>
<div id="carousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-slide-to="0" data-target="#carousel"></li>
<li class="active" data-slide-to="1" data-target="#carousel"></li>
</ol>
<div class="carousel-inner">
<div class="item">
<img alt="" class="img-rounded" src="img1.jpg">
</div>
<div class="item active">
<img alt="" class="img-rounded" src="img2.jpg">
</div>
</div>
<a data-slide="prev" role="button" href="#carousel"
class="left carousel-control">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a data-slide="next" role="button" href="#carousel"
class="right carousel-control">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</li>
</ul>
</li>
</ul>
This looks easy and a very common behavior, however, and since carousel-controls (as well as carousel indicators) event handlers are delegated to the document object, the click event on these elements (prev/next controls, ...) will be “ignored”.
$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
// The event won't be propagated up to the document NODE and
// therefore delegated events won't be fired
event.stopPropagation();
});
Relying on Twitter Bootstrap dropdown hide/hidden events is not a solution for the following reasons:
The provided event object for both event handlers does not give reference to the clicked element
I don't have control over the dropdown menu content so adding a flag class or attribute is not possible
This fiddle is the normal behavior and this fiddle is with event.stopPropagation() added.
Update
Thanks to Roman for his answer. I also found an answer that you can find below.
This should help as well
$(document).on('click', 'someyourContainer .dropdown-menu', function (e) {
e.stopPropagation();
});
Removing the data attribute data-toggle="dropdown" and implementing the open/close of the dropdown can be a solution.
First by handling the click on the link to open/close the dropdown like this :
$('li.dropdown.mega-dropdown a').on('click', function (event) {
$(this).parent().toggleClass('open');
});
and then listening the clicks outside of the dropdown to close it like this :
$('body').on('click', function (e) {
if (!$('li.dropdown.mega-dropdown').is(e.target)
&& $('li.dropdown.mega-dropdown').has(e.target).length === 0
&& $('.open').has(e.target).length === 0
) {
$('li.dropdown.mega-dropdown').removeClass('open');
}
});
Here is the demo :
http://jsfiddle.net/RomaLefrancois/hh81rhcm/2/
The absolute best answer is to put a form tag after the class dropdown-menu
so your code is
<ul class="dropdown-menu">
<form>
<li>
<div class="menu-item">bla bla bla</div>
</li>
</form>
</ul>
Bootstrap provides the following function:
| This event is fired immediately when the hide instance method
hide.bs.dropdown | has been called. The toggling anchor element is available as the
| relatedTarget property of the event.
Therefore, implementing this function should be able to disable the dropdown from closing.
$('#myDropdown').on('hide.bs.dropdown', function (e) {
var target = $(e.clickEvent.target);
if(target.hasClass("keepopen") || target.parents(".keepopen").length){
return false; // returning false should stop the dropdown from hiding.
}else{
return true;
}
});
This might help:
$("dropdownmenuname").click(function(e){
e.stopPropagation();
})
I just add onclick event like below to not close dropdown-menu.
<div class="dropdown-menu dropdown-menu-right" onclick="event.stopPropagation()" aria-labelledby="triggerId">
I also found a solution.
Assuming that the Twitter Bootstrap Components related events handlers are delegated to the document object, I loop the attached handlers and check if the current clicked element (or one of its parents) is concerned by a delegated event.
$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event){
var events = $._data(document, 'events') || {};
events = events.click || [];
for(var i = 0; i < events.length; i++) {
if(events[i].selector) {
//Check if the clicked element matches the event selector
if($(event.target).is(events[i].selector)) {
events[i].handler.call(event.target, event);
}
// Check if any of the clicked element parents matches the
// delegated event selector (Emulating propagation)
$(event.target).parents(events[i].selector).each(function(){
events[i].handler.call(this, event);
});
}
}
event.stopPropagation(); //Always stop propagation
});
Hope it helps any one looking for a similar solution.
Thank you all for your help.
In the new Bootstrap 5 the solution is trivially simple.
Quote from the documentation page:
By default, the dropdown menu is closed when
clicking inside or outside the dropdown menu. You can use the
autoClose option to change this behavior of the dropdown.
In addition to the default behavior, we have 3 options available here:
Clickable outside: data-bs-auto-close="outside"
Clickable inside: data-bs-auto-close="inside"
Manual close: data-bs-auto-close="false"
E.g.:
<div class="btn-group">
<button class="btn btn-secondary dropdown-toggle" data-bs-auto-close="inside" type="button" id="dropdownMenuClickableInside" data-bs-toggle="dropdown" aria-expanded="false">
Clickable inside
</button>
<ul class="dropdown-menu" aria-labelledby="dropdownMenuClickableInside">
<li><a class="dropdown-item" href="#">Menu item</a></li>
<li><a class="dropdown-item" href="#">Menu item</a></li>
<li><a class="dropdown-item" href="#">Menu item</a></li>
</ul>
</div>
More info: https://getbootstrap.com/docs/5.1/components/dropdowns/#auto-close-behavior
$('body').on("click", ".dropdown-menu", function (e) {
$(this).parent().is(".open") && e.stopPropagation();
});
This may work for any conditions.
I tried this simple thing and it worked like a charm.
I changed the dropdown-menu element from <div> to <form> and it worked well.
<div class="nav-item dropdown" >
<a href="javascript:;" class="nav-link dropdown-toggle" data-toggle="dropdown">
Click to open dropdown
</a>
<form class="dropdown-menu ">
<ul class="list-group text-black">
<li class="list-group-item" >
</li>
<li class="list-group-item" >
</li>
</ul>
</form>
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.14.7/umd/popper.min.js"></script>
<script src="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/js/bootstrap.min.js"></script>
<link href="https://stackpath.bootstrapcdn.com/bootstrap/4.3.1/css/bootstrap.min.css" rel="stylesheet"/>
<div class="nav-item dropdown" >
<a href="javascript:;" class="nav-link dropdown-toggle" data-toggle="dropdown">
Click to open dropdown
</a>
<form class="dropdown-menu ">
<ul class="list-group text-black">
<li class="list-group-item" >
List Item 1
</li>
<li class="list-group-item" >
LI 2<input class="form-control" />
</li>
<li class="list-group-item" >
List Item 3
</li>
</ul>
</form>
jQuery:
<script>
$(document).on('click.bs.dropdown.data-api', '.dropdown.keep-inside-clicks-open', function (e) {
e.stopPropagation();
});
</script>
HTML:
<div class="dropdown keep-inside-clicks-open">
<button class="btn btn-primary dropdown-toggle" type="button" data-toggle="dropdown">
Dropdown Example
<span class="caret"></span>
</button>
<ul class="dropdown-menu">
<li>HTML</li>
<li>CSS</li>
<li>JavaScript</li>
</ul>
</div>
Demo:
Generic:
https://jsfiddle.net/kerryjohnson/omefq68b/1/
Your demo with this solution: http://jsfiddle.net/kerryjohnson/80oLdtbf/101/
I modified #Vartan's answer to make it work with Bootstrap 4.3. His solution doesn't work anymore with the latest version as target property always returns dropdown's root div no matter where the click was placed.
Here is the code:
$('.dropdown-keep-open').on('hide.bs.dropdown', function (e) {
if (!e.clickEvent) {
// There is no `clickEvent` property in the `e` object when the `button` (or any other trigger) is clicked.
// What we usually want to happen in such situations is to hide the dropdown so we let it hide.
return true;
}
var target = $(e.clickEvent.target);
return !(target.hasClass('dropdown-keep-open') || target.parents('.dropdown-keep-open').length);
});
<div class="dropdown dropdown-keep-open">
<button class="btn btn-secondary dropdown-toggle" type="button" id="dropdownMenuButton" data-toggle="dropdown" aria-haspopup="true" aria-expanded="false">
Dropdown button
</button>
<div class="dropdown-menu" aria-labelledby="dropdownMenuButton">
<a class="dropdown-item" href="#">Action</a>
<a class="dropdown-item" href="#">Another action</a>
<a class="dropdown-item" href="#">Something else here</a>
</div>
</div>
$('body').on("click", ".dropdown-menu", function (e) {
$(this).parent().is(".show") && e.stopPropagation();
});
Like for instance Bootstrap 4 Alpha has this Menu Event. Why not use?
// PREVENT INSIDE MEGA DROPDOWN
$('.dropdown-menu').on("click.bs.dropdown", function (e) {
e.stopPropagation();
e.preventDefault();
});
You can also use form tag. Example:
<div class="dropdown-menu">
<form>
Anything inside this wont close the dropdown!
<button class="btn btn-primary" type="button" value="Click me!"/>
</form>
<div class="dropdown-divider"></div>
<a class="dropdown-item" href="#">Clik this and the dropdown will be closed</a>
<a class="dropdown-item" href="#">This too</a>
</div>
Source: https://getbootstrap.com/docs/5.0/components/dropdowns/#forms
Bootstrap 5
If anyone comes to this via Google wanting a Bootstrap 5 version like I was, it's built in by adding data-bs-auto-close="outside". Note the option is autoClose but when passing as a data attribute the camelcasing is removed & separated by a dash.
I have a collapse widget in a dropdown & adding data-bs-auto-close="outside" to the parent data-bs-toggle="dropdown" trigger keeps the dropdown open while the collapse is toggled.
See official Bootstrap docs: https://getbootstrap.com/docs/5.1/components/dropdowns/#options
And this codepen for example code (not my pen): https://codepen.io/SitePoint/pen/BaReWGe
I've got a similar problem recently and tried different ways to solve it with removing the data attribute data-toggle="dropdown" and listening click with event.stopPropagation() calling.
The second way looks more preferable. Also Bootstrap developers use this way.
In the source file I found initialization of the dropdown elements:
// APPLY TO STANDARD DROPDOWN ELEMENTS
$(document)
.on('click.bs.dropdown.data-api', clearMenus)
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
.on('click.bs.dropdown.data-api', toggle, Dropdown.prototype.toggle)
.on('keydown.bs.dropdown.data-api', toggle, Dropdown.prototype.keydown)
.on('keydown.bs.dropdown.data-api', '.dropdown-menu', Dropdown.prototype.keydown)
}(jQuery);
So, this line:
.on('click.bs.dropdown.data-api', '.dropdown form', function (e) { e.stopPropagation() })
suggests you can put a form element inside the container with class .dropdown to avoid closing the dropdown menu.
Bootstrap has solved this problem themselves in their support for <form> tags in dropdowns. Their solution is quite graspable and you can read it here: https://github.com/twbs/bootstrap/blob/v4-dev/js/src/dropdown.js
It boils down to preventing propagation at the document element and doing so only for events of type 'click.bs.dropdown.data-api' that match the selector '.dropdown .your-custom-class-for-keep-open-on-click-elements'.
Or in code
$(document).on('click.bs.dropdown.data-api', '.dropdown .keep-open-on-click', (event) => {
event.stopPropagation();
});
You could simply execute event.stopPropagation on click event of the links themselves.
Something like this.
$(".dropdown-menu a").click((event) => {
event.stopPropagation()
let url = event.target.href
//Do something with the url or any other logic you wish
})
Edit: If someone saw this answer and is using react, it will not work.
React handle the javascript events differently and by the time your react event handler is being called, the event has already been fired and propagated. To overcome that you should attach the event manually like that
handleMenuClick(event) {
event.stopPropagation()
let menu_item = event.target
//implement your logic here.
}
componentDidMount() {
document.getElementsByClassName("dropdown-menu")[0].addEventListener(
"click", this.handleMenuClick.bind(this), false)
}
}
You can stop click on the dropdown from propagating and then manually reimplement the carousel controls using carousel javascript methods.
$('ul.dropdown-menu.mega-dropdown-menu').on('click', function(event) {
event.stopPropagation();
});
$('a.left').click(function () {
$('#carousel').carousel('prev');
});
$('a.right').click(function () {
$('#carousel').carousel('next');
});
$('ol.carousel-indicators li').click(function (event) {
var index = $(this).data("slide-to");
$('#carousel').carousel(index);
});
Here is the jsfiddle.
demo: http://jsfiddle.net/4y8tLgcp/
$('ul.nav.navbar-nav').on('click.bs.dropdown', function(e){
var $a = $(e.target), is_a = $a.is('.is_a');
if($a.hasClass('dropdown-toggle')){
$('ul.dropdown-menu', this).toggle(!is_a);
$a.toggleClass('is_a', !is_a);
}
}).on('mouseleave', function(){
$('ul.dropdown-menu',this).hide();
$('.is_a', this).removeClass('is_a');
});
i have updated it once again to be the smartest and functional as possible. it now close when you hover outside the nav, remaining open while you are inside it. simply perfect.
I know there already is a previous answer suggesting to use a form but the markup provided is not correct/ideal. Here's the easiest solution, no javascript needed at all and it doesn't break your dropdown. Works with Bootstrap 4.
<form class="dropdown-item">
<!-- Your elements go here -->
</form>
I know this question was specifically for jQuery, but for anyone using AngularJS that has this problem you can create a directive that handles this:
angular.module('app').directive('dropdownPreventClose', function() {
return {
restrict: 'A',
link: function(scope, element, attrs) {
element.on('click', function(e) {
e.stopPropagation(); //prevent the default behavior of closing the dropdown-menu
});
}
};
});
Then just add the attribute dropdown-prevent-close to your element that is triggering the menu to close, and it should prevent it. For me, it was a select element that automatically closed the menu:
<div class="dropdown-menu">
<select dropdown-prevent-close name="myInput" id="myInput" ng-model="myModel">
<option value="">Select Me</option>
</select>
</div>
With Angular2 Bootstrap, you can use nonInput for most scenarios:
<div dropdown autoClose="nonInput">
nonInput - (default) automatically closes the dropdown when any of its elements is clicked — as long as the clicked element is not an input or a textarea.
https://valor-software.com/ng2-bootstrap/#/dropdowns
[Bootstrap 4 Alpha 6][Rails]
For rails developer, e.stopPropagation() will lead to undesirable behavior for link_to with data-method not equal to get since it will by default return all your request as get.
To remedy this problem, I suggest this solution, which is universal
$('.dropdown .dropdown-menu').on('click.bs.dropdown', function() {
return $('.dropdown').one('hide.bs.dropdown', function() {
return false;
});
});
$('.dropdown .dropdown-menu').on('click.bs.dropdown', function() {
return $('.dropdown').one('hide.bs.dropdown', function() {
return false;
});
});
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/css/bootstrap.min.css" integrity="sha384-rwoIResjU2yc3z8GV/NPeZWAv56rSmLldC3R/AZzGRnGxQQKnKkoFVhFQhNUwEyJ" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.1.1.slim.min.js" integrity="sha384-A7FZj7v+d/sdmMqp/nOQwliLvUsJfDHW+k9Omg/a/EheAdgtzNs3hpfag6Ed950n" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/tether/1.4.0/js/tether.min.js" integrity="sha384-DztdAPBWPRXSA/3eYEEUWrWCy7G5KFbe8fFjk5JAIxUYHKkDx6Qin1DkWx51bBrb" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-alpha.6/js/bootstrap.min.js" integrity="sha384-vBWWzlZJ8ea9aCX4pEW3rVHjgjt7zpkNpZk+02D9phzyeVkE+jo0ieGizqPLForn" crossorigin="anonymous"></script>
<ul class="nav navbar-nav">
<li class="dropdown mega-dropdown">
<a href="javascript:;" class="dropdown-toggle" data-toggle="dropdown">
<i class="fa fa-list-alt"></i> Menu item 1
<span class="fa fa-chevron-down pull-right"></span>
</a>
<ul class="dropdown-menu mega-dropdown-menu">
<li>
<div id="carousel" class="carousel slide" data-ride="carousel">
<ol class="carousel-indicators">
<li data-slide-to="0" data-target="#carousel"></li>
<li class="active" data-slide-to="1" data-target="#carousel"></li>
</ol>
<div class="carousel-inner">
<div class="item">
<img alt="" class="img-rounded" src="img1.jpg">
</div>
<div class="item active">
<img alt="" class="img-rounded" src="img2.jpg">
</div>
</div>
<a data-slide="prev" role="button" href="#carousel" class="left carousel-control">
<span class="glyphicon glyphicon-chevron-left"></span>
</a>
<a data-slide="next" role="button" href="#carousel" class="right carousel-control">
<span class="glyphicon glyphicon-chevron-right"></span>
</a>
</div>
</li>
</ul>
</li>
</ul>
This helped me,
$('.dropdown-menu').on('click', function (e) {
if ($(this).parent().is(".open")) {
var target = $(e.target);
if (target.hasClass("keepopen") || target.parents(".keepopen").length){
return false;
}else{
return true;
}
}
});
Your drop down menu element needs to be like this, (take a note of the classes dropdown-menu and keepopen.
<ul role="menu" class="dropdown-menu topmenu-menu eserv_top_notifications keepopen">
The above code prevents biding on the whole <body>, instead to the specfic element with the class dropdown-menu.
Hope this helps someone.
Thanks.
The simplest working solution for me is:
adding keep-open class to elements that should not cause dropdown closing
and this piece of code do the rest:
$('.dropdown').on('click', function(e) {
var target = $(e.target);
var dropdown = target.closest('.dropdown');
return !dropdown.hasClass('open') || !target.hasClass('keep-open');
});
I've found none of the solutions worked as I would like using default bootstrap nav.
Here is my solution to this problem:
$(document).on('hide.bs.dropdown', function (e) {
if ($(e.currentTarget.activeElement).hasClass('dropdown-toggle')) {
$(e.relatedTarget).parent().removeClass('open');
return true;
}
return false;
});
Instead of writing some javascript or jquery code(reinventing the wheel). The above scenario can be managed by bootstrap auto-close option.
You can provide either of the values to auto-close:
always - (Default) automatically closes the dropdown when any of its elements is clicked.
outsideClick - closes the dropdown automatically only when the user clicks any element outside the dropdown.
disabled - disables the auto close
Take a look at the following plunkr :
http://plnkr.co/edit/gnU8M2fqlE0GscUQtCWa?p=preview
Set
uib-dropdown auto-close="disabled"
Hope this helps :)
In .dropdown content put the .keep-open class on any label like so:
$('.dropdown').on('click', function (e) {
var target = $(e.target);
var dropdown = target.closest('.dropdown');
if (target.hasClass('keep-open')) {
$(dropdown).addClass('keep-open');
} else {
$(dropdown).removeClass('keep-open');
}
});
$(document).on('hide.bs.dropdown', function (e) {
var target = $(e.target);
if ($(target).is('.keep-open')) {
return false
}
});
The previous cases avoided the events related to the container objects, now the container inherits the class keep-open and check before being closed.

Categories