I want to have my menu closed when the user clicks outside the menu, not only outside the navbar element. Because I have more collapses in my menu, this solution did not work for me: How to close an open collapsed navbar when clicking outside of the navbar element in Bootstrap 3?
The menu disapeares when I click outside the menu, but when I click on the link with a dropdown, the whole menu collapses.
<div class="collapse navbar-collapse nav-mobile" id="bs-example-navbar-collapse-1">
<ul class="nav navbar-nav">
<li class="list-group panel">
Webshop
<ul class="collapse" id="submenu-1">
Industriële verpakkingen
Promotionele verpakkingen
Gelamineerde verpakkingen
Enveloppen &verzend verpakkingen
Medische verpakkingen
Co-packing
</ul>
</li>
</ul>
You can use this to collapse if not clicking a link: fiddle
$(document).click(function(e) {
if (!$(e.target).is('a')) {
$('.collapse').collapse('hide');
}
});
another alternative, you can add code below :
<script>
$(document).ready(function(){
$(".list-group ").hover(
function() {
$('.collapse', this).stop( true, true ).slideDown("fast");
$(this).toggleClass('open');
},
function() {
$('.collapse', this).stop( true, true ).slideUp("fast");
$(this).toggleClass('open');
}
);
});
</script>
another example : dtc-eng
Here is my take on this:
$(document).on('click', function(event){
var $clickedOn = $(event.target),
$collapsableItems = $('.collapse'),
isToggleButton = ($clickedOn.closest('.navbar-toggle').length == 1),
isLink = ($clickedOn.closest('a').length == 1),
isOutsideNavbar = ($clickedOn.parents('.navbar').length == 0);
if( (!isToggleButton && isLink) || isOutsideNavbar ) {
$collapsableItems.each(function(){
$(this).collapse('hide');
});
}
});
This solution handles:
single page website/applications (and will work on multi-pages too).
clicks on:
.navbar-toggle elements (could be <buttons> or <a>, and it handles clicks on potential inner elements like <span> or <strong> or whatever).
on simple <a> elements (again, it handles clicks on inner elements).
just outside some particular parent (ie. .navbar).
multiple collapsable (.collapse) elements that might be open (indistinct to where they are placed in the DOM).
Not enough for you? No problem. You can customize most of the selectors passed to jQuery (document, .collapse, .navbar, etc) to suit your needs or even add more conditions.
Related
I am creating a web app that searches for events using an event api. I have a filter navbar where the user can enter certain filters (date-range, event category, distance, etc). I put a click handler on one of the navbar elements(category) so that it displays the hidden dropdown menu upon click. If the same navbar element is clicked again or any of its children (hidden dropdown elements), the dropdown menu should disappear. I used jQuery to change the text of the navbar element to the text of the category that was clicked from the dropdown menu. However, when I try to click the navbar element again, it is locked and I can't open it. I can't seem to find what is wrong with my code. Hopefully some additional eyes can help me spot it.
Here is the code.
<nav class="filter__container">
<ul class="filter">
<li class="filter__category">Category
<div class="filter__category__choices">
<p class="filter__category__choice">Art</p>
<p class="filter__category__choice">Music</p>
<p class="filter__category__choice">Sports</p>
<p class="filter__category__choice">Festival</p>
<p class="filter__category__choice">Miscellaneous</p>
</div>
</li>
<li class="filter__submit">Apply Filters</li>
</ul>
</nav>
const categoryFilter = $(".filter__category");
let categoryOpen = false;
categoryFilter.click((e) => {
if(e.target !== categoryFilter[0]) {
$(".filter__category").text($(e.target).text());
}
if(categoryOpen) {
categoryPopup.slideUp();
categoryOpen = false;
}
else {
categoryPopup.slideDown();
categoryOpen = true;
}
});
I bought this theme a while back and have been chopping it up and modifying it to add/remove functionality. There is this slidein menu that appears on the page once a link is clicked from the navbar menu. The issue is that there is an X button to close the menu that is supposed to toggle/remove a class from the #btn-offcanvas-menu element when it is clicked (#btn-close-canvasmenu is clickable element); it works on the desktop but not the responsive mobile site. The only way it is toggled/removed on mobile is if the original link is clicked again. I have looked at the below questions here, and several others, including trying to use the closest/find options but nothing seems to work. What am I missing?
Desired behavior: the isLeft class should toggle/be removed when the #btn-close-canvasmenu link is clicked. It is on desktop but not mobile.
Javascript not working on mobile but works on desktop.
JavaScript - removeClass not working?
ToggleClass and RemoveClass not working
JQuery - ToggleClass/AddClass/RemoveClass
How to toggle class of closest element jquery toggle class on closest span
This is relevant portion of the index page...
<li id="recent-mobile"><!-- this is hidden by CSS on desktop -->
<a id="btn-offcanvas-menu" href="#">Recent Results</a>
</li>
<li id="recent-results"><!-- this is hidden by CSS on mobile -->
<div class="header-buttons pull-right hidden-xs hidden-sm">
<div class="navright-button">
<i class="fa fa-bars"> Recent Results</i>
</div>
</div>
</li>
<!-- Menu OffCanvas right begin -->
<div class="navright-button">
<div class="compact-menu-canvas" id="offcanvas-menu">
<h3>menu</h3><a id="btn-close-canvasmenu"><i class="fa fa-close"></i></a>
<nav>
<ul class="clearfix">
<li>Home</li>
<li>Features</li>
<li>Pages</li>
<li>Portfolios</li>
<li>Shop</li>
<li>Blog</li>
<li>Contact Us</li>
</ul>
</nav>
</div>
</div>
<!-- Menu OffCanvas right close -->
This is the relevant portion of the javascript compact.js file...
$("#btn-close-canvasmenu").on("click", function() {
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), $("a#btn-offcanvas-menu").removeClass("isLeft")
});
$(document).on("click", "#btn-offcanvas-menu, #btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
EDIT (fixed 2/16/20): I edited the js file file to reflect this updated function: $("#btn-close-canvasmenu").on("click", function()
Essentially, what fixed it was changing the selector from #btn-offcanvas-menu to a#btn-offcanvas-menu. Not sure why that worked as opposed to using closest/find method but once I did, it toggled/removed the class on both desktop and mobile correctly. If anyone has anything thoughts on why the a made the difference with the selector, I'd appreciate the feedback as I am not an expert on js/jQuery. Otherwise, this can be considered closed.
Changing the selector in the compact.js file from #btn-offcanvas-menu to a#btn-offcanvas-menu fixed the issue and while this worked, it was the wrong way to correct the issue as connexo pointed out due to the duplicate ids.
The correct way to resolve this was to change the mobile navbar itself so I could use an id specifically for the mobile that only appeared there.
<nav id="mobile-menu" class="site-mobile-menu hidden-lg hidden-md">
<ul>
<li id="recent-mobile">
Recent Results
</li>
</ul>
</nav>
Next I changed the js function that populated the html for the mobile menu to use prepend instead of append so it populated everything above the Recent Results link...
$("#desktop-menu > ul").children().clone().prependTo($("#mobile-menu > ul")), $("#show-mobile-menu").on("click", function() {
$(this).toggleClass("clicked"), $("#mobile-menu > ul").stop(true, true).slideToggle()
});
Then I tweaked the js function to toggle the class to mobile for the #btn-close-canvasmenu if the selector was #btn-offcanvas-menu-mobile to be used later...
$(document).on("click","#btn-offcanvas-menu,#btn-offcanvas-menu-mobile", {} , function(a){
var id = $(this).attr('id');
if (id === "btn-offcanvas-menu-mobile") {
$("#btn-close-canvasmenu").toggleClass("mobile");
}
return a.preventDefault(), $(this).hasClass("isLeft") ? $("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300) : $("#offcanvas-menu").stop().animate({
right: "0px"
}, 300), $(this).toggleClass("isLeft"), false
});
Finally, I tweaked the js function that closed the menu to check the class to determine which id to toggle the isLeft class for...
$(document).on("click","#btn-close-canvasmenu", {} , function(a){
var id = $(this).attr('id');
if ($(this).hasClass("mobile")) {
var container = $("#btn-offcanvas-menu-mobile");
$("#btn-close-canvasmenu").toggleClass("mobile");
} else {
var container = $("#btn-offcanvas-menu");
}
$("#offcanvas-menu").stop().animate({
right: "-260px"
}, 300), container.removeClass("isLeft")
});
So the first block of code opens and closes the .main-navigation while putting the shadow overlay over the page at the same time. But what I would like to accomplish is to click anywhere outside the navigation to do the same action(close the menu and remove the overlay) only if the menu is opened and overlay is over the page - so if those two classs are applied.
Fiddle: https://jsfiddle.net/bfgb951w/
<header id="ovlay">
<span class="nav-toggle eq">≡</span>
<nav class="main-navigation">
<span class="nav-toggle">×</span>
<ul class="menu">
<li>About</li>
<li>Works and stuff</li>
<li>Contact</li>
</ul>
</nav>
</header>
$(document).ready(function(){
$('.nav-toggle').on('click', function(){
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
});
});
$(document).click(function(){
if($('.nav-toggle').hasClass('open')) {
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
}
});
You never set the open class to the .nav-toggle element so while the $(document).click() fires, the if-statement within it always yields false. Change it to:
$(document).ready(function(){
$('.nav-toggle').on('click', function(){
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
return false;
});
});
$(document).click(function(event){
if($('.main-navigation').hasClass('open') && $(event.target).closest(".main-navigation").length == 0) {
$('.main-navigation').toggleClass('open');
$('#ovlay').toggleClass('overlay');
}
});
Check this fiddle: https://jsfiddle.net/1n78d9jq/
Note the added check in the document.click that prevents closing when the click is on the main menu itself.
I put a panel inside a bootstrap dropdown, but when I click inside the panel, the dropdown goes away. I got many solution on stackoverflow but it didn't work for me. How can i prevent panel from disappearing when i click inside.enter code here
<span class="input-group-addon dropdown">
<label class="dropdown-toggle " id="dropdownMenu1" data-toggle="dropdown aria-expanded="false">Advanced Search <span class="caret"></span></label>
<div class="panel panel-default panel-body dropdown-menu " role="menu"" aria-labelledby="dropdownMenu1" style="width:860px; margin-left:-700px">
Panel content
</div>
</span>
Try to do something like this:if you click on the body it checks the parent class,if you click on the dropdown if parent has class .dropdown-parentclass then the dropdown does not close.
$('body').click(function(event){
if ($(event.target).parent('.dropdown-parentclass').size()>0) {
return false;
}
});
try using the code below. It will close the dropdown only when you click out side the container.
$(document).on("mouseup", function (e) {
var container = $(".panel");
if (!container.is(e.target) // if the target of the click isn't the container
&& container.has(e.target).length === 0) // nor a descendant of the container
{
container.hide();
}
else {
}
});
I'm trying to make a dropdown very similar to dropbox dashboard, where if you click the username a flyout menu appears. Clicking the username again will close the flyout (toggling it every time you click).
The one caveat is that clicking anywhere except on the flyout itself will also close it.
So far, I have it working almost, but not 100%. If you click on the actual 'body' element directly, it will close the flyout as it should. By this I mean my website has a .wrapper element which doesn't take up the full height of the page. Theres a thin strip down at the bottom with no actual element covering it, only the <body> tag. Any place where .wrapper or some other element takes up space (even a 100% width invisible wrapper), it will not close the window if you click on anything where there is an element (besides body).
javascript:
// FLYOUT menu
$flyout = $('.flyout ul'),
flyoutDuration = 120;
$('.flyout h3 a').click(function(e) {
e.preventDefault();
$flyout.fadeToggle(flyoutDuration);
});
$(document).on('click',function(e) {
if ( $(e.target).parents($flyout).length === 0 ) {
$flyout.fadeOut(flyoutDuration);
}
});
HTML
<body>
<div class="blackbar">
<div class="container clearfix">
<div class="icon logo"></div>
<div class="flyout">
<h3>
Welcome back, username
</h3>
<div class="menu">
<ul>
<li><div class="users"></div>Users</li>
<li><div class="groups"></div>Groups</li>
<li><div class="configuration"></div>Configuration</li>
<li><div class="logout"></div>Logout</li>
</ul>
</div>
</div>
</div>
</div>
<div class="wrapper">
<! -- content here -->
</div>
</body>
The expected behavior should be any element you click on that isnt a descendent of .flyout should close the window (including .blackbar, the logo, etc)
To be honest - when I am doing something like this and I do not want clicks inside of the "box" to close the element - I prevent clicks from bubbling.
// FLYOUT menu
$flyout = $('.flyout ul'),
flyoutDuration = 120;
$('.flyout h3 a').click(function(e) {
e.preventDefault();
$flyout.fadeToggle(flyoutDuration);
});
$('.flyout').click(function(e) {
e.stopPropagation();
e.preventDefault();
});
$(document).on('click',function(e) {
if(flyout-open) {
$flyout.fadeOut(flyoutDuration);
}
});
Jquery Menu Click - on click anywhere on body will close the menu
In my case i wanted to close a drop down menu if its clicked primary link or outside the link i.e. anywhere on the html/body
http://jsfiddle.net/austinnoronha/k2Lwj/
var toggleClick = function(){
var divObj = $(this).next();
var nstyle = divObj.css("display");
if(nstyle == "none"){
divObj.slideDown(false,function(){
$("html").bind("click",function(){
divObj.slideUp();
$("html").unbind("click");
});
});
}
};
$(".clickme").click(toggleClick);