46

I have a button dropdown (just one, not all of them), and inside of it, I want to have several input field where people can type stuff inside without the dropdown hiding as soon as you click on it (but it does close if you click outside of it).

I created a jsfiddle: http://jsfiddle.net/denislexic/8afrw/2/

And here is the code, it's basic:

<div class="btn-group" style="margin-left:20px;">
  <a class="btn dropdown-toggle" data-toggle="dropdown" href="#">
    Action
    <span class="caret"></span>
  </a>
  <ul class="dropdown-menu">
    <!-- dropdown menu links -->
      <li>Email<input type="text" place-holder="Type here" /></li>
      <li>Password<input type="text" place-holder="Type here" /></li>
  </ul>
</div>​

So basically, I want it to not close on click of the dropdown (but close on click of the action button or outside the dropdown). My best guess so far was to add a class to it and try to do some JS, but I couldn't figure it out.

Thanks for any help.

isherwood
  • 58,414
  • 16
  • 114
  • 157
denislexic
  • 10,786
  • 23
  • 84
  • 128

7 Answers7

112

The issue is that the boostrap dropdown jQuery plugin closes the dropped-menu when you click anywhere else. You can disable that behavior by capturing the click events on your dropdown-menu element and keeping it from reaching the click event listeners on the body element.

Just add

$('.dropdown-menu').click(function(event){
     event.stopPropagation();
 });​

jsfiddle can be found here

CraigTeegarden
  • 8,173
  • 8
  • 38
  • 43
  • 2
    Amazing, I tweaked it a bit because I just need some dropdowns not to do the normal behavior, by adding a class to it, and checking it in your code...see fiddle if interested. http://jsfiddle.net/denislexic/8afrw/8/ – denislexic Jul 24 '12 at 11:04
  • 2
    You can also only block clicks on a specific class, so you leave alone the normal dropdowns. [js fiddle here](http://jsfiddle.net/8afrw/9/) – CraigTeegarden Jul 24 '12 at 15:08
  • This is a good answer. Used it, but ran into a problem. For those with some extra time on their hands, might be interesting to read this article: http://css-tricks.com/dangers-stopping-event-propagation/ – yaserso Jan 03 '15 at 20:22
  • Better answer if you want to handle click events on the children in the dropdown http://stackoverflow.com/questions/25089297/twitter-bootstrap-avoid-dropdown-menu-close-on-click-inside#answer-25196101 – Fatmuemoo Apr 24 '15 at 17:08
  • If you want to disable all auto closing of the dropdown you can just disable the listener. $('html').off('click.dropdown') – Amr Hossam Jun 11 '15 at 19:23
  • but my href have #archor, How can I prevent it added in to url? – huykon225 Jan 15 '18 at 03:50
39

I know this question isn't for Angular per se, but for anyone using Angular you can pass the event from the HTML and stop propagation via $event:

<div ng-click="$event.stopPropagation();">
    <span>Content example</span>
</div>
EpokK
  • 38,062
  • 9
  • 61
  • 69
parliament
  • 21,544
  • 38
  • 148
  • 238
5

Actually, if you were in Angular.js, it would be more elegant to make a directive for it:

app.directive('stopClickPropagation', function() {
    return {
        restrict: 'A',
        link: function(scope, element) {
            element.click(function(e) {
                e.stopPropagation();
            });
        }
    };
});

And then, on the dropdown-menu, add the directive:

<div class="dropdown-menu" stop-click-propagation> 
    my dropdown content...
<div>

Especially if you want to stop propagation for multiple mouse events:

...
element.click(function(e) {
    e.stopPropagation();
});

element.mousedown(...
element.mouseup(...
...
Nahn
  • 3,196
  • 1
  • 24
  • 23
5

Another quick solution, just add onclick attribute to div having class dropdown-menu:

<div class="dropdown-menu" onClick="event.stopPropagation();">...</div>
Remi Guan
  • 21,506
  • 17
  • 64
  • 87
Hassan Talha
  • 69
  • 1
  • 3
1

After trying a lot of techniques I found that the best one to use, that causes no drawbacks which is even simple:

$(document)
.on( 'click', '.dropdown-menu', function (e){
    e.stopPropagation();
});

Which lets you also do some live binding for inner elements inside dropdowns.

Monkey Monk
  • 984
  • 9
  • 19
Julian Xhokaxhiu
  • 503
  • 4
  • 11
0

also, prevent click unless clicks a button element

$('.dropdown-menu').click(function(e) {
    if (e.target.nodeName !== 'BUTTON') e.stopPropagation();
});
Elise Chant
  • 5,048
  • 3
  • 29
  • 36
0

I had this issue but in a react component - the react component was in a bootstrap dropdown menu with a form. Every time an element inside the dropdown was clicked it would close, causing issues inputting anything in the form.

The usual e.preventDefault() and e.stopPropagation() would not work in the react app due to the jquery event being fired immediately and react trying to intervene after this.

The below code allowed me to fix my issue.

stopPropagation: function(e){
    e.nativeEvent.stopImmediatePropagation();
}

or in ES6 format

stopPropagation(e){
    e.nativeEvent.stopImmediatePropagation();
}

Hope this can be of use to anyone struggling with the other answers when trying to use it in react.

Sprose
  • 1,255
  • 1
  • 16
  • 20