user1694077
user1694077

Reputation:

Why does this nested dropdown list script not work?

I have a script for hiding and unhiding dropdown lists. I've tried to make it work with nested lists, but it does not work. The problem is that on click of a nested dropdown, it toggles the .is-hidden class on the parent, which hides the appearing dropdown.

Here is an example: http://codepen.io/dr-potato/pen/AfIyx

I've tried to prevent the hiding of the parent with .not($(this).parent().addBack()), but apparently it does not work.

$(document).ready(function() {

  // When a dropdown trigger is clicked
  $('.Navigation-link--dropdownTrigger').click(function(e) {
    // If the selected dropdown list is not visible
    if( $(this).siblings('.Navigation-list--dropdown').hasClass('is-hidden') ){
      // Hide all dropdown lists, except the selected dropdown and its parents
      $(".Navigation-list--dropdown")
        .not($(this).parent().addBack())
        .addClass('is-hidden');
      // Make the selected dropdown visible
      $(this).siblings('.Navigation-list--dropdown')
        .removeClass('is-hidden'); 
    // If the selected dropdown is visible, hide it and its descendants
    } else {
      $(".Navigation-list--dropdown").addClass('is-hidden');
    }
  }).children('a.Navigation-link--dropdownTrigger').click(function(e){e.preventDefault();});
  // Stop clicks on navigation links from bubbling up
  $('.Navigation-link').click(function(e) {
    e.stopPropagation();
  });

});

Upvotes: 1

Views: 55

Answers (2)

timo
timo

Reputation: 2169

I had some trouble trying to understand your code so I tried to simplify it with a simple rewrite.

I believe this is the basic functionality you are after right?

In my example I'm checking if the next element has the class .is-hidden or not. If it has that class, then we want to remove it, thus showing the element. If the element is allready shown the else statement is triggered since the class is no longer in place. This statement hides the element once again.

$(document).ready(function() {  

    $('.Navigation-link--dropdownTrigger').click(function(){
      if($(this).next().hasClass('is-hidden')){
        $(this).next().removeClass('is-hidden');
      }
      else{
        $(this).next().addClass('is-hidden');
      }
    });

});

http://codepen.io/anon/pen/qLIKk

In case you would like to hide all the sub items as well, change:

$(this).next().addClass('is-hidden');

To

$(this).parent().find('ul').addClass('is-hidden');

Upvotes: 1

Me.Name
Me.Name

Reputation: 12544

In JQuery, you can also use the toggleClass function to easily switch if elements should implement a class.

 $('.Navigation-link--dropdownTrigger').click(function(e) {    
    var children = $(this).siblings('.Navigation-list--dropdown');
    children.toggleClass('is-hidden');  
  })

Upvotes: 0

Related Questions