0

Getting a little headache with jQuery in my attempt to add a toggle button to each element that contains a specific class. As i use jQuery's .each( , i was hoping to do it at the loop i add my identifier class. But somehow it keeps append my html code in a loop to each li instead of the li.has-children

This is my current code:

    function addLevelClass($parent, level) {
      // fetch all the li's that are direct children of the ul
      var $children = $parent.children('li');
      // loop trough each li
      $children.each(function() {
        // get the ul that is a direct child of the li
        var $sublist = $(this).children('ul');
        // if an ul was found
        if ($sublist.length > 0) {
          $sublist.addClass('slideable-submenu');
          // add a class to the current li indicating there is a sub list
          $(this).addClass('has-children level-'+level);


          //last attempt before ask on SO
          if( $(this).hasClass('has-children level-'+level) ){
            $( 'li.has-children span a' ).after( '<span class="sub-menu-toggle"></span>');
          }

          // repeat the process for the sublist, but with the level one higher
          // = recursive function call
          addLevelClass($sublist, level+1);
        }
      });
    }

    // call the function to add level classes on the upper most ul
    addLevelClass($('.header-mobile-menu'), 0);
    //$( 'li.has-children span a' ).after( '<span class="sub-menu-toggle"></span>');//Adds toggle buttons everywhere

So the idea is to get:

$( 'li.has-children span a' ).after( '<span class="sub-menu-toggle"></span>');

In it's correct position.

2
  • 1
    Can you post markup? Also you don't need if( $(this).hasClass('has-children level-'+level) ) as it's always going to be true Commented Jun 25, 2019 at 16:28
  • @SeanT , thanks for your help attempt (the fiddle was a pain and the answer came quicker). I did so many attempts like: find('a') but should have been find('span:first'). We keep learning. Commented Jun 25, 2019 at 17:08

1 Answer 1

1

If I understand correctly you're trying to add a toggle button with each <li> that has a sub menu.

If so, I created a fiddle with some generic markup that might be helpful.

The only real change I made was how the toggle button is appended and I removed the recursive call back to itself.

Here is the updated code:

function addLevelClass($parent, level) {

      // fetch all the li's that are direct children of the ul
      var $children = $parent.children('li');

      // loop trough each li
      // here I added a check if level is defined, if not set it to 0, this way you don't have to pass it a value unless you want to start it somewhere
      var level = (typeof(level) !== 'undefined') ? level : 0;
      $children.each(function() {
        // get the ul that is a direct child of the li
        var $sublist = $(this).children('ul');
        // if an ul was found
        if ($sublist.length > 0) {


          $sublist.addClass('slideable-submenu');

          // add a class to the current li indicating there is a sub list
          $(this).addClass('has-children level-'+level).find('span:first').append( '<span class="sub-menu-toggle">toggle</span>');

          // increment level
          level++;

        }
      });
    }

    // call the function to add level classes on the upper most ul
    addLevelClass($('#parent ul'));
    //$( 'li.has-children span a' ).after( '<span class="sub-menu-toggle"></span>');//Adds toggle buttons everywhere
Sign up to request clarification or add additional context in comments.

3 Comments

It works if i keep the recursive call, seems al i needed was: $(this).addClass('has-children level-'+level).find('span:first').append( '<span class="sub-menu-toggle">toggle</span>');
Reason i have to keep the recursive call is that it is a multi-level-menu generated via php. Good job!!! answer accepted.
I'm glad to have helped!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.