How to add a submenu toggle button inside all "li" elements that have a submenu?

I'm building a mobile navigation menu. I wan't the menu to work like this:

In this image you see a mobile nav with multiple depth levels.

This is how I wan't the code structure to look like:

ul
    li/li
    li class="menu-item-has-children"
        div class="toggle-button"/div
        a href=""/a
        ul class="submenu"
            li/li
            li class="menu-item-has-children"
                div class="toggle-button"/div
                a href=""/a
                ul class="submenu"/ul
            /li
        /ul
    /li
/ul

You can see a menu item "Products" with children that are hidden.

Below you see "Industries". Here the children are shown when the toggle button to the right is clicked. The children of the next submenu level can also be toggled and so on.

I'm outputting all menu items with 'depth' = '0', and now I wan't submenus to be expandable.

To do this I need to add a toggle HTML element (see the code structure above) for which I can use jQuery to toggle an "active" class on the parent element, which then reveals the children.

My question

How can I add this toggle element inside all li elements, that have children, for all depth levels?

I think I need to filter wp_nav_menu or add a custom walker function, but I'm not sure how.

Topic walker sub-menu navigation mobile menus Wordpress

Category Web


I managed to solve this:

Create the function

So I created a new custom walker function in functions.php and copied all the code of the core wp nav walker function (wp-includes/class-walker-nav-menu.php).

Check for a menu item that has children

I then added this array_search in public function start_el to check if the parent element has the class "menu-item-has-children":

$has_children = array_search ( 'menu-item-has-children' , $classes );

Output the toggle button

I then output the collapse element at the end of the start_el function if $has_children is true:

if($has_children != false) :
    $item_output .= '<div class="toggle-button"></div>';
endif;

Making it all work

I then added jQuery to toggle a class on the parent element of the toggle button.

jQuery(".toggle-button").click( function (){
    $(this).parent().toggleClass("menu-collapsed");
});

This works perfectly, but is there a better way to check if the menu item has children? Searching for a class name just doesn't feel like the best solution.

About

Geeks Mental is a community that publishes articles and tutorials about Web, Android, Data Science, new techniques and Linux security.