jQuery Events DatePicker in WordPress

In previous posts, we set up an events system for WordPress. Users could enter the date of an event, and we had great archives for displaying and categorizing them.

Today, we want to improve the admin end of things. Instead of using custom fields, we’ll make a box for the event’s date, and use jQuery to let users pick the date from a calendar.

This tutorial is a self-contained post, which is useful on its own whether or not you’ve read the previous posts. But if you haven’t and would like to, you can here: (Or there’s a shortcut afterwards)

  1. Setup an Events List (Using Custom Post Types and Taxonomies)
  2. Making the Template (for our Post Types & Taxonomies)

If you want to skip on though, grab this file, rename it to events.php, and upload it to your theme folder. Then add this line to your theme’s functions.php:

// Events
include('events.php');

Everything we do in this tutorial will be added to that file, so you’re good to go now!

Demo / Download

So what does the end result look like? Well, the meta box itself will appear right below your post editor on Events, like this:

Date Meta Box Demo

And when you click in the box, you’ll see this datepicker calendar:

DatePicker Demo

The completed file can be found here: events-datepicker.phps (Rename it to events.php, and add the same include() line from this post’s intro to your functions.php file).

Also, grab this folder, unzip it, and upload it to your theme folder as well. This holds the jQuery elements we need, which you can download from jQuery UI itself here (For convenience though, I’ve just picked out the files we need and zipped them up here).

1 – Create a Meta Box

Right, let’s start the actual tutorial!

The first thing I want to talk about is meta boxes. On your “Add Post”, “Add Page” etc. screens, you see a series of boxes. There’s one for the post itself, one for choosing a category, one for custom fields etc.

A meta box is just another box like these. Specifically, it’s for custom fields. Instead of always having to type in a name and a value, which isn’t very user-friendly, you can add a meta box of your own to make it much simpler. Behind the scenes though, the end result is the same, you’re still just saving some metadata about the post.

In previous posts in this series, we used a “Date” custom field to save the date of the event. We’re now going to improve it so that the user gets a nice box to enter their Date custom field in (Like you saw in the screenshots above).

So now that you know what a meta box is, how do you add one? There are 3 stages to it:

  1. Tell WordPress about your box.
  2. Write the HTML for the box.
  3. Save the date.

WordPress makes this all very easy to do. Here goes!

1 – Tell WordPress About Your Box

Open your events.php file (Downloadable at the start of this post, or just pick up right where we left off in the last post!), and before the closing ?> tag, paste the following:

/**
 * Register meta box
 *
 * Adds a metabox to Event post types, allowing users to easily enter the date of an event.
 */
function pbd_events_meta_box() {
	add_meta_box('pbd-events-meta-box', 'Event Date', 'pbd_events_create_meta_box', 'events', 'normal', 'high');
}
add_action('add_meta_boxes', 'pbd_events_meta_box');

We use the add_meta_box() function to tell WordPress about the box. The first parameter is just a CSS class, and the last 2 are to do with where to position the box. The important ones are the 2nd, 3rd, and 4th:

  • ‘Event Date’ – The title shown on the box.
  • ‘pbd_events_create_meta_box’ – The function that creates the HTML. We’re going to create this next.
  • ‘events’ – The type of post that this box should appear on. We don’t need it on posts/pages, just on our ‘events’ post type.

That line is wrapped in a function, which hooks into the ‘add_meta_boxes’ action, so WordPress knows to add our box when its needed.

2 – Write the HTML for the Box

WordPress takes care of most of the HTML for us. The divs etc. for the box and the title are taken care of. All we need to do is add the text input:

/**
 * Creates the HTML for the meta box.
 */
function pbd_events_create_meta_box($post) {
	// Get already-entered date.
	$date = get_post_meta($post->ID, 'Date', true);
 
	// Nonce for verification.
	wp_nonce_field( plugin_basename(__FILE__), 'pbd_events_nonce');
	?>
 
Date (mm/dd/yy):
<input id="pbd-event-date" name="pbd-event-date" type="text" value="<?php echo $date; ?>" />
 
<?php }

As you can see, we’ve given this function the name we specified in add_meta_box(). WordPress also sends it the current $post object, which we use next.

On line 6, we get the previously saved Date value (if there was one) to show in our text field. On line 9, we use the wp_nonce_field() function to add some verification fields that we will use to secure our save function later.

And lastly, on line 12, we add the simple text input in a paragraph.

3 – Save the Date

The main issue with saving, as you might expect, is security. So the bulk of our work here is making sure that we actually should save it.

/**
 * Saves the meta box value when the post is saved.
 */
function pbd_events_save_meta_box($post_id) {
 
	// Verification check.
	if ( !wp_verify_nonce( $_POST['pbd_events_nonce'], plugin_basename(__FILE__) ) )
	      return;
 
	// And they're of the right level?
	if(!current_user_can('edit_posts') )
		return;
 
	// Has the field been used?
	$date = trim( $_POST['pbd-event-date'] );
	if( empty($date) )
		return;
 
	// Validate that what was entered is of the form: 00/00/00
	if(preg_match('(^\d{1,2}\/\d{1,2}\/\d{2}$)', $date) ) {
		update_post_meta($post_id, 'Date', $date);
	}
}
add_action('save_post', 'pbd_events_save_meta_box');

As always, the format here is to create a function, and then hook it into place. In this case, the ‘save_post’ hook, which runs each time WordPress saves a post.

We start by using the nonce fields we added in step 2. In a nutshell, a nonce makes sure that the user performing this action actually meant to do it (And wasn’t tricked into it). You can read more about them on Mark Jaquith’s blog.

Next, on line 11, we make sure they have the right capabilities. And the last check is on lines 15-16, where we check if a Date has actually been entered (So we don’t do anything on regular posts/pages). This has the slight downside that to delete the date info altogether, users will need to use the “Custom Fields” metabox again, but given the purpose of our script, that’s not likely to be an issue!

We’ve now verified that the user saving the data is allowed to. The next step is checking that what they entered is valid.

On line 20, we use regular expressions to do this. Our events list requires the date to be in the format: mm/dd/yy, so we verify the Date entered by checking that it’s in the format 00/00/00. If it’s not, then it won’t be saved.

Finally, on line 21, after all of our checks, we can use the update_post_meta() function to save the new Date.

2 – The jQuery DatePicker

Your box is now fully functional and working. Next, we just want to enhance it with an easy-to-use DatePicker, to make the admin’s life easier.

Thankfully, the jQuery UI project has an awesome datepicker script that we can use. Check out its demo page here.

To download the files from jQuery UI itself, you can go here, tick all of the “Core” boxes, and the “DatePicker” widget. Then in the right-hand column, choose the “Smoothness” theme, then hit download.

The resulting package contains quite a few files though, so for simplicity sake, I’ve picked out the ones you need and uploaded them in a zip file here. Download that, unzip it, and save the whole folder (“jquery-ui-datepicker”) into your theme.

The setup is then quite simple. We need to add the JavaScript and CSS files to the admin page, and initiate it on our form field. We’ll start with this last step.

If you downloaded the zip folder I put together, this simple JavaScript file has already been made for you. If not, simply save the 3 lines below into a file called pbd-datepicker.js in the datepicker folder.

jQuery(function($) {
	$( "#pbd-event-date" ).datepicker({ dateFormat: 'mm/dd/y' });
});

We wait for the page to be fully loaded, then call the .datepicker() constructor on our “pbd-event-date” text input (We added that ID to it back in step 2 of the first section).

DatePicker takes a number of options, but the one we need, dateFormat:, allows us to set how it should enter the date in our text box. This way, it matches our mm/dd/yy pattern exactly.

Now, all that’s left to do is load our JS and CSS files. Let’s start with the JavaScript. Add the following to your events.php file:

/**
 * Adds a jQuery datepicker script to Event pages.
 * http://jqueryui.com/demos/datepicker/
 */
function pbd_events_jquery_datepicker() {
	wp_enqueue_script(
		'jquery-ui-datepicker',
		get_bloginfo('template_directory') . '/jquery-ui-datepicker/jquery-ui-1.8.11.custom.min.js',
		array('jquery')
	);
 
	wp_enqueue_script(
		'pbd-datepicker',
		get_bloginfo('template_directory') . '/jquery-ui-datepicker/pbd-datepicker.js',
		array('jquery', 'jquery-ui-datepicker')
	);
}
add_action('admin_print_scripts-post-new.php', 'pbd_events_jquery_datepicker');
add_action('admin_print_scripts-post.php', 'pbd_events_jquery_datepicker');

The wp_enqueue_script() function is a safe way to add JavaScript files to WordPress. Here, we call it twice to add our 2 JavaScript files (Using get_bloginfo(‘template_directory’) to get the link to our theme folder).

The important part in this script is the 2 hooks at the end. Rather than adding these files to every admin page, we only want them when we’re adding a new event (i.e. we’re on the post.php or post-new.php pages in the dashboard). One of WordPress’ admin hooks is of the format:

admin_print_scripts-filename.php

You can use that to add scripts to any particular page in the dashboard, just by replacing the filename.php part with the page you need (as we have done in our example).

Adding the CSS is almost identical, with just a slight change in the function and hook names:

/**
 * Adds CSS for the jQuery datepicker script to Event pages.
 * http://jqueryui.com/demos/datepicker/
 */
function pbd_events_jquery_datepicker_css() {
	wp_enqueue_style(
		'jquery-ui-datepicker',
		get_bloginfo('template_directory') . '/jquery-ui-datepicker/css/smoothness/jquery-ui-1.8.11.custom.css'
	);
}
add_action('admin_print_styles-post-new.php', 'pbd_events_jquery_datepicker_css');
add_action('admin_print_styles-post.php', 'pbd_events_jquery_datepicker_css');

And that’s us done! Now save your file and go add a new event with your snazzy datepicker in all its convenient glory!

If you’ve made it this far through the 3-4 posts in this series, well done! You should now have a very customizable and easy-to-use events list for your blog. If there’s anything else you’d like to know about tweaking it, just let me know in the comments!

And just before we end; I’d love to get your feedback on tutorials of this length. I know they can be quite a long read to sift through. I’m not sure I could make them any shorter (To me, all the explanations are the valuable part), but I could try out screencasts. Would you be interested in seeing that, or are you cool with written guides?

Enjoy this post? You should follow me on Twitter!