1

I'm trying to create a nav menu with a clickable dropdown function but minimize scripting at the same time, so I found out a way to achieve this with an invisible input box and CSS. My only problem is I have no experience with PHP and getting the menu to load the right HTML is very frustrating (it took me forever just to get the custom walker to show up in the first place). This is the effect I want to achieve - the same default WordPress menu, but the menu items with children are slightly different:

<ul>
    <li>A menu item</li>
    <li>A menu item</li>
    <li>
    <input id="check-(item-id)" type="checkbox" />
    <label for="check-(item-id)">A menu item with children</label>
        <ul>
            <li>Child one</li>
            <li>Child two</li>
    </li>
    <li>A menu item</li>
</ul>

In my functions.php file, I have this:

<?php
/*---- Custom Menu Settings ----*/
function custom_menus() {
    $locations = array(
        "top-menu" => __( "Top Menu" ),
        "side-menu" => __( "Side Menu" ),
       );

    register_nav_menus( $locations );
    }

add_action( "init", "custom_menus" );

class Clickable_Dropdown_Walker extends Walker_Nav_Menu {
    // The code isn't even worth showing because I've tried at least a dozen combinations and nothing's worked
    }
?>

And finally, in my sidebar.php I have this:

<?php
if ( has_nav_menu( "side-menu" ) ) {
    wp_nav_menu( array( 
        "theme_location" => "side-menu", 
        "container_class" => "side-menu",
        "walker" => new Clickable_Dropdown_Walker() ) );
    }
?>

Any help would be appreciated, thanks!

2 Answers 2

1

I did this in my theme, so you can look at the whole code here: https://wordpress.org/themes/twenty8teen

I used the standard walker and added a filter for 'walker_nav_menu_start_el'. Of course, I also wanted it to work for the fallback Page menu, so I cloned the standard walker and added the call to apply_filters with a slightly different filter.

/**
 * For custom menu, adding an input and label for submenus.
 */
function twenty8teen_nav_menu_start_el( $item_output, $item, $depth, $args ) {
    $classes = empty( $item->classes ) ? array() : (array) $item->classes;
    if ( $classes && in_array( 'menu-item-has-children', $classes ) ||
        in_array( 'page_item_has_children', $classes) ) {
        $item_output .= '<input type="checkbox" id="sub' . $item->ID
            . '"><label for="sub' . $item->ID . '"></label>';
    }
    return $item_output;
}

/**
 * For page menu, adding an input and label for submenus.
 */
function twenty8teen_page_menu_start_el( $item_output, $page, $depth, $args ) {
    if ( isset( $args['pages_with_children'][ $page->ID ] ) ) {
        $item_output .= '<input type="checkbox" id="sub' . $page->ID
            . '"><label for="sub' . $page->ID . '"></label>';
    }
    return $item_output;
}
add_filter( 'walker_page_menu_start_el', 'twenty8teen_page_menu_start_el', 9, 4);
2
  • I'm trying to try your method but no matter what I do the custom walker/function won't output any html at all, even if I remove the custom walker work and try just rendering the menu. I haven't changed anything except the functions.php and sidebar.php and I'm working in a local environment. Have you experienced this before? Commented Jun 26, 2019 at 10:29
  • I found out my problem, my side menu wasn't being assigned automatically. Working now! Commented Jun 26, 2019 at 10:37
0

I managed to use what you did and other resources to come up with my own solution! The code is short and sweet:

class Clickable_Dropdown_Walker extends Walker_Nav_Menu {
    function start_el( &$output, $item, $item_output, $depth = 0, $args = array() ) {
        if( in_array( 'menu-item-has-children', $item->classes ) ){
            $output .= '<li class="menu-item-has-children"><input id="check-' . $item->ID . '" type="checkbox" />'
                    . '<label for="check-' . $item->ID . '">' . $item->title . '</label>';
            }

        else {
            $output .= '<li><a href="' . $item->url . '">' . $item->title . '</a>';
            }
        }
    }

I had to make sure the walker was enabled in my custom menu and the menu in the WP Admin was assigned to "Side Menu."

Thanks for your help!!

Your Answer

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

Not the answer you're looking for? Browse other questions tagged or ask your own question.