bootstrap multilevel dropdown menu

You can easily create multilevel dropdown menu even with bootstrap css framework, although, the framework itself has not come up with a solution of its own so far. So, here, we learn how to create a multilevel dropdown menu with bootstrap.

If you have ever inspected the html elements and tracked the changes that are made whenever a user clicks on the class dropdown on navigation item, you should be already aware that this action adds a class open to its parent li element and adds an attribute aria-expanded="true" onto itself.

You can try replcating the same effect using jQuery and make a working multilevel dropdown with bootstrap.

The only issue would be whenever you click on the dropdown class in the dropdown item, its ancestor li class would get its class open removed making the first level dropdown disappear.

So, the better option would be to give the second level menu handler a different class name. And, to position the second level dropdown menu, you better add another class.

Here's an example.

<nav class="navbar navbar-inverse">
  <ul class="nav navbar-nav text-capitalize">
    <li><a href="#">main nav</a></li>
    <li><a href="#" data-toggle="dropdown" class="dropdown">main nav <i class="caret"></i></a>
      <ul class="dropdown-menu">
        <li><a href="#">dropdown 1</a></li>
        <li><a href="#">dropdown 1</a></li>
        <li><a href="#">dropdown 1</a></li>
        <li><a href="#" class="dropdown-2">dropdown 1 <i class="caret caret-right"></i></a>
          <ul class="dropdown-menu level-2">
            <li><a href="#">dropdown 2</a></li>
            <li><a href="#">dropdown 2</a></li>
            <li><a href="#">dropdown 2</a></li>
            <li><a href="#">dropdown 2</a></li>
          </ul>
        </li>
      </ul>
    </li>
    <li><a href="#">main nav</a></li>
    <li><a href="#">main nav</a></li>
    <li><a href="#">main nav</a></li>
    <li><a href="#">main nav</a></li>
    <li><a href="#">main nav</a></li>
  </ul>
</nav>	

Now, lets make the second level dropdown appear on click of the dropdown-2 class.

<script>
$('.dropdown-2').click(function(e){
  e.stopPropagation();
  $(this).parent('li').toggleClass('open');
})
</script>

We added stopPropagation() to prevent the event from being transferred to the ancestor li where the class open is already present. If the query passes to that ancestor, then, the first level dropdown will get hidden, as, the query instructs that class to be toggled.

To make things look much better, you can add some css to your liking. Here's mine.

<style>
  @media(min-width: 768px){.caret-right{transform: rotate(-90deg);}} 
  .nav .open{position: relative;}
  .nav .open>.level-2{display: block;}
  .level-2{left: 100%;top: 0;}
</style>

Now, your second level dropdown looks perfectly working. But, if you make the second level dropdown visible and close its parent dropdown menu, then, another event trigerring that dropdown menu to open will make the child dropdown menu appear simultaneously as class open is not removed from its parent li.

Lets add a bit more code to close the child dropdown when the parent dropdown is closed.

<script>
  $('.dropdown').click(function(){
    $('.dropdown-2').parent('li').removeClass('open');
  })
</script>

We don't even need to check if its form some other siblings li or if the class is not there. Simply, adding this code means, any parent li of dropdown-2 with class open will have its class open removed on click of any dropdown class.

Hence, the issue is resolved. Now, you can add any number of dropdown menus upto any level to your liking easily by changing classnames. Make sure that you don't make it agonizing for the webpage visitors.

Now, the only problem would be to make it work on smaller screens too. While testing, you will find the link # makes it impossible to open the dropdown level 2. So, we need to add e.preventDefault() to the query to prevent it from happening.

<script>
  $('.dropdown-2').click(function(e){
    e.preventDefault();
    e.stopPropagation();
    $(this).parent('li').toggleClass('open');
  })
</script>	

One more trick up the sleeve would be to make those dropdown menus appear on hover on larger screens. You can easily do that with css, but here, we will do the same with jQuery.

<script>
  $('.nav li').hover(function(){
    $(this).toggleClass('open');
  })
</script>	

This code will work fine. The only issue is that, you'll have to double click on the dropdown class to open it on smaller screens. So, it's better to limit this code to larger screens only.

For that, we will check the width of the browser screen first. Then, if the screen is wider than 991px, we will activate the hover effect.

<script>
  var width = $(window).width();
  if(width >= 992){
    $('.nav li').hover(function(){
      $(this).toggleClass('open');
    })
  }
</script>

Everything looks great so far. But, what if the user click on the dropdown class, the effect would invert in that case right? Because the class open in already added on hover. Then, it will get closed on click. Now, if you move your mouse out of the element, the dropdown menu appears and vice-versa.

Not the effect you intended, right?

Then, why not nullify the click event in larger screens? Here's what you should do.

	
<script>
  var width = $(window).width();
  if(width > 991){
    $('.nav li').hover(function(){
      $(this).toggleClass('open');
    })
    $('.dropdown').click(function(){
      return false;
    })
    $('.dropdown-2').click(function(){
      return false;
    })	
  }else{
    $('.dropdown-2').click(function(e){
      e.preventDefault();
      e.stopPropagation();
      $(this).parent('li').toggleClass('open');
    })
  }
</script>	

Since, we have already defined dropdown-2 click event, we need to wrap that code inside else statement, so that, it only works on smaller screens.

Finally, you get your own multilevel dropdown menu with bootstrap. Enjoy!


0 Like 0 Dislike 0 Comment Share

Leave a comment