Take the 2-minute tour ×
WordPress Development Stack Exchange is a question and answer site for WordPress developers and administrators. It's 100% free, no registration required.

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.

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.

share|improve this question
    
You could move the "Solution" part to an answer, then we can all vote on it - or even add alternative solutions? –  Jan Fabry Apr 8 '11 at 14:09
    
@Jan Fabry - done. Good idea. Unmarked the answer as solution. –  kaiser Apr 8 '11 at 14:18
    
I re-wrote the intro so it looks like a real question, and is more likely to attract Google searches for similar problems. If you don't like it, feel free to edit or rollback! –  Jan Fabry Apr 20 '11 at 20:07
    
@Jan Fabry - No, it's fine. –  kaiser Apr 21 '11 at 0:57
add comment

2 Answers

up vote 1 down vote accepted

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.

share|improve this answer
    
excellent solution. +1. I wrote the code above as an example. In my theme i don't use wp_head(), but some custom filter that is set after a $var that get's printed after the hooked function, so in my case it's fine that way, but i updated the example. Ad ID) Right. Completely oversaw that trap. thanks! –  kaiser Apr 11 '11 at 7:35
    
@kaiser: Yes, I thought you had some custom way to add that Javascript. You still need to add <script></script> to your current output. –  Jan Fabry Apr 11 '11 at 7:38
    
yes and the cdata stuff :) –  kaiser Apr 11 '11 at 7:43
    
i just exchanged my approach with yours and it works like a charm. Thanks a lot. I guess i can mark this as solution. –  kaiser Apr 11 '11 at 8:03
    
@kaiser: And that's the wonder of using WPSE as a technical blog where you post your answers to your own daily problems: not only can you pro-actively help others, you can even get better solutions from others! –  Jan Fabry Apr 11 '11 at 8:16
add comment

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.

share|improve this answer
add comment

Your Answer

 
discard

By posting your answer, you agree to the privacy policy and terms of service.

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