67

I'm trying to open a Bootstrap dropdown when I click a item of another dropdown.

The idea is to select a city from the first drop down - then the script will auto open the second dropdown with areas (and show only areas corresponding to the chosen city).

Here is my JS:

$('#sidebar_filter_city li').click(function(){   
    $('#sidebar_filter_areas').dropdown('toggle');
});

and this is the HTML:

<div class="dropdown form-control">
   <div data-toggle="dropdown" id="sidebar_filter_cities" class="sidebar_filter_menu" data-value="jersey-city">Jersey City<span class="caret caret_sidebar"></span></div>           
   <input type="hidden" name="advanced_city" value="jersey-city">
   <ul id="sidebar_filter_city" class="dropdown-menu filter_menu" role="menu" aria-labelledby="sidebar_filter_cities">
      <li role="presentation" data-value="">All Cities</li>
      <li role="presentation" data-value="jersey-city">Jersey City</li>
      <li role="presentation" data-value="london">London</li>
      <li role="presentation" data-value="new-york">New York</li>
   </ul>        
   </div>
</div>

<div class="dropdown form-control">
    <div data-toggle="dropdown" id="sidebar_filter_areas" class="sidebar_filter_menu">All Areas<span class="caret caret_sidebar"></span> </div>           
        <input type="hidden" name="advanced_area" value="">
           <ul id="sidebar_filter_area" class="dropdown-menu filter_menu" role="menu" aria-labelledby="sidebar_filter_areas">
               <li role="presentation" data-value="">All Areas</li>
               <li role="presentation" data-value="east-harlem" data-parentcity="">East Harlem</li>
               <li role="presentation" data-value="greenville" data-parentcity="">Greenville</li>
               <li role="presentation" data-value="manhattan" data-parentcity="">Manhattan</li>
               <li role="presentation" data-value="northern-brooklyn" data-parentcity="">Northern Brooklyn</li>

                  .....
           </ul>        
        </div>    
</div>
Zanon
  • 29,231
  • 20
  • 113
  • 126
Crerem
  • 1,289
  • 2
  • 18
  • 45

20 Answers20

58

The best way is to check if the dropdown is not already open, and then to use .dropdown('toggle').

Couple things to be aware of:

  • If you want to trigger it by clicking on another element, you must kill the click event on the other element- otherwise Bootstrap will treat it as a click outside of the dropdown and immediately close it.
  • $('.dropdown').addClass('open') is not a good replacement for $('.dropdown-toggle').dropdown('toggle') as suggested in other answers, because it will cause the dropdown to stay permanently open instead of closing when you click off of the component.

HTML:

<button class="btn btn-secondary trigger_button">Trigger dropdown</button><br><br>
<div class="dropdown">
  <button class="btn btn-secondary dropdown-toggle" type="button" data-toggle="dropdown">
Dropdown
  </button>
  <div class="dropdown-menu">
  Stuff...
  </div>
</div>

JS:

$('.trigger_button').click(function(e){
  // Kill click event:
  e.stopPropagation();
  // Toggle dropdown if not already visible:
  if ($('.dropdown').find('.dropdown-menu').is(":hidden")){
    $('.dropdown-toggle').dropdown('toggle');
  }
});

Fiddle example

Yarin
  • 173,523
  • 149
  • 402
  • 512
  • 1
    This is the only answer that works for me in Twitter Bootstrap 4.0.0-beta.3 – Alex Bitek Jan 07 '18 at 21:59
  • Why didn't it occur to me?! (***If you want to trigger it by clicking on another element, you must kill the click event on the other element- otherwise Bootstrap will treat it as a click outside of the dropdown and immediately close it***) – Fr0zenFyr Jan 23 '18 at 10:26
  • 1
    You also should toggle aria-expanded attribute. – jcubic May 28 '18 at 10:37
  • About "_it will cause the dropdown to stay permanently open instead of closing when you click off of the component._". No, it doesn't. It closes the dropdown as soon as I click on any other element. – Daniyal Nasir Aug 24 '18 at 18:00
  • About "it will cause the dropdown to stay permanently open instead of closing when you click off of the component." It shows the menu but Bootstrap thinks it is still closed. If you are listening to the `show.bs.dropdown` event, it will NOT be fired using this method. I definitely recommend the accepted answer if you need to use the Bootstrap dropdown events. – cytek04 May 12 '23 at 21:35
22

For Bootstrap 3 you can just add the 'open' class to the dropdown tag. Removing it closes the dropdown.

$('.dropdown').addClass('open'); // Opens the dropdown
$('.dropdown').removeClass('open'); // Closes it

This may work in other versions, but I'm not sure.

mkandefer
  • 269
  • 2
  • 9
  • This works in Bootstrap 4. I was puzzled until I realised you have to add it to the 'dropdown-menu'
    . In native JS: document.getElementsByClassName('.dropdown-menu')[0].classList.add('show')
    – Martin CR Mar 16 '21 at 17:02
20

Bootstrap's dropdown plugin waits for 'click.bs.dropdown' event to show the menu, so in this case:

$('#sidebar_filter_areas').trigger('click.bs.dropdown');

should work. This will not trigger other 'click' events on same element if any.

Eugene
  • 3,280
  • 21
  • 17
9

dropdown('toggle') works great for me when using the button tag.

JS

$("#mybutton").dropdown('toggle')

HTML

<button class="dropdown-toggle ban" role="button" data-toggle="dropdown" data-target="#" id="mybutton">...</button>
Marcos Pérez Gude
  • 21,869
  • 4
  • 38
  • 69
mendydo
  • 99
  • 1
  • 2
  • But I do have a question. I am getting an error: Uncaught TypeError: "#button".dropdown is not a function : in the javascript console. Is this normal? – JoCoaker Jun 10 '16 at 12:52
  • open and toggle are different things. toggle might close the dropdown if it's already open – TomSawyer Jun 09 '20 at 13:08
7

You need to stop the click event from bubbling to parent elements

$('#sidebar_filter_city li').click(function(e){   
    $('#sidebar_filter_areas').dropdown('toggle');
    e.stopPropagation();
});

You can also use return false; which will do the same thing, but this will also preventDefault on the click.

Adam Lynch
  • 331
  • 2
  • 6
5

If absolutely none of them are doing the trick, then you can do something like the following:

$('.dropdown').addClass('open'); // substitute with your own selector
$('.dropdown-toggle').attr('aria-expanded', true).focus(); // substitute with your own selector

Although the above will work, I do not recommend using it as it's a bit hacky.

adamj
  • 4,672
  • 5
  • 49
  • 60
5

Something I like to use that has a bit more user-expected behavior:

if(!$('#myDropdown').hasClass('show')){
  $('#myDropdown').dropdown('toggle');
}

If it is already open, don't do anything. If it is closed, then it should open.

Reed
  • 1,515
  • 1
  • 21
  • 38
3

This works for me.

$('.dropdown-toggle').click(function (ev) {
    ev.stopPropagation();

    $(this).parent().toggleClass('open');
});

Markup:

<div class="dropdown pull-right">
    <button class="btn btn-default dropdown-toggle task-actions" type="button"
            data-toggle="dropdown" aria-haspopup="true" aria-expanded="true">
        <img src="{{ asset('img/site/icons/menu.svg') }}" alt="Menu">
    </button>
    <ul id="dropdown-overview" class="dropdown-menu">
        <li><a href="#">Action</a></li>
        <li><a href="#">Another action</a></li>
        <li><a href="#">Something else here</a></li>
        <li role="separator" class="divider"></li>
        <li><a href="#">Separated link</a></li>
    </ul>
</div>
LTroya
  • 530
  • 8
  • 23
3

just use .click() on data-toggle element but do not forget e.stopPropagation()

these one simple line took me for hours, hope it's help :)

2

If you inspect opened drop down menu you can see selector which changes display of Dropdown menu. In bootstrap v3.0.0 css selector is:

.open > .dropdown-menu {
    display: block;
}

So open class should be added to parent node of element with .dropdown-menu class. In other versions if it has been changed probably correct selector can be found in the same way.

Hamed Mahdizadeh
  • 936
  • 1
  • 15
  • 29
2

Try this:

$('#sidebar_filter_areas').click();
Paolo
  • 20,112
  • 21
  • 72
  • 113
2

According to bootstrap docs you can simply use this :

$('.dropdown-toggle').dropdown();
MajiD
  • 2,420
  • 1
  • 22
  • 32
2

For Bootstrap 4 using Anuglar 6 i used this:

<div class="dropdown-menu" id='logoutDropDownMenu' x-placement="bottom-start" style="position: absolute; transform: translate3d(0px, 40px, 0px); top: 0px; left: 0px; will-change: transform;">

My component ts file has this function

 import { DOCUMENT } from '@angular/common';
 import { Inject } from '@angular/core';

export class HomeComponent implements OnInit {

  private toggleLogout: boolean;

  constructor(@Inject(DOCUMENT) private document: any){}


 toggleButton() {
    if (this.toggleLogout) {
      this.document.getElementById('logoutDropDownMenu').classList.add('show');
    } else {
      this.document.getElementById('logoutDropDownMenu').classList.remove('show');
    }
    this.toggleLogout = !this.toggleLogout;

  }
Levijatanu
  • 371
  • 2
  • 17
1

in Bootstrap 4.x, following components need to be effected:

  • li > .nav-item .dropdown
    • a > .nav-link > aria-expanded
  • div > .dropdown-menu

Adding a click event listener, which triggers toggling a class and a bool value, for those classes make dropdown work with pure javascript as follows:

let status = false
const nav = document.getElementsByClassName('nav-item dropdown')[0]
nav.addEventListener('click', toggleDropdown)
function toggleDropdown () {
   if (status) {
      nav.classList.add('show')
      document.getElementsByClassName('nav-link dropdown-toggle')[0].setAttribute('aria-expanded', ' + status + ')
      document.getElementsByClassName('dropdown-menu').classList.add('show')
   } else {
      nav.classList.remove('show')
      document.getElementsByClassName('nav-link dropdown-toggle')[0].setAttribute('aria-expanded', ' + status + ')
      document.getElementsByClassName('dropdown-menu').classList.remove('show')
   }
   return status = !status
}
cagcak
  • 3,894
  • 2
  • 21
  • 22
1

You can achieve the same thing using Native JavaScript like this:

 document.getElementById('XYZ').click('open');

It works on all browsers.

Vivek Mehta
  • 734
  • 8
  • 10
0

most of the time act as a manual action works :

$('#sidebar_filter_city li').click(function(){   
    $('#sidebar_filter_areas').click();
});
0

Add data-toggle="dropdown" id="dropbox" in HTML like this:

<div data-toggle="dropdown" id="dropbox" 

And in JS/TS:

$('#dropbox').trigger('click.bs.dropdown');
isherwood
  • 58,414
  • 16
  • 114
  • 157
Shashwat Gupta
  • 5,071
  • 41
  • 33
0

If you don't want to use jQuery, than the plain JS variant of Dropdown.toggle() is:

# jQuery
$(elementThatTriggersDropdown).dropdown('toggle');

# js 
let dropdown = new Dropdown(elementThatTriggersDropdown);
dropdown.toggle();

Don't forget to import / make Dropdown class of bootstrap available.

https://github.com/twbs/bootstrap/blob/v5.2.0/js/src/dropdown.js

for example:

import Dropdown from "bootstrap/js/src/dropdown";
Johannes Reiners
  • 570
  • 5
  • 11
0

this is how i do it using jQuery no need to add or remove classes it’s built in bootstrap 4

$(function () {
        $('li.nav-item').hover(function () {
                $(this).children('.dropdown-menu').addClass('show')

            },
            function () {
                $(this).children('.dropdown-menu').removeClass("show");
            });
    });
-1

If you use a JS framework like AngularJS, you just need to implement your condition in JS (conditionMenuIsOpen()) and bind display styling of dropdown-menu with this condition in HTML. When condition is true, then display styling will change from hidden to block and the dropdown menu will appear.

<ul class="dropdown-menu" ng-style="vm.conditionMenuIsOpen() && {'display':'block'}">
  ...
</ul>
Stefanos Kargas
  • 10,547
  • 22
  • 76
  • 101