Adding javascript into an admin page is a critical part of plugin coding. Critical, because it is both trivial and probably reason #1 why it will conflict with other plugins if not done properly. When their plugin needs javascript, Good Plugin Coders™ have to make sure of the following points:
- add javascript only once: if you need prototype.js, don't add it if it's already included
- add javascript only on your plugin page: don't load yourscript.js in every admin page (with hook 'admin_head') including on other's plugin pages.
Doing so is hopefully very easy :
Add javascript only once
Need to include a javascript library or an external script? Don't ever use some straight echo '<script src="prototype.js"></script>';. The script might have been already loaded already, so there's no point in adding it again. Moreover, it can break everything: just add prototype after jQuery and you're ready for some trouble.
Instead, use wp_enqueue_script() :
-
wp_enqueue_script('prototype');
-
wp_enqueue_script('myscript', '/wp-content/plugins/myplugin/myscript.js');
-
wp_enqueue_script('theirscript', 'http://theirsite.com/script.js');
Even simpler, if your script needs, say, Scriptaculous to work, just use:
-
wp_enqueue_script('myscript', '/wp-content/plugins/myplugin/myscript.js', array('scriptaculous') );
Usage:
wp_enqueue_script( [string: handle], [optional string: src], [optional array: dependencies], [optional string: version number])
There are a number of predefined script handles: 'jquery', 'prototype', 'scriptaculous' and a bunch of others. Please refer to wp_enqueue_script() on the Codex for more details.
Add javascript only to your page
Never ever simply hook into 'admin_head' to add your script: not only you will be adding it to every admin pages (the Dashboard, Comments, etc...) but also to every other plugin pages. Seriously, half of the support question I've had with Who Sees Ads were because of WP-ContactForm adding its crappy javascript everywhere it could, including my plugin page.
Instead of testing current page URL in order to determine if it's your plugin page with a smart strpos() over $pagenow or $_SERVER['REQUEST_URI'], you should use hook 'admin_print_scripts-(page_hook)'
Example with a plugin that would create an admin page under "Manage":
-
$mypage = add_management_page( 'myplugin', 'myplugin', 9, __FILE__, 'myplugin_admin_page' );
-
add_action( "admin_print_scripts-$mypage", 'myplugin_admin_head' );
-
-
function myplugin_admin_head() {
-
// what your plugin needs in its <head>
-
}
This snippet from Andrew Ozz on the wp-hackers mailing list.
Complete Example
This simple plugin will create an admin page under "Settings" in which a CSS and a JS file will be loaded. Check other pages of the admin area: they won't be affected.
Download load-js-example.
Summary
Be nice to other plugin coders. Add your javascript properly and only where needed. Thanks :)
Related posts
Shorter URL
Want to share or tweet this post? Please use this short URL: http://ozh.in/hk
Pages: [4] 3 2 1 » Show All
replied, on 01/Nov/09 at 5:11 am # :
I tried searching google, poking through dashboard.php and even crossed my fingers and checked out what wp_add_dashboard_widget returned as a value, but to no avail.
I have a plugin that I originally had done this with, until I added a dashboard widget. I'm curious if there's a hook I could use to load the styles on the dashboard, so I don't have to load them globally?
The closest thing I turned up on google, was ironically this post.
replied, on 31/Oct/09 at 7:15 am # :
Thanks Ozh for yet another eye-opening post right when it was needed. Keep it up.
said, on 27/Oct/09 at 1:26 am # :
@Ozh: Oh really?! That's good news :-) Thanks for the hint!
commented, on 25/Oct/09 at 2:10 pm # :
Henry » You can totally have several $(document).ready() and they won't override themselves.
commented, on 24/Oct/09 at 2:26 pm # :
Hello,
first thanks for the post, it already helped a lot. Now I know how to properly load an external javascript file into the header of a specific page.
Though a new problem arose from that: I defined some functions in my external javascript file, which need to be called when the DOM is ready. Usually jQuery provides the "ready" function for that purpose. But I don't want to put the "jQuery(document).ready(function() { });" code directly in the head, because this might cause trouble with other plugins (overriding). Any suggestions how to deal with that problem?
Thanks for reading and thinking about it...
Cheers
Henry
wrote, on 12/Sep/09 at 10:39 pm # :
So, what's the difference between:
and
?
replied, on 13/Aug/09 at 1:02 pm # :
Cool post! It really helped me develop the admin panel and chart features for SpamTask. :)
Thanks!
pingback on 30/Jul/09 at 6:33 am # :
[...] in pratica. Vediamo il modo più semplice e veloce per farlo. In primis, vi ricordo che esiste un modo consigliato per caricare javascript sulle pagine di Wordpress ed è la funzione wp_enqueue_script che, come vedete da link, richiede un [...]
replied, on 07/Jul/09 at 2:36 am # :
Just to clarify my last comment, as it may not have been clear enough.
If you want to use this method for CSS, you HAVE TO USE the admin_print_styles-$menu_page hook, not the admin_print_scripts-$menu_page!! Now that I have your attention, go read the previous comment.
thought, on 17/Jun/09 at 7:30 pm # :
Excellent post, Ozh, as always - exactly what I needed.
I have a comment regarding loading CSS files in a similar fashion. I have a function enqueue_scripts() that does the CSS and JS enqueuing using wp_enqueue_script() and wp_enqueue_style().
After I applied
I only saw JS showing up in the head. After a bit of mucking around, I found that there's a admin_print_styles- hook that does exactly that. It's obvious but a bit of a tricky one to notice right away.
So, really, they can both call the same function, like so:
Hope it helps someone.