Reputation: 1205
I am trying to modify the behavior of the bootstrap dropdown. First, I wanted to prevent the dropdown from closing when you click elsewhere on the page. I did that with this code:
$('#filters').on({
"shown.bs.dropdown": function() { this.closable = false; },
"click": function() { this.closable = true; },
"hide.bs.dropdown": function() { return this.closable; }
});
Now, I want to delay the closing of the dropdown, when you click a link inside it. I want to do this because the dropdown closes immediately when you click the link, before you've actually left the page and loaded the new one.
Here is a fiddle of what I have so far.
Upvotes: 4
Views: 2139
Reputation: 29683
How about this DEMO
I would like to suggest you 2 things:
- add
eventlisteners
on.btn-group
instead of#filters
as its easy enough to check whichdropdown
was clicked- Add the required animations to
click
event instead
So according to above suggestions code would go as below:
$('.btn-group').on({
"shown.bs.dropdown": function () {
this.closable = false;
},
"click": function () {
this.closable = true;
if(!$(this).hasClass('open'))
$(this).find('.dropdown-menu').stop(true, true).slideToggle();
else
$(this).find('.dropdown-menu').stop(true, true).delay(600).slideToggle();
},
"hide.bs.dropdown": function () {
return this.closable;
}
});
UPDATE :
Based on your comment, I hope this is what you would desire to achieve:
$('.btn-group').on({
"shown.bs.dropdown": function () {
this.closable = false;
},
"click": function () {
this.closable = true;
$('.btn-group').not($(this)).find('.dropdown-menu').stop(true, true).slideUp();//Close all the dropdowns except this
if(!$(this).hasClass('open'))
{
$(this).find('.dropdown-menu').stop(true, true).slideToggle();//open only this dropdown
$('.btn-group').not($(this)).removeClass('open'); //remove the focus effect from other dropdowns
}
else
$(this).find('.dropdown-menu').stop(true, true).delay(600).slideToggle();
},
"hide.bs.dropdown": function () {
return this.closable;
}
});
Upvotes: 2
Reputation: 764
Well, I think you have to hack the normal bootstrap dropdown event sequence a bit, but you could use the event with an if/else to trigger the delay + slideUp() only if the this.closable is true. Then, since you're not able to "return true" on the hide.bs.dropdown event, you have to remove the 'open' class and then trigger the 'show()' yourself the next time you click the dropdown... like this:
Here's a fiddle with one working dropdown - you'll have to make unique ID's for each dropdown if you have multiples, and then probably use the event.target.[something] to identify the correct dropdown to toggle...
http://jsfiddle.net/yp44tt9e/2/
$('#filters').on({
"show.bs.dropdown": function() {
console.log($(this));
$(this).find('.dropdown-menu').show();
},
"shown.bs.dropdown": function () {
this.closable = false;
},
"click": function () {
this.closable = true;
},
"hide.bs.dropdown": function (e){
if(this.closable){
e.preventDefault();
$(this).find('.dropdown-menu')
.first()
.stop(true, true)
.delay(600)
.slideUp('slow', function(){
$('.btn-group').removeClass('open');
});
}else{
return this.closable;
}
}
});
Upvotes: 0