user3265000
user3265000

Reputation:

jQuery multilevel submenu

Ok this might be pretty simple but can’t make it…

What i want to make is a sub menu with multilevel support

Right now step by step:

  1. hide all “li” with “ul”

  2. Show subnav by adding Class “Show-subnav” to the li > ul when it is clicked

Problem: All the clicked li > ul remain open

How can i make the previously clicked subnav’s close?

Ex: When you click Item1 it show Item1 > Level 1 subnav but remains open even after clicking Item 2 subnav. Item1 should close when you click Item 2.

feel free to edit this pen

$(document).ready(function() {

  // Toggle Sub Nav
  $("#nav li:has(ul)").children("ul").hide(); // hide the li UL
  $("#nav li:has(ul)").find("a").click(function() {
    // Add .show-subnav class to revele on click
    $(this).parent().find("ul:first").toggleClass("show-subnav");
    // how to hide previously clicked submenus?
  });

});
#nav .show-subnav {
  display: block!important;
}
<!-- Nav primary start  -->
<nav id="nav">
  <ul>
    <li><a href="#">Item 1 Submenu</a>
      <ul>
        <li><a href="#">Level 1 Submenu</a>
          <ul>
            <li><a href="#">Level 2 </a>
            </li>
            <li><a href="">Level 2 </a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="#">Level 2</a>
            </li>
          </ul>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#">Item 2 Submenu</a>
      <ul>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#section-3">Link 3</a>
    </li>
    <li><a href="#section-4">Link 4</a>
    </li>
    <li><a href="#section-5">Link 5</a>
    </li>
  </ul>
</nav>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 2

Views: 4876

Answers (4)

Dipesh Rana
Dipesh Rana

Reputation: 367

$(document).ready(function() {
$('#nav li a').click(function(e){
if($(this).hasClass('clicked')){
$(this).removeClass('clicked').next('ul').slideUp(500);
}
else if($(this).parents().siblings('a').hasClass('clicked')){
$('.clicked').slideDown();
$(this).addClass('clicked').next('ul').slideDown(500);	
}
else{
$('#nav li a').removeClass('clicked').next('ul').slideUp(500);
$(this).addClass('clicked').next('ul').slideDown(500);	
}
})
	
});
#nav .show-subnav {
  display: block;
}
#nav li > ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Nav primary start  -->
<nav id="nav">
  <ul>
    <li><a href="#">Item 1 Submenu</a>
      <ul>
        <li><a href="#">Level 1 Submenu</a>
          <ul>
            <li><a href="#">Level 2 </a>
            </li>
            <li><a href="">Level 2 </a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="#">Level 2</a>
            </li>
          </ul>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#">Item 2 Submenu</a>
      <ul>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#section-3">Link 3</a>
    </li>
    <li><a href="#section-4">Link 4</a>
    </li>
    <li><a href="#section-5">Link 5</a>
    </li>
  </ul>
</nav>

Upvotes: 0

Arun P Johny
Arun P Johny

Reputation: 388436

Remove the open class from sub ul elements

$(document).ready(function() {
  $("#nav li:has(ul) > a").click(function() {
    var $ul = $(this).next("ul").toggleClass("show-subnav");
    $ul.find('ul.show-subnav').removeClass('show-subnav');
    $('#nav ul.show-subnav').not($ul.parentsUntil('#nav', 'ul').add($ul)).removeClass('show-subnav')
  });
});
#nav .show-subnav {
  display: block;
}
#nav li > ul {
  display: none;
}
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<!-- Nav primary start  -->
<nav id="nav">
  <ul>
    <li><a href="#">Item 1 Submenu</a>
      <ul>
        <li><a href="#">Level 1 Submenu</a>
          <ul>
            <li><a href="#">Level 2 </a>
            </li>
            <li><a href="">Level 2 </a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="#">Level 2</a>
            </li>
          </ul>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#">Item 2 Submenu</a>
      <ul>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#section-3">Link 3</a>
    </li>
    <li><a href="#section-4">Link 4</a>
    </li>
    <li><a href="#section-5">Link 5</a>
    </li>
  </ul>
</nav>

Upvotes: 2

Omer S
Omer S

Reputation: 81

Here is one way to do it. You could also use the .children() approach instead of the parent.

$(document).ready(function() {

  // Toggle Sub Nav
  $("#nav li:has(ul)").children("ul").hide(); // hide the li UL
  $("#nav li:has(ul)").find("a").click(function(e) {
    // Add .show-subnav class to revele on click
    var $clicked = $(this),
        theClass = 'show-subnav';
    
    $('.'+theClass).each(function(i,v) {//iterate all the opened uls
      if (!$clicked.parents('.'+ theClass).length == 1) {//check if clicked element has a ul with the opened Css Class, and remove that class if condition fails
        $(v).removeClass(theClass);
      }
    });
    $(this).parent().find("ul:first").toggleClass(theClass);
    // how to hide previously clicked submenus?
  });

});
#nav .show-subnav {
  display: block!important;
}
<!-- Nav primary start  -->
<nav id="nav">
  <ul>
    <li><a href="#">Item 1 Submenu</a>
      <ul>
        <li><a href="#">Level 1 Submenu</a>
          <ul>
            <li><a href="#">Level 2 </a>
            </li>
            <li><a href="">Level 2 </a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="#">Level 2</a>
            </li>
          </ul>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#">Item 2 Submenu</a>
      <ul>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#section-3">Link 3</a>
    </li>
    <li><a href="#section-4">Link 4</a>
    </li>
    <li><a href="#section-5">Link 5</a>
    </li>
  </ul>
</nav>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

Shaunak D
Shaunak D

Reputation: 20646

Use .removeClass() to remove already open ul

$(document).ready(function() {

  // Toggle Sub Nav
  $("#nav li:has(ul)").children("ul").hide(); // hide the li UL
  $("#nav li:has(ul)").find("a").click(function() {
    var parent = $(this).parent()
    parent.siblings().find("ul.show-subnav").removeClass("show-subnav");
    parent.find("ul:first").toggleClass("show-subnav");
  });

});

$(document).ready(function() {

  // Toggle Sub Nav
  $("#nav li:has(ul)").children("ul").hide(); // hide the li UL
  $("#nav li:has(ul)").find("a").click(function() {
    // Add .show-subnav class to revele on click
    var parent = $(this).parent()
    parent.siblings().find("ul.show-subnav").removeClass("show-subnav");
    parent.find("ul:first").toggleClass("show-subnav");
    // how to hide previously clicked submenus?
  });

});
#nav .show-subnav {
  display: block!important;
}
<!-- Nav primary start  -->
<nav id="nav">
  <ul>
    <li><a href="#">Item 1 Submenu</a>
      <ul>
        <li><a href="#">Level 1 Submenu</a>
          <ul>
            <li><a href="#">Level 2 </a>
            </li>
            <li><a href="">Level 2 </a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="">Level 2</a>
            </li>
            <li><a href="#">Level 2</a>
            </li>
          </ul>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#">Item 2 Submenu</a>
      <ul>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
        <li><a href="#">Level 1 </a>
        </li>
      </ul>
    </li>
    <li><a href="#section-3">Link 3</a>
    </li>
    <li><a href="#section-4">Link 4</a>
    </li>
    <li><a href="#section-5">Link 5</a>
    </li>
  </ul>
</nav>

<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>

Upvotes: 1

Related Questions