My brief was to add a delivery date picker to a Woocommerce website selling gift hampers. There were a few conditions required on the datepicker;
- 5pm cut-off for next day delivery
- Sun delivery unavailable
- National Holidays/ holidays unavailable
- add £10 surcharge for Saturday Deliveries.
Initially I was looking at this plugin, however this delivery option is only at checkout, and applies to all products. What if I need to specify the delivery date selection on a per product basis? The solution was to first use WooCommerce Product Addons to add 2 global addons.
- Delivery date text field (to add datepicker.js onto)
- Saturday Delivery checkbox field with £10 addon when active
Next I call the jQuery UI library and my custom datepicker.js file.
/*-----------------------------------------------------------------------------------*/
/* Delivery Custom Datepicker */
/*-----------------------------------------------------------------------------------*/
add_action( 'wp_enqueue_scripts', 'custom_enqueue_datepicker' );
function custom_enqueue_datepicker() {
// Optional - enqueue styles
wp_enqueue_style( 'jquery-ui', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.21/themes/smoothness/jquery-ui.css', false, '1.0', false );
// Enqueue YOURTHEME/js/datepicker.js
wp_enqueue_script( 'your-datepicker-script', get_stylesheet_directory_uri() . '/js/datepicker.js', array( 'jquery', 'jquery-ui-datepicker' ), '1.0', true );
}
Now I add the datepicker.js file within my theme’s js/ folder.
jQuery(document).ready(function($) {
var dateMin = new Date();
var weekDays = AddWeekDays(1);
dateMin.setDate(dateMin.getDate() + weekDays);
var natDays = [
[1, 1, 'uk'], //New Years Day
[12, 25, 'uk'], //Xmas Day
[12, 26, 'uk'] //Boxing Day
];
function noWeekendsOrHolidays(date) {
var noWeekend = date.getDay();
if (noWeekend > 0) {
return nationalDays(date);
} else {
return [(noWeekend > 0), ''];
}
}
function nationalDays(date) {
for (i = 0; i < natDays.length; i++) {
if (date.getMonth() == natDays[i][0] - 1 && date.getDate() == natDays[i][1]) {
return [false, natDays[i][2] + '_day'];
}
}
return [true, ''];
}
function AddWeekDays(weekDaysToAdd) {
var mydate = new Date()
if (mydate.getHours()>=17) var daysToAdd = 1 // 5pm Cut Off
else var daysToAdd = 0
var day = mydate.getDay()
weekDaysToAdd = weekDaysToAdd - (5 - day)
if ((5 - day) < weekDaysToAdd || weekDaysToAdd == 1) {
daysToAdd = (5 - day) + 2 + daysToAdd
} else { // (5-day) >= weekDaysToAdd
daysToAdd = (5 - day) + daysToAdd
}
while (weekDaysToAdd != 0) {
var week = weekDaysToAdd - 5
if (week > 0) {
daysToAdd = 7 + daysToAdd
weekDaysToAdd = weekDaysToAdd - 5
} else { // week < 0
daysToAdd = (5 + week) + daysToAdd
weekDaysToAdd = weekDaysToAdd - (5 + week)
}
}
return daysToAdd;
}
//Add datepicker to Woocommerce Addon field
jQuery( ".product-addon-delivery-date input" ).datepicker({
beforeShowDay: noWeekendsOrHolidays,
minDate: dateMin,
defaultDate: +1,
firstDay: 1,
changeFirstDay: true,
dateFormat: "DD dd-mm-yy"
});
});
Now the datepicker is using the conditions required I just need to add the Saturday delivery charge. The date is outputting the long day name (DD) into the field. So lets check the date field for the word ‘Saturday’ and if present check the addon checkbox. If no present, uncheck the addon checkbox.
jQuery( ".product-addon-delivery-date input" ).change(function() {
if ( $(this).val().indexOf("Saturday") > -1 ) {
$('.product-addon-saturday-delivery input').attr('checked','checked');
} else {
$( ".product-addon-saturday-delivery input" ).prop( "checked", false );
}
});
Finally hide the Saturday Delivery field with some CSS. Final result here