I have a few qualms about the reliance on Thickbox in the WordPress admin interface. As a plugin developer, I use the modal-box method frequently; it’s great for handling all kinds of data asynchronously … without page refreshes. They keep your file quantities down, and WordPress users are already familiar with how they work.
However, Thickbox is becoming a little antiquated:
Now that the WordPress interface is being brought towards a more open source model, I hope this is one of things they change. I’d like to see more integration of the jQuery UI Dialog widget.
Regardless, Thickbox is how it works now; so here’s how to use it in a plugin.
The most frequent use (I’m saying this with no evidence to support my claim) of any modal box in a plugin is to do something without navigating to another page. For instance, you upload an image through a Thickbox; the page stays current, but an image is uploaded asynchronously through the modal-box.
For this example, let’s imagine that it is necessary for a user to decide something: black or white? We want them to open a box, decide, and close the box all from the plugin’s interface.
<?php
/*
Plugin Name: Black or White?
Plugin URI: http://www.example.com/
Description: You choose.
Version: 0.1
Author: Kyle Truscott
Author URI: http://www.keighl.com
*/
$BlackOrWhite = new BlackOrWhite();
class BlackOrWhite {
function BlackOrWhite() {
add_action('admin_menu', array(&$this, 'add_admin'));
add_action("admin_print_scripts", array(&$this, 'js_libs'));
add_action("admin_print_styles", array(&$this, 'style_libs'));
}
function add_admin() {
add_theme_page('BlackOrWhite', 'BlackOrWhite', 'administrator', 'black-or-white', array(&$this, 'admin_view'));
}
function js_libs() {
wp_enqueue_script('jquery');
wp_enqueue_script('thickbox');
}
function style_libs() {
wp_enqueue_style('thickbox');
}
function admin_view() {}
function choice() {}
}
?>
Fairly normal. In order to use Thickbox, you need to queue both the script and style respectively. WordPress has these pre-registered for us, so all we need to do is tell it to load with wp_enqueue_script() and wp_enqueue_style() from the constructor.
In order to actually have the modal-box pop up, it is necessary to do so through the href parameter of a link. This is where it gets ugly.
function admin_view() {
?>
<div class="wrap">
<h2>Black or White?</h2>
<p>
<a class="thickbox button" href="<?php echo get_option('siteurl'); ?>/wp-admin/admin-ajax.php?action=choice&width=150&height=100" title="Choice">
Choice
</a>
</p>
<p>
Your choice: <span class="your-choice"></span>
</p>
</div>
<?php
}
You need to :
<?php echo get_option('siteurl'); ?>/wp-admin/admin-ajax.php?The reason for passing the AJAX request through admin-ajax.php is so we can call one of our plugin functions … the one for the dialog box content. Back in the constructor, simply tell WordPress to which function it should redirect the AJAX request.
function BlackOrWhite() {
add_action('admin_menu', array(&$this, 'add_admin'));
add_action("admin_print_scripts", array(&$this, 'js_libs'));
add_action("admin_print_styles", array(&$this, 'style_libs'));
add_action('wp_ajax_choice', array(&$this, 'choice'));
}
Now, when the user clicks “Choose”, whatever we have stored in choice() will return within the box.
So far so good, but there is nothing in the modal-box. We need two buttons: black and white. The dialog box displays whatever is returned from choice(). Therefore, that’s where the buttons go.
function choice() {
?>
<p>
<a class="button choice_button" id="Black">Black</a>
<a class="button choice_button" id="White">White</a>
</p>
<?php
exit();
}
Don’t forget to exit() the function, or you’ll get an annoying 0 in the Thickbox. We don’t have any href info for these links, because we’ll be handling their events via jQuery. The goal here is to only have one page, right?
function admin_view() {
?>
<script type="text/javascript">
jQuery(document).ready(function($) {
$('.choice_button').live('click',
function () {
var choice = $(this).attr('id');
tb_remove();
$('.your-choice').html(choice);
}
);
});
</script>
<!-- The rest of the admin view ... -->
<?php
}
On the click event of either choice_button, we execute a function that returns the user’s choice to the main interface. Use the live() method to bind the event, because the buttons were loaded via AJAX.
Removing the Thickbox is much easier than launching it … simply call the tb_remove() function.
All in all, using the Thickbox in WordPress plugins is not that hard, but it could certainly be easier.
Download the full tutorial code here: Black or White?