skip to Main Content

I am following a css flex video and I am trying to build a menu with several levels. I am using jQuery to open and close a menu and sub-menu, and sub-sub-menu, etc.

Here is my demo.

  1. I click on "Contact"
  2. Then, I clik on "A propo" and "Contact" should close.
  3. I click on the first sub-menu (Item 1.2) => The first level should not close
  4. I click on the second sub-menu (Item 1.2.3) => All of this direct ul parent, should not close.
  5. Then now, when I click again to "Contact", all menu and sub-menus of "A propos" should close

My problem, I do not know how to target the first level of li.hasChildren and check all of child of other ul li.hasChildren and look for the children to close the opened menu and sub-menu.

Here is my script to close/open the selected menu, which works

( function( $ ) {

    $( '.dropdown-toggle' ).click( function( e ) {
        var _this = $( this );
        e.preventDefault();
        _this.toggleClass( 'toggled-on' );
        _this.find('.fa').toggleClass( 'fa-angle-down fa-angle-up');
        _this.parent().next( '.sub-menu' ).toggleClass( 'toggled-on' );
        _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );

         // HOW CAN I CHECK ALL OTHER MENUS
        
    } );

})( jQuery );

Above, I created a variable _this

  1. How can I check for the first li.hasChildren from _this
  2. Then how can check if there is other parent li.hasChildren up to the first level of li
  3. Then how can check all other branch of the tree to close the ul-su-menu bellow li.hasChildren, excepted for the tree that the click come from

I tried with parentUntil()

(this).parentsUntil("li.hasChildren").css( "background-color", "red" );

to mark with a class first level, but I apparently jQuery stop at the first li.hasChildren it meet, and do not continue until the first level

Note, when a menu or sub-menu is open, the ul take the class ul.toggled-on. To close a sub-menu, we can use removeClass('.toggled-on')

here is my html code

 <nav class="e-panel e-panel-row" role="navigation" aria-label="Main navigation">
    <ul class="e-justify-content-space-beween bg-black">
        <li class="hasChildren">
            <div>
                <a href="#">A propo</a>
                <a href="#" class="dropdown-toggle" aria-expanded="false">
                    [12]
                    <i class="fa fa-angle-down"></i>
                </a>
            </div>
        
            <ul class="sub-menu" role="group">
                <li>
                    <div>
                        <a class="link" href="#">Item 1.1</a>
                    </div>
                </li>
                <li class="hasChildren">

                    <div>
                        <a href="#" class="link">Item 1.2</a>
                        <a href="#" class="dropdown-toggle" aria-expanded="false">
                            [1]
                            <i class="fa fa-angle-down"></i>
                        </a>
                    </div>
                    
                    <ul class="sub-menu" role="group">
                        <li>
                            <div>
                                <a href="#">Item 1.2.1</a>
                            </div>
                        </li>
                        <li>
                            <div>
                                <a href="#">Item 1.2.2</a>
                            </div>
                        </li>
                        <li class="hasChildren">
                            <div>
                                <a href="#">Item 1.2.3</a>
                                <a href="#" class="dropdown-toggle" aria-expanded="false">
                                    [1]
                                    <i class="fa fa-angle-down"></i>
                                </a>
                            </div>
                            <ul class="sub-menu">
                                <li><div><a href="#">Item 1.2.3.1</a></div></li>
                                <li><div><a href="#">Item 1.2.3.2</a></div></li>
                                <li><div><a href="#">Item 1.2.3.3</a></div></li>
                            </ul>
                        </li>
                    </ul>
                </li>
                <li>
                    <div>
                    <a href="#">Item 333333</a>
                    </div>
                </li>
            </ul>
        </li>    
                     
        <li>
            <div>
                <a href="#">Team</a>
            </div>
        </li>
        <li class="hasChildren">
            <div>
                <a href="#" class="link">Contact</a>
                <a href="#" class="dropdown-toggle" aria-expanded="false">
                            [13]
                    <i class="fa fa-angle-down"></i>
                </a>
            </div>
                    
            <ul class="sub-menu" role="group">
                <li>
                    <div>
                        <a href="#">Adresse</a>
                    </div>
                </li>
                <li>
                    <div>
                        <a href="#">Téléphone</a>
                        </div>
                    </li>
                <li>
                    <div>
                        <a href="#">e-mail</a>
                    </div>
                </li>
            </ul>
        </li>
        <li>
            <div>
                <a href="#">Nos cours</a>
            </div>
        </li>
        <li>
            <div>
                <a href="#">Menu 3</a>
            </div>
        </li>
        <li>
            <div>
                <a href="#">Encore un beau menu 4</a>
            </div>
        </li>
        <li>
            <div>
                <a href="#">Contact</a>
            </div>
        </li>
    </ul>
</nav>

Then my question is, how can I check all ul.toggled-on, which does not belong of the branch where I clicked

Many thanks

2

Answers


  1. Chosen as BEST ANSWER

    I finally found a solution as the following

    ( function( $ ) {
    
        $( '.dropdown-toggle' ).click( function( e ) {
            e.preventDefault();
            
            //console.log( e + ": " + $( this ).siblings('a').text() );
    
            // Add or remove the toggled-on class and change the aria-expand status of the link
            $(this).toggleClass('toggled-on').attr('aria-expanded',$(this).attr('aria-expanded') === 'false' ? 'true' : 'false')
            .find('.fa').toggleClass('fa-angle-down fa-angle-up')
            // find the closest parent div and go to the first ul.sub-menu, then add/remove the class toggled-on to the ué
            .closest('div').eq(0).next('ul').toggleClass('toggled-on')
            // Go up to the closest hasChildren class and look at all system/brother of .hasChildren
            .closest('.hasChildren').eq(0).siblings(".hasChildren")
            // Find .dropdown-toggle and do a forwach for all of them
            .find('.dropdown-toggle').each(function(){
                $('#breadcrumb').text('');
                //$(this).css("background-color", "blue");
                // remove the toggled-on class and change the axia-expanded status of each links
                $(this).removeClass('toggled-on').attr('aria-expanded','false')
                // change the icon
                .find('.fa').removeClass('fa-angle-up').addClass('fa-angle-down')
                // move up to the closest div and go to the next ul (ul.sub-menu) and remove the toggled-on class to close the menu
                .closest('div').eq(0).next('ul').removeClass('toggled-on');
            });
    
            $('#breadcrumb').append(' / ' + $( this ).siblings('a').text());
    
        } );
    
    })( jQuery );
    

    I hope, you will like it


  2. You can set a class active for the last click on your menus.

    Like this, you can do a loop with each() and check for unactive menu.

    I commented my code.

    ( function( $ ) {
    
        $( '.dropdown-toggle' ).click( function( e ) {
            $( '.dropdown-toggle' ).removeClass('active');
            
            var _this = $( this );
            e.preventDefault();
            _this.toggleClass( 'toggled-on' );
            _this.find('.fa').toggleClass( 'fa-angle-down fa-angle-up');
            _this.parent().next( '.sub-menu' ).toggleClass( 'toggled-on' );
            _this.attr( 'aria-expanded', _this.attr( 'aria-expanded' ) === 'false' ? 'true' : 'false' );
            _this.addClass( 'active' );
    
            // check if link has submenu
            var checkIfSubMenu = _this.parent('div:first').nextAll('ul.sub-menu:first');
            //console.log(checkIfSubMenu.length);
      
            // check for inactive toogled menu
            var checkIfNotActiveSubMenu = $( 'a.toggled-on:not(.active)' );
            //console.log(checkIfNotActiveSubMenu.length);
            
            // close inactive menu
            $('.toggled-on').each(function() {
              // we get the link in the previous div and check if the link dont have class active 
              if (!$(this).prevAll('div:first').find('.dropdown-toggle').hasClass('active')) {
                // so we remove class for the submenu
                $(this).removeClass('toggled-on');
              }
            });
    
            // HOW CAN I CHECK ALL OTHER MENUS
            
        } );
        
        $( '.e-panel ul li div a:not(.dropdown-toggle, .link)' ).click( function( e ) {
          $('.toggled-on').removeClass('toggled-on');
        });
    })( jQuery );
    .bg-black{
        background-color: black;
        color: white;
    }
    .bg-black a{
        color: white;
        text-decoration: none;  
    }
    .bg-black li:hover{
    
        color: white;
        text-decoration: none;  
    }
    
    .red{
        border: 4px solid #ff22ff;
    }
    
    /* GENERAL */
    /* ul li */
    i{
        width: 8px;
    }
    
    /* First level */
    nav.e-panel-row ul{
        margin: 0 auto;
        list-style: none;
        box-sizing: border-box;
        padding: 0px;
        display: flex;
        flex-wrap: wrap;
        flex-direction: row;
        justify-content: space-between;
        border: 1px solid red;
    
    }
    
    nav.e-panel-row ul li{
        
        font-size: 1em;
        /*border: solid 3px red !important;*/
        position: relative;
        flex: 1 0 auto;
    }
    
    nav.e-panel-row ul li div{
        padding: 10px;
    }
    
    /* hasChildren */
    
    nav.e-panel-row  ul li.hasChildren{
    
    }
    nav.e-panel-row  ul li.hasChildren ul.sub-menu{
        display: none;
        border: 1px solid green;
        position: absolute;
        z-index: 1000;
        background-color: #666;
        width: 100%;
    
    }
    nav.e-panel-row ul li.hasChildren ul.sub-menu.toggled-on{
        display: flex;
        flex-wrap: wrap;
        flex-direction: column;
        box-sizing: border-box;
        border: 1px solid red;
    }
    
    nav.e-panel-row  ul li.hasChildren ul.sub-menu.toggled-on li{
        flex: 1 1 auto;
        
    }
    nav.e-panel-row  ul li.hasChildren ul.sub-menu.toggled-on li.hasChildren ul.sub-menu{
        position: relative;
        
    }
    
    nav.e-panel-row ul li:hover, section.e-panel-row nav ul li:hover,
        background-color: #333333;
    }
    
    .toggle-on{display:inline-block}
    .sub-menu{display:none}
    .sub-menu.toggled-on{display:block}
    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
    
        <section class="container">
            <div class="container">
                <h2>Row</h2>
            </div>
    
            <nav class="e-panel e-panel-row" aria-label="Main navigation">
    
                <ul class="e-justify-content-space-beween bg-black">
    
                    <li class="hasChildren">
                        <div>
                            <a href="#">A propo</a>
                            <a href="#" class="dropdown-toggle" aria-expanded="false">
                                [12]
                                <i class="fa fa-angle-down"></i>
                            </a>
                        </div>
                    
                        <ul class="sub-menu" role="group">
                            <li>
                                <div>
                                    <a class="link" href="#">Item 1.1</a>
                                </div>
                            </li>
                            <li class="hasChildren">
    
                                <div>
                                    <a href="#" class="link">Item 1.2</a>
                                    <a href="#" class="dropdown-toggle" aria-expanded="false">
                                        [1]
                                        <i class="fa fa-angle-down"></i>
                                    </a>
                                </div>
                                
                                <ul class="sub-menu" role="group">
                                    <li>
                                        <div>
                                            <a href="#" class="link">Item 1.2.1</a>
                                        </div>
                                    </li>
                                    <li>
                                        <div>
                                            <a href="#" class="link">Item 1.2.2</a>
                                        </div>
                                    </li>
                                    <li class="hasChildren">
                                        <div>
                                            <a href="#">Item 1.2.3</a>
                                            <a href="#" class="dropdown-toggle" aria-expanded="false">
                                                [1]
                                                <i class="fa fa-angle-down"></i>
                                            </a>
                                        </div>
                                        <ul class="sub-menu">
                                            <li><div><a href="#" class="link">Item 1.2.3.1</a></div></li>
                                            <li><div><a href="#" class="link">Item 1.2.3.2</a></div></li>
                                            <li><div><a href="#" class="link">Item 1.2.3.3</a></div></li>
                                        </ul>
                                    </li>
                                </ul>
                            </li>
                            <li>
                                <div>
                                <a href="#" class="link">Item 333333</a>
                                </div>
                            </li>
                        </ul>
                    </li>    
                                 
                    <li class="hasChildren">
                        <div>
                            <a href="#" class="link">Team</a>
                            <a href="#" class="dropdown-toggle" aria-expanded="false">
                                        [3]
                                <i class="fa fa-angle-down"></i>
                            </a>
                        </div>
                        <ul class="sub-menu" role="group">
                            <li>
                                <div>
                                    <a href="#" class="link">Direction</a>
                                </div>
                            </li>
                            <li>
                                <div>
                                    <a href="#" class="link">Secrétaires</a>
                                    </div>
                                </li>
                            <li>
                                <div>
                                    <a href="#" class="link">Collaborateurs</a>
                                </div>
                            </li>
                        </ul>
                    </li>
    
                    <li class="hasChildren">
                        <div>
                            <a href="#" class="link">Contact</a>
                            <a href="#" class="dropdown-toggle" aria-expanded="false">
                                        [13]
                                <i class="fa fa-angle-down"></i>
                            </a>
                        </div>
                                
                        <ul class="sub-menu" role="group">
                            <li>
                                <div>
                                    <a href="#" class="link">Adresse</a>
                                </div>
                            </li>
                            <li>
                                <div>
                                    <a href="#" class="link">Téléphone</a>
                                    </div>
                                </li>
                            <li>
                                <div>
                                    <a href="#" class="link">e-mail</a>
                                </div>
                            </li>
                        </ul>
                    </li>
                    <li class="hasChildren">
                        <div>
                            <a href="#" class="link">Nous cours</a>
                            <a href="#" class="dropdown-toggle" aria-expanded="false">
                                        [3]
                                <i class="fa fa-angle-down"></i>
                            </a>
                        </div>
                         <ul class="sub-menu" role="group">
                            <li>
                                <div>
                                    <a href="#" class="link">CSS</a>
                                </div>
                            </li>
                            <li>
                                <div>
                                    <a href="#" class="link">Django</a>
                                    </div>
                                </li>
                            <li>
                                <div>
                                    <a href="#" class="link">React</a>
                                </div>
                            </li>
                        </ul>
                    </li>
                    <li>
                        <div>
                            <a href="#">Menu 3</a>
                        </div>
                    </li>
                    <li>
                        <div>
                            <a href="#">Encore un beau menu 4</a>
                        </div>
                    </li>
                    <li>
                        <div>
                            <a href="#">Contact</a>
                        </div>
                    </li>
                </ul>
            </nav>
        </section>
    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search