Ask your WordPress questions! Pay money and get answers fast! Comodo Trusted Site Seal
Official PayPal Seal

Custom meta field date picker+ordering by this value WordPress

I am using a custom post type to create an event calendar, and have previously used one custom meta field to write the date as "YYYYMMDD" (named "sort" as in "getting sorted by"), and another field (named "date") where the user could write the date as text in any way he wanted. But of course this is not a very good solution, and I'd like to make it a bit smoother.

Could someone help me

a) Help me with the code for the meta fields in functions.php, so I get a proper "date-picker"? Something like this would be cool http://jqueryui.com/demos/datepicker/ (I'll add a bonus if someone can help me do that), but not neccessarily that fancy, even just plain dropdown fields for day/month/year would do. It would be nice to set the current year as default, but making a coulple more years ahead available.

b) help me with any neccessary changes to make the query work again

I guess something like first saving day, month and year seperately as meta fields, and then concatenate them to one and saving that one as a fourth meta field would be the best way to do it, but HOW to do that is really way beyond my php skills, and I'm on too tight a deadline to try figuring it out by myself right now :)

It would also be great if its simple to change the code around so I can show either the full months name, or just the monts number (ie: March/03), since I'm not quite sure what we will end up using :)

So, this is the code for the template:

<ul class="calendar">
<?php
// fetch posts from calendar.
$today = date("Ymd") ;
query_posts("post_type=calendar&orderby=meta_value&meta_key=sort&order=ASC&meta_compare=>=&meta_value=$today&posts_per_page=10"); ?>
<?php while (have_posts()) : the_post(); ?>
<?php $custom = get_post_custom($post->ID);
$date = $custom["date"][0];
$location = $custom["location"][0];
$sort = $custom["sort"][0];?>
<li class="calendar">
<a href="<?php the_permalink()?>" class="calendar">
<h2 class="kalender-dato"><?php the_title(); ?></h2>
<p class="kalender-sted"><?php echo $date; ?>, <?php echo $location; ?></p>
</a>
</li>
<?php endwhile;?>
</ul>



And here is the current code for the custom post type:


function kalender_register() {

$labels = array(
'name' => _x('Calendar', 'post type general name'),
'singular_name' => _x('Calendarevent', 'post type singular name'),
'add_new' => _x('Add', 'Calendar event'),
'add_new_item' => __('Add new event'),
'edit_item' => __('Edit event'),
'new_item' => __('New event'),
'view_item' => __('Look at event'),
'search_items' => __('Search events'),
'not_found' => __('Nothing found'),
'not_found_in_trash' => __('Nothing found in trash'),
'parent_item_colon' => ''
);

$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'menu_icon' => get_stylesheet_directory_uri() . '/article16.png',
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title','editor','excerpt','thumbnail','revisions'),
'menu_position' => 4
);

register_post_type( 'calendar' , $args );
}

// Legg til custom fields
add_action("admin_init", "admin_init");

function admin_init(){
add_meta_box("calendar_meta", "Dates and locations", "calendar_meta", "calendar", "normal", "low");
}

function calendar_meta() {
global $post;
$custom = get_post_custom($post->ID);
$date = $custom["date"][0];
$time = $custom["time"][0];
$location = $custom["location"][0];
$sort = $custom["sort"][0]; ?>
<p><label>Date:</label><br />
<input cols="20" name="date" value="<?php echo $date; ?>"></input></p>
<p><label>Time for the event:</label><br />
<input cols="8" name="time" value="<?php echo $time; ?>"></input></p>
<p><label>Date on the form YYYYMMDD (Ex - july 30th 2010 will be: 20100730) for sorting the calendar:</label><br />
<input cols="8" name="sort" value="<?php echo $sort; ?>"></input></p>
<p><label>Location:</label><br />
<textarea cols="50" rows="3" name="location"><?php echo $location; ?></textarea></p>
<?php
}
// save custom fields

Answers (3)

2011-12-17

Francisco Javier Carazo Gil answers:

Hi Torstein,

First one, the date-picker. I have been working for years with jQuery UI and for me is the best alternative. Simple to implement and greatest at the same time.

Change:

<input cols="20" name="date" value="<?php echo $date; ?>"></input>


For this one:

<input name="date" value="<?php echo $date; ?>"></input>

<script>
$(function() {<input name="date" value="<?php echo $date; ?>"></input>

$( "#date" ).datepicker();
});
</script>


You only have to load jQuery UI Core, so you will have to enqueue the script:

wp_enqueue_script( 'jquery-ui-core' );


I continue now with the rest.


Francisco Javier Carazo Gil comments:

The options you want for the picker:
* Two years more maximum: maxDate: '+2y'
* Default date: currentText: 'Now'

So you will have:

$( ".selector" ).datepicker({ maxDate: '+2y'}, {currentText: 'Now'});


Francisco Javier Carazo Gil comments:

How to save data? I recommend you save only one meta field. For example, use same format as MySQL: YYYY-MM-DD.

In datepicker you choose this option: dateFormat:'yy-mm-dd'

Then you always use this data but you can split the string in runtime to know date, month and year:
list($year, $month, $day) = split('-', $your_date_value_meta);

With this you could alway make a PHP date and show it as you want. For example:
date("your-format", mktime(0, 0, 0, $month, $day, $year));

Some examples of format (without usign mktime uses default date that is now, assume today is 10th March 2001):

date("F j, Y, g:i a"); // March 10, 2001, 5:16 pm
date("m.d.y"); // 03.10.01
date("j, n, Y"); // 10, 3, 2001
date("Ymd"); // 20010310
date('h-i-s, j-m-y, it is w Day'); // 05-16-18, 10-03-01, 1631 1618 6 Satpm01
date('\i\t \i\s \t\h\e jS \d\a\y.'); // it is the 10th day.
date("D M j G:i:s T Y"); // Sat Mar 10 17:16:18 MST 2001
date('H:m:s \m \i\s\ \m\o\n\t\h'); // 17:03:18 m is month
date("H:i:s"); // 17:16:18


You can use string format you want.

If you need more help, tell me!


Torstein Opperud comments:

Hi Francisco, seems good, I'll test it later tonight :)


Francisco Javier Carazo Gil comments:

Torstein,

Thanks. If you need something, tell me.

Regards.


Torstein Opperud comments:

Hmmm... I must be doing something wrong, this is what the code for the custom post type looks like now:

<?php
//Custom posts under her
add_action('init', 'kalender_register');

function kalender_register() {

$labels = array(
'name' => _x('Calendar', 'post type general name'),
'singular_name' => _x('Calendarevent', 'post type singular name'),
'add_new' => _x('Add', 'Calendar event'),
'add_new_item' => __('Add new event'),
'edit_item' => __('Edit event'),
'new_item' => __('New event'),
'view_item' => __('Look at event'),
'search_items' => __('Search events'),
'not_found' => __('Nothing found'),
'not_found_in_trash' => __('Nothing found in trash'),
'parent_item_colon' => ''
);

$args = array(
'labels' => $labels,
'public' => true,
'publicly_queryable' => true,
'show_ui' => true,
'query_var' => true,
'menu_icon' => get_stylesheet_directory_uri() . '/article16.png',
'rewrite' => true,
'capability_type' => 'post',
'hierarchical' => false,
'supports' => array('title','editor','excerpt','thumbnail','revisions'),
'menu_position' => 4
);

register_post_type( 'calendar' , $args );
}

// Legg til custom fields
add_action("admin_init", "admin_init");

function admin_init(){
add_meta_box("calendar_meta", "Dates and locations", "calendar_meta", "calendar", "normal", "low");
}

function calendar_meta() {
global $post;
$custom = get_post_custom($post->ID);
$date = $custom["date"][0];
$time = $custom["time"][0];
$location = $custom["location"][0];
$sort = $custom["sort"][0]; ?>
<p><label>Date:</label><br />
<input name="date" value="<?php echo $date; ?>"></input>



<script>

$(function() {<input name="date" value="<?php echo $date; ?>"></input>
//enque jquery UI
wp_enqueue_script( 'jquery-ui-core' );



$( "#date" ).datepicker();
$( ".selector" ).datepicker({ maxDate: '+2y'}, {currentText: 'Now'});
list($year, $month, $day) = split('-', $your_date_value_meta);
date("your-format", mktime(0, 0, 0, $month, $day, $year));

});

</script></p>
<p><label>Time for the event:</label><br />
<input cols="8" name="time" value="<?php echo $time; ?>"></input></p>
<p><label>Date on the form YYYYMMDD (Ex - july 30th 2010 will be: 20100730) for sorting the calendar:</label><br />
<input cols="8" name="sort" value="<?php echo $sort; ?>"></input></p>
<p><label>Location:</label><br />
<textarea cols="50" rows="3" name="location"><?php echo $location; ?></textarea></p>
<?php
}
// lagre custom fields

add_action('save_post', 'save_details');

function save_details(){
global $post;

$post_id = $post->ID;

// to prevent metadata or custom fields from disappearing...
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE )
return $post_id;

update_post_meta($post->ID, "date", $_POST["date"]);
update_post_meta($post->ID, "time", $_POST["time"]);
update_post_meta($post->ID, "sort", $_POST["sort"]);
update_post_meta($post->ID, "location", $_POST["location"]);
}


Francisco Javier Carazo Gil comments:

Torstein,

Sorry I was not in the PC. Try what Julio says.

Thanks Julio :)

I will be in the PC now so if it's not running, I will be ready to tell you.

2011-12-17

Manoj Raj answers:

Here is the perfect working solution

http://www.refactord.com/create-a-wordpress-meta-box-with-jquery-ui-datepicker

Just download the files and activate as a plugin. (the code is simple) It works perfectly fine for me. It automatically adds a new metabox with datepicker.

Here is the code from the plugin file. Have a look ..You can tweak it according to your needs. You are in need to have it under a custom post type.Right?


<?php
/*
Plugin Name: Refactord Datepicker
Plugin URI: http://www.refactord.com/create-a-wordpress-meta-box-with-jquery-ui-datepicker
Description: This is a plugin that will allow you to add a datepicker to the new post and edit post pages in the admin. You can create the same thing just read the plugin here <a href='http://www.refactord.com/create-a-wordpress-meta-box-with-jquery-ui-datepicker'>WordPress Meta Box with Jquery UI datepicker</a>
Author:Kyle G
Version: 1.0
*/

class Refactord_Datepicker {

var $plugin_dir;
var $plugin_url;

function __construct() {

$this->plugin_dir = WP_PLUGIN_DIR . "/refactord-datepicker";
$this->plugin_url = WP_PLUGIN_URL . "/refactord-datepicker";

add_action( 'admin_print_styles', array($this, 'add_stylesheets') );
add_action( 'admin_enqueue_scripts', array($this, 'add_js') );
add_action( 'add_meta_boxes', array( $this, 'datepicker_meta_box' ) );
add_action( 'admin_head', array($this, 'call_js') );
add_action( 'save_post', array($this, 'save_data') );
}

function add_stylesheets(){
global $post;
$styleFile = $this->plugin_dir . "/css/jquery-ui-1.8.13.custom.css";

if(file_exists($styleFile) && $post->post_type == '<em>calendar</em>'){
wp_register_style('datepicker-css', $this->plugin_url . "/css/jquery-ui-1.8.13.custom.css");
wp_enqueue_style( 'datepicker-css');
}
}

function add_js(){
global $post;
$jsFile = $this->plugin_dir . "/js/jquery-ui-1.8.13.custom.min.js";

if(file_exists($jsFile) && $post->post_type == '<em>calendar</em>'){
wp_register_script('datepicker-js', $this->plugin_url . "/js/jquery-ui-1.8.13.custom.min.js");
wp_enqueue_script( 'datepicker-js');
}
}

function call_js(){
global $post;
if($post->post_type == '<em>calendar</em>'){

echo '<script>
jQuery(document).ready(function() {
jQuery( "#datepicker-field" ).datepicker();
});
</script>';
}
}

function datepicker_meta_box(){
add_meta_box(
'refactord-datepicker'
,'Refactord Datepicker'
,array( &$this, 'meta_box_content' )
,'<em>calendar</em>'
,'side'
,'default'
);
}

function meta_box_content(){
global $post;
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), 'refactord_nounce' );

// The actual fields for data entry
echo '<label for="datepicker-field">';
_e("Pick A date", 'myplugin_textdomain' );
echo '</label> : ';
echo '<input type="text" id="datepicker-field" name="datepicker-field" value="' . get_post_meta($post->ID, '_refactord-datepicker', TRUE) . '" size="20" />';
}

function save_data($post_id){
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;

if ( !wp_verify_nonce( $_POST['refactord_nounce'], plugin_basename( __FILE__ ) ) )
return;


// Check permissions
if ( 'page' == $_POST['post_type'] ){
if ( !current_user_can( 'edit_page', $post_id ) )
return;
}else{
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}

$data = $_POST['datepicker-field'];

update_post_meta($post_id, '_refactord-datepicker', $data, get_post_meta($post_id, '_refactord-datepicker', TRUE));

return $data;
}

}

$refactord_Datepicker = new Refactord_Datepicker;


I replaced the 'post' post type(in default file) with 'calendar' (highlighted in italics) .You can just copy this and paste inside datepicker.php and activate it. You will get a new metabox "Pick a date" and it will display the date picker and saves it.


Torstein Opperud comments:

Hi Manoj,
thanks, but I think I prefer a solution that will not involve a plugin :)

=)
Torstein


Manoj Raj comments:

:) oh.. Okay..But the solution mentioned is nothing but the functions wrapped into a plugin(Instead of adding the code into functions.php, they just bundle the functions with essential jquery needed and made it into a plugin).. A flexible one. We can add the metabox datepicker to any post type. You can have a try.

Francisco solution seems to be perfect for your requirements it seems. Have a good one.



2011-12-19

Julio Potier answers:

Hello

Try this <script> TAG in place of the one in your last reply to Fransisco

<script>
$(function() {
$( "#date" ).datepicker({ maxDate: '+2y'}, {currentText: 'Now'});
});
</script>


And
<input name="date" value="<?php echo $date; ?>"></input>
replaced by
<input name="date" id="date" value="<?php echo $date; ?>"></input>

And
function admin_init(){
add_meta_box("calendar_meta", "Dates and locations", "calendar_meta", "calendar", "normal", "low");
}

replaced by
function admin_init(){
add_meta_box("calendar_meta", "Dates and locations", "calendar_meta", "calendar", "normal", "low");
wp_enqueue_script( 'jquery-ui-core' );
}


<em>Credits goes to Fransisco ;)</em>