Bootsrap 4: Disable button until modal animation is done - javascript

I'm using a Bootstrap 4 modal to show a big navigation.
To open the navigation I'm using a toggle button with a CSS animation. The animation changes a hamburger menu icon to an X.
The problem is, that if you click to fast and the modal animation isn't ready, the button gets confused and shows the X even at an already closed menu/modal.
Is there any way to disable the button until the modal animation is ready?
Here's my code:
$('.menu').click(function(){
$('#burger').toggleClass('active');
});
I saw, that there is a way to listen to the modal animation:
$('#myModal').on('shown', function () {
// do something…
})
But I could not figure out how to implement it in my function.
Here's my actual code: https://codepen.io/cray_code/pen/JjjqRpN

You can just tie toggling of the burger to both show/hide modal events..
var toggleBurger = function () {
$('#burger').toggleClass('active-sandwich');
}
$('#nav-modal').on('show.bs.modal', toggleBurger)
$('#nav-modal').on('hide.bs.modal', toggleBurger)
Demo

Well you could write it like this
$(document).ready(function(){
var isShown = false;
$('#nav-modal').on('shown.bs.modal', function(){
isShown = false;
$("#burger").css("display", "block");
});
if(!isShown)
{
$('#burger').on('click', function(){
isShown = true;
$("#burger").css("display", "none");
});
}
$('#nav-modal').on('hidden.bs.modal', function () {
isShown = false;
$("#burger").css("display", "block");
});
Sorry if the code kind of messy, but I hope you could understand what I mean.
basically I only put some boolean to make sure its showing or not.
After that I validate it. If isshown is false then you can't click until isshown true.

Related

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 hover dropdown menu disappears when hovering on the dropdown menu

I'm doing something slightly different to what i've seen work, many people have done it so there dropdown is part of a child list. However i'm trying to work with a sibling dropdown menu.
Here is my fiddle: http://jsfiddle.net/58m99wf8/
What you'll notice is that if you hover on the button, the dropdown menu appears. If you leave the button it disappears which is perfect. However if you hover on the dropdown menu it still disappears and this isn't what I want it to do.
How can i prevent this?
I've seen it work like this:
if($('#menuONE').has(e.target).length === 0) {
// toggle menu to close
}
However i don't see how i can attach this to the submenu as well as the button.
What you can do is add the menu to the selector.
I also defined menu because this can refer to the button or the menu now, so traversing from there could be problematic.
var menu = $('.dropdown-menu');
$('.dropdown-hover-toggle, .dropdown-menu').hover(
function () {
//show its sibling menu
menu.stop().slideDown();
},
function () {
//hide its sibling menu
menu.stop().slideUp();
});
http://jsfiddle.net/58m99wf8/1/
Try this
var isSiblingHovered = false;
$('.dropdown-hover-toggle').hover(function () {
$(this).siblings('.dropdown-menu').slideDown();
},
function () {
var current = $(this);
setTimeout(function(){
if(!isSiblingHovered){
current.siblings('.dropdown-menu').stop().slideUp();
}
}, 50);
});
$('body').on("mouseleave", ".dropdown-menu", function() {
isSiblingHovered = false;
$('.dropdown-menu').stop().slideUp();
});
$('body').on("mouseenter", ".dropdown-menu", function() {
isSiblingHovered = true;
});
EXAMPLE

Why jquery plugin is not repeating after it's been executed

I am struggling to find a solution to repeat action when user did already one time. For example, when user comes on site there is carousel which can be swiped, slided, and eventually opened in order to see full gallery. I have managed to do that but when the user made this action and closes modal box, he is not able to repeat the same action. Anyone has idea how to solve it?
Here is js
$(document).ready(function () {
// - jQuery
// Swipe feature
$('#myCarousel').swiperight(function () {
$('#myCarousel').carousel('prev');
});
$('#myCarousel').swipeleft(function () {
$('#myCarousel').carousel('next');
});
// Swipe feature for modal
$('#modal-carousel').swiperight(function () {
$('#modal-carousel').carousel('prev');
console.log('swipe_right');
});
$('#modal-carousel').swipeleft(function () {
$('#modal-carousel').carousel('next');
console.log('swipe_left');
});
// Additional toolbar with "close" button appears
$(window).on('shown.bs.modal', function () {
$('modal').modal('show');
$('#toolbar').css('display', 'block'); //.css('position','fixed')
$('.carousel-inner').css('overflow', 'visible');
// Remove entirely in final version
$('.item').css('background', 'none')
console.log('fires toolbar');
});
$(window).on('hidden.bs.modal', function () {
$('modal').modal('show');
$('#toolbar').css('display', 'none'); //.css('position','absolute')
$('.carousel-inner').css('overflow', 'hidden');
// Remove entirely in final version
$('.item').css('background', '#60b1ff')
console.log('closes toolbar when modal is closed');
});
// Closes modal on toolbar
$('.trigger').click(function () {
$('.modal').modal('hide');
});
/* Modal Carousel from version 3. adjusted to version 2.3 */
/* activate the carousel */
$("#modal-carousel").carousel({
interval : false,
});
/* when clicking a image */
$(".thumbnail").click(function () {
var content = $(".carousel-inner");
content.empty();
var id = this.id;
var repo = $('#img-repo .item');
var repoCopy = repo.filter('#' + id).clone();
var active = repoCopy.first();
var next = repoCopy.last();
active.addClass('active');
content.append(repoCopy);
// show the modal
$('#modal-gallery').modal('show');
});
// Carousel pause - prevents automatic slideshow
$('.carousel').carousel({
pause : true,
interval : false
});
// Close window
$('.modal-backdrop').modal({
show : false
});
}); //end of script
Problem is at the content.empty(); which after executed action stays empty. Any ideas how to solve this?
Fiddle
Fiddle 2 with working carousel. Just imagine that you are able to open one of those images in modal.

JQuery drop down, remain down while hover over drop down

I setup a jquery dropdown menu that works perfect. It drops down when a user rolls over a link. The problem is that when the user rolls over the content area of the drop down menu, it slides back up. I need to set up the code so that the slidedown box remains in the down position while the user's cursor is still over it.
Here is my HTML:
<ul id="tabnav">
<li class="tab2">My Leases</li>
</ul>
<div id="leases">
<!-- slide down content here -->
</div>
JS Trigger:
<script type="text/javascript">
$(document).ready(function(){
$(".btn-slide").hover(function(){
$("#leases").slideToggle("medium");
$(this).toggleClass("active");
return false;
});
});
</script>
Any ideas?
EDIT: Here is a link to page in question: http://designvillain.com/testbed/600/601.html
I'm not sure if this is what you want, but I'll just drop it here. It waits 500ms before sliding up #leases, and only when appropriate
var isMousedOver;
var hideDropdown = function(a) {
setTimeout( function() {
if (isMousedOver) return;
$("#leases").slideUp("medium");
$(a).removeClass("active");
}, 500);
}
$(".btn-slide").hover(
function(){
$("#leases").stop(true,true).slideDown("medium");
isMousedOver = true;
$(".btn-slide").removeClass("active");
$(this).addClass("active");
var that = this;
$("#leases").data("mouseoutfn", function() { hideDropdown(that) });
},
function(){
isMousedOver = false;
hideDropdown(this);
}
);
$("#leases").hover(
function() {
isMousedOver = true;
},
function() {
isMousedOver = false;
$(this).data("mouseoutfn")();
}
);
Here's a demo: http://jsfiddle.net/mMRZc/
The .hover() binds two events, mouseenter and mouseleave.
I would instead go granular and use the mouseenter() on the .btn-slide and the mouseleave() on the .leases
$(function()
{
$(".btn-slide").mouseenter(function(){
$("#leases").slideToggle("medium");
$(this).toggleClass("active");
});
$("#leases").mouseleave(function(){
$(".btn-slide").toggleClass("active");
$(this).slideToggle("medium");
});
});
EDIT: Note, if the mouse never enters the #leases div, it will not get the mouseleave, and you may need to consider that.
EDIT2: fix my bad finger typing of funciton to function
I assume the div is hidden on page load and you want it to show when you hover over the link? Change toggle to down...
$(document).ready(function(){
$("#leases").hide();
$(".btn-slide").hover(function(){
$("#leases").slideDown("medium");
$(this).toggleClass("active");
return false;
});
});
Does it need to slide back up sometime?

Show menu/div onclick or onmouseover not the easy way

I'm trying to make a menu that can collapse:
If you click on a button div the menu shows and stays even if you hover the button div.
If you click again on the button div the menu hides.
When the menu is hiding onmouseenter or mouseover it shows onmouseleave or mouseout
it's hiding.
I can't make this happen, this is my code:
$(function() {
$('#arrow').bind('mouseenter', function(){
if($('#hoofdmenu').attr("class") == "show"){
$('#hoofdmenu').addClass("class", "mousehide");
$('#hoofdmenu').hide();
}
else
{
$('#hoofdmenu').removeClass("class", "mousehide");
$('#hoofdmenu').addClass("class", "mouseshow");
$('#hoofdmenu').show();
}
});
$('#arrow').bind('click',function(){
if ($('#hoofdmenu').attr("class") == "show"){
$('#hoofdmenu').attr("class", "hide");
$('#hoofdmenu').hide();
}
else
{
$('#hoofdmenu').attr("class", "show");
$('#hoofdmenu').show();
}
});
});
Someone can help me with this problem?
Kind regards,
Frank
Why do you want to add special classes for this? You can use the hide() and show() function for clicks and the mouseOver() and mouseOut() functions for the mouse hover.
Check this out for more
Edit: For some reason I cannot load jquery.com to point out the right pages
Using attr() and classes a lot is pretty slow, since a DOM reflow is issued each time. Also, make sure to cache elements. We can speed things up a bit doing this:
$(function(){
var menu = $('#menu'),
arrow = $('#arrow'),
isOpen = false;
arrow.hover(function(){
if(isOpen) return;
if(menu.is(':visible'))
menu.hide();
else
menu.show();
});
arrow.click(function(){
if(isOpen)
menu.hide();
else
menu.show();
isOpen = !isOpen; // shift bool
});
});

Categories