If the dropdown is visible, and I click outside the dropdown it closes. I need it to not close.

From the documentation:

When opened, the plugin also adds .dropdown-backdrop as a click area for closing dropdown menus when clicking outside the menu.

What JavaScript can I add to prevent the drop down from closing?


Solution 1:

From the events section of the Bootstrap dropdown documentation:

hide.bs.dropdown: This event is fired immediately when the hide instance method has been called.

For starters, to prevent the dropdown from closing, we can just listen to this event and stop it from proceeding by returning false:

$('#myDropdown').on('hide.bs.dropdown', function () {
    return false;
});

For a complete solution, you probably want to allow it to close when the dropdown itself is clicked. So only some of the time we'll want to prevent the box from closing.

To do this we'll set .data() flags in two more events raised by the dropdown:

  • shown.bs.dropdown - When shown, we'll set .data('closable') to false
  • click - When clicked, we'll set .data('closable') to true

Thus, if the hide.bs.dropdown event was raised by a click on the dropdown, we'll allow a close.

Live Demo in jsFiddle

JavaScript

$('.dropdown.keep-open').on({
    "shown.bs.dropdown": function() { this.closable = false; },
    "click":             function() { this.closable = true; },
    "hide.bs.dropdown":  function() { return this.closable; }
});

HTML (note I've added the class keep-open to the dropdown)

<div class="dropdown keep-open">
    <!-- Dropdown Button -->
    <button id="dLabel" role="button" href="#" class="btn btn-primary"
            data-toggle="dropdown" data-target="#" >
        Dropdown <span class="caret"></span>
    </button>

    <!-- Dropdown Menu -->
    <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li><a href="#">Separated link</a></li>
    </ul>
</div>

Solution 2:

Version changes in some dependency have caused KyleMit's, and most other solutions to no longer work. I dug into a bit further and for some reason a click() is sent when Bootstrap tries and fails hide.bs.dropdown, followed by another call to hide.bs.dropdown. I got around this issue by forcing the closing click() to occur on the button itself, not the entire dropdown menu.

Live Demo in Bootply

JavaScript

$('.keep-open').on({
    "shown.bs.dropdown": function() { $(this).attr('closable', false); },
    //"click":             function() { }, // For some reason a click() is sent when Bootstrap tries and fails hide.bs.dropdown
    "hide.bs.dropdown":  function() { return $(this).attr('closable') == 'true'; }
});

$('.keep-open').children().first().on({
  "click": function() {
    $(this).parent().attr('closable', true );
  }
})

HTML

<h2>Click the dropdown button </h2>
<p>It will stay open unless clicked again to close </p>

<div class="dropdown keep-open">
    <!-- Dropdown Button -->
    <button id="dLabel" role="button" href="#" data-toggle="dropdown" data-target="#" class="btn btn-primary">
        Dropdown <span class="caret"></span>
    </button>
    
    <!-- Dropdown Menu -->
    <ul class="dropdown-menu" role="menu" aria-labelledby="dLabel">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li><a href="#">Separated link</a></li>
    </ul>
</div>

Solution 3:

$('.dropdown.keep-open').on({
    "shown.bs.dropdown": function() { this.closable = true; },
    "click":             function(e) { 
        var target = $(e.target);
        if(target.hasClass("btn-primary")) 
            this.closable = true;
        else 
           this.closable = false; 
    },
    "hide.bs.dropdown":  function() { return this.closable; }
});
body {
    margin: 10px;
}
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<script src="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/js/bootstrap.min.js"></script>
<link href="http://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet"/>
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.0.2/jquery.min.js"></script>
<h2>Click the dropdown button </h2>
<p>It will stay open unless clicked again to close </p>

<div class="dropdown keep-open">
    <!-- Dropdown Button -->
    <button id="dLabel" role="button" href="#"
       data-toggle="dropdown" data-target="#" 
       class="btn btn-primary">
        Dropdown <span class="caret"></span>
    </button>
    
    <!-- Dropdown Menu -->
    <ul class="dropdown-menu" role="menu" 
        aria-labelledby="dLabel">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
        <li class="divider"></li>
        <li><a href="#">Separated link</a></li>
    </ul>
</div>




<!-- Post Info -->
<div style='position:fixed;bottom:0;left:0;    
            background:lightgray;width:100%;'>
    About this SO Question: <a href='http://stackoverflow.com/q/19740121/1366033'>Keep dropdown menu open</a><br/>
    Fork This Skeleton Here <a href='http://jsfiddle.net/KyleMit/kcpma/'>Bootrsap 3.0 Skeleton</a><br/>
    Bootstrap Documentation: <a href='http://getbootstrap.com/javascript/#dropdowns'>Dropdowns</a><br/>
<div>

Solution 4:

I found a solution that requires no new js. Don't use a drop down and use bootstrap collapse instead. I still use some dropdown classes to style it like a dropdown.

<div class="dropdown">
    <button class="dropdown-toggle" type="button" data-toggle="collapse" data-target="#myList">Drop Down
    <span class="caret"></span></button>
    <div id="myList" class="dropdown-menu">
        <input type="checkbox" name="vehicle" value="Bike"> I have a bike<br>
        <input type="checkbox" name="vehicle" value="Car"> I have a car<br></div>

Solution 5:

I managed to use a combination of KyleMitt's solution above and ran into issues when using this within a Footable object (I believe this is due to the dynamic creation of the table). I applied .keep-open to the .dropdown .div at the top level.

$('#contact_table').on("click", '.keep-open', function () {
    this.closable = false;
});

$('#contact_table').on("shown.bs.dropdown", '.keep-open', function () {
    this.closable = true;
});
$('#contact_table').on("hide.bs.dropdown", '.keep-open', function () {
    let ret = this.closable;
    this.closable = true;
    return ret;
});

The functionality of this code allows you to click outside to close the dropdown, but clicking on items within it would maintain it being open. Please let me know if you have any suggestions/comments on this and I will attempt to edit.