Reputation: 1437
I have a custom woocommerce filter function which use the jQuery-ui datepicker. I would like to customize the options with the code below but it just make the datepicker disappear, even when I try to enqueue the script. This code is customized from this answer:
Can the jQuery UI Datepicker be made to disable Saturdays and Sundays (and holidays)?
Below is the code for the delivery-date.js that I enqueue in my php also below.
/*====================================================
Delivery date Code
Only two weeks booking time allowed.
Diallowed days Sunday = 0, Saturday = 6
Dates Disallowed by m/d - 1,1 | 1,26 | 2,16 | 3,8 | 4,14 | 4, 16 | 4,17 | 5,1 | 6,3 | 6,9 | 10,9 | 12,25 | 12, 26
=====================================================*/
jQuery(function($){
$('#datepicker').datepicker({
maxDate: '+2W',
beforeShowDay: noWeekendsOrHolidays
});
var natDays = [ [1,1], [1,26], [2,16], [3,8], [4,14], [4, 16], [4,17], [5,1], [6,3], [6,9], [10,9], [12,25], [12, 26] ];
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 noWeekendsOrHolidays(date) {
var noWeekend = $.datepicker.noWeekends(date);
if (noWeekend[0]) {
return nationalDays(date);
} else {
return noWeekend;
}
}
});
I am trying to merge that in this answer code:
Time loop for WooCommerce checkout select option from date picker input field
But it doesn't work.
Upvotes: 3
Views: 2325
Reputation: 253784
Your array is quiet different than the one used in:
Can the jQuery UI Datepicker be made to disable Saturdays and Sundays (and holidays)?
To make it work with your custom array in Wordpress / Woocommerce you will need to make some changes. In the below code, I have merged the 2 Javascript functions in one:
jQuery(function($){
var natDays = [ [1,1], [1,26], [2,16], [3,8], [4,14], [4, 16],
[4,17], [5,1], [6,3], [6,9], [10,9], [12,25], [12, 26] ]; // Holidays
// No weekends and no holidays
function noWeekendAndHolidays(date) {
// No Holidays
var nationalDays = [];
for (i = 0; i < natDays.length; i++)
if (date.getMonth() == natDays[i][0] - 1 && date.getDate() == natDays[i][1]) {
nationalDays = [false, ''];
return false; // stop the loop
}
if( ! nationalDays[0] )
nationalDays = [true, ''];
// No weekends (or no holidays)
var noWeekend = $.datepicker.noWeekends(date);
if (noWeekend[0])
return nationalDays;
else
return noWeekend;
}
// Jquery-ui datepicker
$("#datepicker").datepicker({
beforeShowDay: noWeekendAndHolidays,
maxDate: '+2W',
});
});
This just works now with your custom array and the jQuery-ui datepicker is displayed correctly.
To merge it in my other answer code you will have it this way:
// Enable available jQuery datepicker script in Wordpress
add_action( 'wp_enqueue_scripts', 'enabling_date_picker' );
function enabling_date_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load available datepicker jQuery-ui plugin script
wp_enqueue_script( 'jquery-ui-datepicker' );
}
// Add and display custom checkout fields + jQuery script
add_filter( 'woocommerce_checkout_fields' , 'brown_remove_billing_postcode_checkout' );
function brown_remove_billing_postcode_checkout( $fields ) {
// Your Settings
$start_hour = 11; // start time (in hours)
$end_hour = 16; // end time (in hours)
$offset = 1; // One hour before slot time (can be a float number like 1.5
// date_default_timezone_set ('Africa/Kampala'); // The timezone
date_default_timezone_set('Australia/Brisbane');
// Initializing variables
$hour = 3600; // 1 hour in seconds
$day = $hour * 24; // 1 day in seconds
$now = strtotime("now"); // Now time
$real_now = $now + ($offset * $hour); // Now time + offset
$today_date = date("Y-m-d"); // today date
$tomorrow_date = date("Y-m-d", strtotime("+1 day")); // tomorow date
$today_time = strtotime($today_date); // Today time at 00:00 in seconds
$tomorrow_time = strtotime($tomorrow_date); // Tomorrow time at 00:00 in seconds
$start_time = $today_time + ( $start_hour * $hour ); // Start datetime in seconds
$end_time = $today_time + ( $end_hour * $hour ); // End datetime in seconds
$today_slots = $default_slots = $option_days = array();
// Add Delivery day field (with jquery-ui datepicker enabled)
$fields['billing']['billing_delivery_day'] = array(
'label' => __('Delivery Day', 'woocommerce'),
'placeholder' => _x('Date for your delivery', 'placeholder', 'woocommerce'),
'required' => true,
'id' => 'datepicker', // Enable jQuery datepicker for this field
'class' => array('form-row-first'),
'clear' => false,
'autocomplete' => false,
'type' => 'text'
);
// Add Delivery hour slots
$fields['billing']['billing_delivery_hour'] = array(
'label' => __('Delivery Time', 'woocommerce'),
'required' => true,
'class' => array('form-row-last'),
'clear' => false,
'autocomplete' => false,
'type' => 'select',
'options' => array( '' => __('Select time for your delivery') ),
);
// Making the delivery hour slots <option> arrays for Javascript
for($i = $start_time; $i <= $end_time; $i += 1800 ){ // 1800 seconds is half an hour
$key = date('H:i', $i);
$value = date('h:ia', $i);
// Today available hour slots array
if($real_now < $i)
$today_slots[$key] = $value;
// Default hour slots array
$default_slots[$key] = $value;
}
// The correct start date and time (today or tomorow) for Javascript
$date = $real_now < $end_time ? $today_date : $tomorrow_date;
$dtime = $real_now < $end_time ? date("Y-m-d\TH:i:s", $today_time) : date("Y-m-d\TH:i:s", $tomorrow_time);
?>
<script>
jQuery(function($){
var offsetDate = 14, // Number of days enabled in the date picker
startingDate = new Date('<?php echo $dtime; ?>'), // Starting day
endingDate = new Date('<?php echo $dtime; ?>'), // End date is calculated below
todaySlots = <?php echo json_encode($today_slots); ?>,
defaultSlots = <?php echo json_encode($default_slots); ?>,
sDay = 'input[name ="billing_delivery_day"]',
sHour = 'select[name ="billing_delivery_hour"]',
defaultOption = $(sHour+' > option').text(),
todaySlotsLength = Object.keys(todaySlots).length,
natDays = [ [1,1], [1,26], [2,16], [3,8], [4,14], [4, 16],
[4,17], [5,1], [6,3], [6,9], [10,9], [12,25], [12, 26] ]; // Holidays
// ------ 1). Dates and Date picker ------ //
// Set the default field start date
$(sDay).val('<?php echo $date; ?>');
$('#datepicker_field').addClass('woocommerce-validated');
// Max date calculation
endingDate.setDate(startingDate.getDate()+offsetDate);
console.log(new Date($(sDay).val()));
// No weekends and no holidays
function noWeekendAndHolidays(date) {
// No Holidays
var nationalDays = [];
for (i = 0; i < natDays.length; i++)
if (date.getMonth() == natDays[i][0] - 1 && date.getDate() == natDays[i][1]) {
nationalDays = [false, ''];
return false; // stop the loop
}
if( ! nationalDays[0] )
nationalDays = [true, ''];
// No weekends (or no holidays)
var noWeekend = $.datepicker.noWeekends(date);
if (noWeekend[0])
return nationalDays;
else
return noWeekend;
}
// Jquery-ui datepicker
$("#datepicker").datepicker({
beforeShowDay: noWeekendAndHolidays,
dateFormat: "yy-mm-dd",
minDate: startingDate,
maxDate: endingDate, // optional
setDate: startingDate,
});
// ------ 2). HOUR slots select field (dynamic <option>) ------ //
// Build the <option> html html in the select field dynamically
function dynamic_select_options_buid( slotsType ){
$.each( slotsType, function( index, value ){
$(sHour).append('<option value="'+index+'">'+value+'</option>');
});
}
// Replace and Build the <option> html in the select field dynamically
function dynamic_select_options_replace( slotsType ){
$(sHour+' > option').remove();
$(sHour).append('<option value="">'+defaultOption+'</option>');
dynamic_select_options_buid( slotsType );
}
console.log(defaultOption);
console.log(todaySlotsLength);
if(todaySlotsLength != 0 && todaySlotsLength < 11 ){
// Loaded at start
dynamic_select_options_buid( todaySlots );
// Live date selection event
$(sDay).change( function(){
console.log('day changed: '+$(this).val());
if( $(this).val() != '<?php echo $date; ?>' )
dynamic_select_options_replace( defaultSlots );
else
dynamic_select_options_replace( todaySlots );
})
} else {
dynamic_select_options_buid( defaultSlots );
}
});
</script>
<?
return $fields;
}
Code goes in function.php file of your active child theme (or active theme).
Tested and works.
Upvotes: 2