Bootstrap dropdown menu: not close when click outside the menu - javascript

I'm using this script to control open/collapse menu items:
$('.dropdown').on({
"click": function(event) {
if ($(event.target).closest('.dropdown-toggle').length && $(this).parents('.dropdown').length === ($(event.target).parents('.dropdown').length - 1)) {
$(this).data('closable', true);
} else {
$(this).data('closable', false);
}
},
"hide.bs.dropdown": function(event) {
hide = $(this).data('closable');
$(this).data('closable', true);
return hide;
}
});
But I need to create a conditional that if user click outside the menu, the open item not close.
This question involves Bootstrap specificities. Just using:
$(document).on('click', function(event)
Not answer my question completely.

Try this to detect if you are out of the menu.
$(document).on('click', function(event) {
if (!$(event.target).closest('.dropdown-toggle').length) {
return false;
}
});

Related

Href links inside my mobile menu bar doesn't work

$(document).click(function (event) {
if ($("#sidenav").width() != 0) {
$("#sidenav").css({ 'width': '0' });
}
});
$("#sidenav").click(function (e) {
e.stopPropagation();
return false;
});
$("#navHome").click(function () {
$("#navHome").attr("href", "/public/templates/default/index.html");
$("#sidenav").css({ 'width': '0' });
});
1) The $(document).click(function (event) function closes the nav bar if user click anywhere outside the navbar
2) The $("#sidenav").click(function (e) function prevents nav bar from closing if user click anywhere inside the navbar
3) Now because of the e.stopPropagation(); in the second function, when I click on the navHome it did close the navBar but didn't take me to the index page. In other words, $("#navHome").attr("href","/public/templates/default/index.html"); doesn't work.
Is there a work around for this? Thanks!
Do not cancel the click if the target is a link
$("#sidenav").click(function (e) {
if(!$(e.target).closest("a").length) {
e.stopPropagation();
return false;
}
});

Issue with quiz and jQuery

I have written simple quiz with two cards. After user have clicked on the card, attribute clicked change status and answer is checked.
clicked = false;
$(document).on("click", "#card1", function() {
clicked = true;
check answer........
});
I have got antoher on click event, which should load next question when user click on body element.
This event should only work when the card is clicked and clicked status is true.
$(document).on("click", "body", function() {
if (clicked == true) {
quiz.nextQuestion();
clicked = false;
}
});
But these two onclick events start and execute simultaneously.
How can I prevent this?
stopPropagation(); can be used for this. Otherwise click on elements inside will also trigger the body click functions.
One more thing is that, we have to give click for <html> rather than <body>.
Description: Prevents the event from bubbling up the DOM tree, preventing any parent handlers from being notified of the event.
clicked = false;
$(document).on("click", "#card1", function(e) {
e.stopPropagation();
clicked = true;
console.log('click card');
});
$(document).on("click", "html", function(e) {
if (clicked == true) {
console.log('click body');
clicked = false;
}
});
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<body>
<div id="card1">
Card1
</div>
</body>
Simple...
clicked = false;
$(document).on("click", "#card1", function() {
clicked = true;
//check answer........
$(this).on("click", "body", function() {
if (clicked == true) {
quiz.nextQuestion();
clicked = false;
}
});
});
Hope this helps.....
You can do it by changing the status of clicked as true after you have checked the answer.
$(document).on("click", "#card1", function() {
check answer........
clicked = true;
});
This will make sure that clicked is not made true as soon as the click event is fired hence making the if statement in the second part of the code false
OR
You can even do it by
clicked = 0;
$(document).on("click", "#card1", function() {
clicked = 1;
check answer........
});
$(document).on("click", "body", function() {
if (clicked == 2) {
quiz.nextQuestion();
clicked = 0;
}else
{
clicked +=1;
}
});

Menu should disappear when clicked somewhere else

I have a div which should be visible, whenever a button is clicked. It's like a menu. Afterwards, it should disappear (toggle), when the button is clicked again or when the user clicks somewhere else on the page (whole body).
In my current approach, the menu constantly toggles, so both functions (see below) are being triggered.
$("#b1").click(function() {
$("#menu").toggle("slide");
});
$("body").click(function() {
if ($("#menu").is(":visible")) {
$("#menu").toggle("slide");
}
});
How should I improve my code, so that the menu only disappears when the button is clicked again or when the user clicks somewhere else?
Here is a fiddle.
Use $(window) to attach the event, then you can close the menu anywhere.
$("#b1").click(function() {
$("#menu").toggle("slide");
return false;
});
$(window).click(function() {
if ($("#menu").is(":visible")) {
$("#menu").toggle("slide");
}
});
Check demo: https://jsfiddle.net/wru8mvxt/5/
You can use e.target and check whenever it's not the menu or the button which got clicked. Otherwise the menu closed even on the button click or on a click inside.
$("#b1").click(function() {
$("#menu").slideDown();
});
$("body").click(function(e) {
if (!$(e.target).is("#b1") && $("#menu").is(":visible")) {
$("#menu").slideUp();
} else {
e.preventDefault();
}
});
If you want the menu to stay even on click inside, just add && !$(e.target).is("#menu") to the if condition.
Working example.
I think your code looks good.. I see one problem when you click on menu it will be hide.
$("#b1").click(function() {
$("#menu").toggle("slide");
return false; // prevent to pass click event to body
});
$("body").click(function() {
if ($("#menu").is(":visible")) {
$("#menu").toggle("slide");
}
});
$("#menu").click(function(e){
e.preventDefault();
return false;
});
Use something like this:
$(document).mouseup(function (e)
{
var container = $("YOUR CONTAINER SELECTOR");
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();
}
});
Try this.
$("#b1").click(function() {
event.stopPropagation();
$("#menu").toggle("slide");
});
$("body").click(function() {
if(!$(event.target).closest('#menu').length){
if ($("#menu").is(":visible")) {
$("#menu").toggle("slide");
}
}
});
I think this code will solve your issue. You can use e.target property to find whether user clicked on button or outside button. When user click on button b1 it enters both b1 click event and body click event. So if in order to find where the user is clicked you can use event.target property.
Clicking the button will toggle the menu visibility.
Clicking outside the button will close the menu if it is opened.
$("#b1").click(function() {
$("#menu").toggle("slide");
$("#b1").text() == "hide menu" ? $("#b1").text("show menu") : $("#b1").text("hide menu");
});
$("body").click(function(e) {
if (!$(e.target).is("#b1") && $("#menu").is(":visible")) {
$("#menu").slideUp();
}
else {
e.preventDefault();
}
});
Working fiddle
You have to do following changes.
$(document).ready(function() {
$("#b1").click(function(e) {
$("#menu").slideToggle();
e.stopPropagation();
});
$(document).click(function(e) {
if (!$(e.target).is('#menu, #menu *')) {
$("#menu").slideUp();
}
});
});

Prevent bootstrap dropdown from closing on click event [duplicate]

This question already has answers here:
How do I prevent my dropdown from closing when clicking inside it?
(3 answers)
Closed 4 years ago.
My menu uses Bootstrap 3 and I can't prevent dropdown from closing on click. How can I do it?
JSFiddle
// Add open class if active
$('.sidebar-nav').find('li.dropdown.active').addClass('open');
// Open submenu if active
$('.sidebar-nav').find('li.dropdown.open ul').css("display","block");
// Change active menu
$(".sidebar-nav > li").click(function(){
$(".sidebar-nav > li").removeClass("active");
$(this).addClass("active");
});
// Add open animation
$('.dropdown').on('show.bs.dropdown', function(e){
$(this).find('.dropdown-menu').first().stop(true, true).slideDown();
});
// Add close animation
$('.dropdown').on('hide.bs.dropdown', function(e){
$(this).find('.dropdown-menu').first().stop(true, true).slideUp();
});
You need to stop event from bubbling up the DOM tree:
$('.dropdown-menu').click(function(e) {
e.stopPropagation();
});
event.stopPropagation prevents event from reaching the node where it's eventually handled by Bootstrap hiding menu.
Demo: http://jsfiddle.net/wkc5md23/3/
I believe this should be a more proper solution, as stopping propagation on the click event might sometimes cause issues later on in development. You may read more into it here: http://css-tricks.com/dangers-stopping-event-propagation/ Instead this solution stops propagation on the Bootstrap hide (hide.bs.dropdown) event, which stops it from continuing on to the hidden (hidden.bs.dropdown) event.
The following code has been taken and edited by myself to make it work on all Bootstrap dropdowns, as it has originally been taken from here: Preventing bootstrap dropdown from closing on click I personally prefer this way also because it uses the built in Bootstrap dropdown events, which could be found here: https://getbootstrap.com/docs/3.4/javascript/#dropdowns-events.
$(function () {
$('.dropdown').on({
'click': function (event) {
if ($(event.target).closest('.dropdown-toggle').length) {
$(this).data('closable', true);
} else {
$(this).data('closable', false);
}
},
'hide.bs.dropdown': function (event) {
hide = $(this).data('closable');
$(this).data('closable', true);
return hide;
}
});
});
You can disable the dropdown functionality temporarily. This is a workaround.
Example with input field inside the drop-down "menu":
//for dropdown field not closing when clicking on inputfield
$(document).on('focus', 'input', function (e) {
// this attribute can be anything except "dropdown", you can leave it blank
$('#yourDropdownID').attr('data-toggle', 'off');
});
//for dropdown field back to normal when not on inputfield
$(document).on('focusout', 'input', function (e) {
$('#yourDropdownID').attr('data-toggle', 'dropdown');
});
This can be used on anything that is clickable and you can define individually what items clicked can close or not close the drop-down menu.
Not close in click out side menu
$(function() {
var closeble = false;
$('body').on('click', function (e) {
if (!$(event.target).is('a.dropdown-toggle')) {
closeble = false;
}
});
$('.dropdown').on({
'click': function (event) {
if ($(event.target).closest('.dropdown-toggle').length) {
closeble = true;
} else {
closeble = false;
}
},
'hide.bs.dropdown': function () {
return closeble;
}
});
});

jQuery menu with click to show and hide on mouseleave

At the moment it shows the divs instead of hiding them and on click it hides just so you can see the movement. Should be .show instead of .hide. On clicking the link, li should slide down and on mouseleave slide back up.
Working example http://jsfiddle.net/DTqDD/3/
jQuery:
$(function() {
var toggleMenu = function(e) {
var self = $(this),
elemType = self[0].tagName.toLowerCase(),
//get caller
menu = null;
if (elemType === 'a') {
//anchor clicked, nav back to containing ul
menu = self.parents('ul').not('ul#mainmenu');
} else if (elemType === 'ul') {
//mouseleft ul, ergo menu is this.
menu = self;
}
if (menu) {
menu.hide('medium');
}
e.preventDefault();
return false;
};
$(document).ready(function() {
$('a.drop').click(function(e) {
$('li#mainmenudrop').show('medium');
console.log('div clicked');
e.preventDefault();
return false;
});
$('li#mainmenudrop a').click(toggleMenu);
$('li#mainmenudrop').mouseleave(toggleMenu);
});
});
On li tags change id="mainmenudrop" to class="mainmenudrop" since it ain't valid HTML. Then use the following jQuery code.
$(document).ready(function() {
$('a.drop').click(function(e) {
$(this).next("div").show('medium');
console.log('div clicked');
e.preventDefault();
return false;
});
$('li.mainmenudrop').mouseleave(function() {
$(this).children("div").hide('medium');
});
});​
Could this possibly be what you are trying to accomplish?
EDIT:
If you want the divs hidden at the beginning, just add this CSS:
.mainmenudrop div {
display: none;
}

Categories