Submenu dropdown "on click" instead of "on hover"


I have a use case in which (almost) all of the main navigation menu items have subitems, but where those top level items do not have landing pages associated with them - all content is accessed via the subitems. I would like the user to be able to click on the top level item to see the submenu dropdown.

The default Beans behavior, however, is that the dropdown drops "on hover" instead of "on click". This is a major problem, as users with touch devices that are wide enough not to trigger the hamburger menu breakpoint (like many tablets in landscape orientation) cannot navigate the site, since they can't hover...

I implemented the code here (deleting the beans_get( 'beans_type', $args ) === 'offcanvas' clause, since I want that behavior in both wide screen and off-canvas modes). Off-canvas works exactly as expected, but not on wide screens: dropdowns only appear "on hover".

I discovered that uikit has a data-uk-dropdown attribute, so I tried using

beans_add_attribute('beans_menu_item', 'data-uk-dropdown', "{mode:'click'}");

This works great on wide screen, but it breaks the off-canvas menu (submenus no longer appear on click).

Is there any way to get "on click" behavior for both off-canvas and "regular" wide screen drop down navigation?


Hope I'm not too late to jump in here.

I'm building a UIKit megamenu and am running into kind-of-similar issues. Are you getting an error in your console that says something like "Cannot read property 'focus' of undefined"?


I sure hope it's not too late, as I still haven't resolved this issue...

I don't see any errors, unfortunately (as that might help in debugging...)

Actually, I just tested it again, and it seems to be almost working now, though I have no idea what I changed to make this happen. Now, the off-canvas works "on click", but on wide-screen touch devices I have to "click" twice for the submenu to appear.

Very puzzling.


I had that too. If I recall, it had something to do with adding the class uk-open not being added on the click event.

How are you handling the non-linking parent menu items? I'm assuming it's something like setting the href to # and adding preventDefault to the event in jQuery?

If you could share a link to your site, I don't mind taking a look.


I'm doing it server-side (not with jQuery) using a minor modification of the method described in https://community.getbeans.io/discussion/offcanvas-menu/#post-558

My code (in my subtheme's functions.php) looks like this:

add_filter( 'beans_menu_item_link_attributes', 'example_modify_menu_link_attributes', 10, 4 );

function example_modify_menu_link_attributes( $attributes, $item, $depth, $args ) {
    // Replace href with # if the menu type is offcanvas and the menu item has children.
    if ( beans_get( 'has_children', beans_get( 'walker', $args ) ) ) {
        $attributes['href'] = '#';
    }

    return $attributes;
}

I'm building the site for a client, and since it's not ready for release, I unfortunately can't share it...

And I really have no real understanding of that php code, since the beans_get() function is not really documented in any useful manner anywhere that I can find 🙁


Understanding beans_get().

beans_get( 'has_children', beans_get( 'walker', $args ) ) is the same as $args['walker']['has_children'].

Differences with beans_get().

If you use $args['walker']['has_children'] will return value if key exist and (empty) if key doesn't exist.

beans_get() accepts 3 arguments. The third is $default = null. The function does the same thing as example above, but if the key has_children doesn't exist on $args['walker'], you can return something else instead of (empty). If you did not set the third argument ( $default ) , beans will return a null value.

Examples using beans_get()

$browsers = array(
  'chrome' => 'I use Chrome',
    'firefox' => 'I use Firefox'
);

1. echo $browsers[ 'chrome' ];
2. echo $browsers[ 'opera' ];
3. echo beans_get( 'chrome', $browsers );
4. echo beans_get( 'chrome', $browsers, 'I use it too' );
5. echo beans_get( 'opera', $browsers );
6. echo beans_get( 'opera', $browsers, 'I forgot Opera' );

//  Will echo:

1. I use Chrome        // key exist, echo key's value.
2. (empty)             // key doesn't exist, echo NULL.
3. I use Chrome        // key exist, echo key's value.
4. I use Chrome        // key exist, ignore $default, echo key's value.
5. (empty)             // key doesn't exist, $default not set ( set as NULL by default ), echo NULL.
6. I forgot Opera      // key doesn't exist, $default is set, echo $default's value.

Write a reply

Login or register to write a reply, it's free!