LBF
LBF

Reputation: 1205

Delay closing of bootstrap dropdown

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

Answers (2)

Guruprasad J Rao
Guruprasad J Rao

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 which dropdown 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:

DEMO

$('.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

jordajm
jordajm

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

Related Questions