Admin Bar menu item that executes Javascript but does not reload the page?

I added a menu item to the Admin Bar that executes some Javascript to show debug information. The problem is that clicking this item also reloads the page. How can I prevent this?

I was trying to speed up my debug & dev stuff and wanted to add a class to my main wrapper div using jQuery.

Read More

Step 1:

Add styles to your head

function my_admin_bar_script_def( $script ) {
$script = '
    jQuery(document).ready( function() {
        jQuery("li#wp-admin-bar-showdebug").click( function() {
            jQuery(".wrap").toggleClass("showdebug");
        } )
    } );
';

return print $script;
}
add_action( 'wp_head', 'my_admin_bar_script_def', 11 );

Step 2:

Add a admin bar menu item:

function my_admin_bar_class_switch() {
global $wp_admin_bar;

$wp_admin_bar->add_menu( 
    array( 
         'parent'   => 'theme_options'
        ,'title'    => __( 'showdebug', TEXTDOMAIN )
        ,'href'     => '' // **interesting problem over here**
    ) 
);
}
add_action( 'admin_bar_menu', 'my_admin_bar_class_switch', 70 );

Problem:

Every time you trigger your toggle function you’ll fire up the link and reload the page. Therefore you’ll get the initial trigger again. Replacing the link is not possible, because in the $args array for the add_menu() function you only define the href and the link will be printed anyway. Filters or hooks? Not available.

Related posts

Leave a Reply

2 comments

  1. If you return false in that Javascript function the click will not be propagated and the page will also not reload.

    Even better, you can specify a onclick attribute for a menu item. So you definition would become this:

    function my_admin_bar_class_switch( &$wp_admin_bar ) {
        // $wp_admin_bar is passed by reference, you don't need the global var
        $wp_admin_bar->add_menu( 
            array( 
                 'parent'   => 'theme_options'
                ,'title'    => __( 'showdebug', AHF_LANG )
                ,'href'     => '' // This can stay empty
                ,'meta'     => array(
                    'onclick' => 'jQuery(".wrap").toggleClass("showdebug"); return false;'
                )
            ) 
        );
    }
    add_action( 'admin_bar_menu', 'my_admin_bar_class_switch', 70 );
    

    In that case you don’t need to hook up the onclick event yourself. I see two other possible errors there: wp_head is an action, not a filter, so by returning the script it won’t be printed. Also, you depend on showdebug being part of the id, but because you don’t specify the ID it is generated from the title. If that string is translated this ID won’t stay the same.

  2. Solution:

    Simply set 'href' => '#' to link to a not defined anchor to avoid page reloading.

    I know this is really simple, but it took me nearly an hour to get on the right track (thinking too much about filters and hooks to modify the output), so here’s my share.