Reputation: 167
I need to make a selection of the time and date of delivery of the products, after choosing the method of delivery and place these fields in woocommerce_after_shipping_rate
.
As I see it. The customer chooses the delivery method, for example, "Courier".
After that, two checkboxes appear:
ASAP
Delivery Date.
If the customer chooses "Delivery Date", a new field appears with the date and time of delivery. That's about how here
Based on "Enable Datepicker in a WooCommerce Checkout custom text field" answer code, I made additional fields for the date and time of delivery, "ASAP" and "Delivery Date". I downloaded DateTimePicker from here.
Here is my code:
// Register main datetimepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_time_picker' );
function enabling_date_time_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datetimepicker jQuery-ui plugin script
wp_enqueue_style( 'datetimepicker', get_stylesheet_directory_uri() . '/assets/css/jquery.datetimepicker.min.css', array());
wp_enqueue_script('datetimepicker', get_stylesheet_directory_uri() . '/js/jquery.datetimepicker.full.min.js', array());
}
// Call datetimepicker functionality in your custom text field
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field', 10, 1);
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('Europe');
$mydateoptions = array('' => __('', 'woocommerce' ));
echo '<div id="my_custom_checkout_field">
<h3>'.__('Delivery Info').'</h3>';
echo '
<script>
jQuery(function($){
$("#datetimepicker").datetimepicker({format:\'d.m.Y H:i\', allowTimes:[
\'11:00\', \'11:30\', \'12:00\', \'12:30\', \'13:00\', \'13:30\', \'14:00\', \'14:30\',
\'15:00\', \'15:30\', \'16:00\', \'16:30\', \'17:00\', \'17:30\', \'18:00\', \'18:30\',
\'19:00\', \'19:30\', \'20:00\', \'20:30\', \'21:00\', \'21:30\', \'22:00\', \'22:30\']
});
});
</script>';
// Checkbox ASAP
woocommerce_form_field( 'order_delivery_asap', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __('As Soon As Possible'),
'checked' => '',
'default' => 0,
), $checkout->get_value( 'order_delivery_asap' ));
// Checkbox Delivery Date
woocommerce_form_field( 'order_delivery_date', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __('Delivery Date'),
'checked' => '',
'default' => 0,
), $checkout->get_value( 'order_delivery_date' ));
// DateTimePicker
woocommerce_form_field( 'order_pickup_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'id' => 'datetimepicker',
'required' => false,
'label' => __('Select date'),
'placeholder' => __(''),
'options' => $mydateoptions
),$checkout->get_value( 'order_pickup_date' ));
echo '</div>';
}
As I understand it, I need to include conditional logic here so that when selecting the "Delivery Date" checkbox, a field with a DateTimePicker appears. And so that the selected values of the ASAP checkbox and DateTimePicker are saved.
Unfortunately, I do not know how to do all this correctly. I will be glad for your help!
Upvotes: 7
Views: 6166
Reputation: 254286
Update with an addition - The following code will:
I have revisited your code changing your field slugs and adding some additional things.
1) With Checkboxes
// Register main datetimepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_time_picker' );
function enabling_date_time_picker() {
// Only on front-end and checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) :
// Load the datetimepicker jQuery-ui plugin script
wp_enqueue_style( 'datetimepicker', get_stylesheet_directory_uri() . '/assets/css/jquery.datetimepicker.min.css', array());
wp_enqueue_script('datetimepicker', get_stylesheet_directory_uri() . '/js/jquery.datetimepicker.full.min.js', array('jquery'), '1.0', false );
endif;
}
// Display custom checkout fields (+ datetime picker)
add_action('woocommerce_before_order_notes', 'display_custom_checkout_fields', 10, 1 );
function display_custom_checkout_fields( $checkout ) {
// Define the time zone
date_default_timezone_set('Europe/Paris'); // <== Set the time zone (http://php.net/manual/en/timezones.php)
echo '<div id="my_custom_checkout_field">
<h3>'.__('Delivery Info').'</h3>';
// Hide datetimepicker container field
echo'<style> #datetimepicker_field.off { display:none; } </style>';
// Checkbox ASAP
woocommerce_form_field( 'delivery_asap', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __("As Soon As Possible", "woocommerce"),
'checked' => '',
'default' => 0,
), '');
// Checkbox Delivery Date
woocommerce_form_field( 'delivery_option', array(
'type' => 'checkbox',
'class' => array('my-field-class form-row-wide'),
'label' => __("Choose a delivery Date", "woocommerce"),
'checked' => '',
'default' => 0,
), '');
// DateTimePicker
woocommerce_form_field( 'delivery_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide off'),
'id' => 'datetimepicker',
'required' => false,
'label' => __('Select date'),
'placeholder' => __(''),
'options' => array('' => __('', 'woocommerce' ))
),'');
echo '</div>';
}
// The jQuery script
add_action( 'wp_footer', 'checkout_delivery_jquery_script');
function checkout_delivery_jquery_script() {
// Only on front-end and checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script>
jQuery(function($){
var a = 'input[name="delivery_asap"]',
c = 'input[name="delivery_option"]',
d = '#datetimepicker',
f = d+'_field';
$(f).hide();
$(a).prop('checked', true);
// First checkbox
$(a).change(function(){
if( $(this).prop('checked') == true ){
$(f).hide();
$(c).prop('checked', false);
} else {
$(f).show();
$(c).prop('checked', true);
}
});
// Second checkbox
$(c).change(function(){
if( $(this).prop('checked') == true ){
$(f).show();
$(a).prop('checked', false);
} else {
$(f).hide();
$(a).prop('checked', true);
}
});
$(d).datetimepicker({
format: 'd.m.Y H:i',
allowTimes:[ '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30',
'15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30',
'19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00', '22:30']
});
});
</script>
<?php
endif;
}
// Check that the delivery date is not empty when it's selected
add_action( 'woocommerce_checkout_process', 'check_datetimepicker_field' );
function check_datetimepicker_field() {
if ( isset($_POST['delivery_option']) && empty($_POST['delivery_date']) ) {
wc_add_notice( __( 'Error: You must choose a delivery date and time', 'woocommerce' ), 'error' );
}
}
// Check that the delivery date is not empty when it's selected
add_action( 'woocommerce_checkout_create_order', 'save_order_delivery_data', 10, 2 );
function save_order_delivery_data( $order, $data ) {
if ( isset($_POST['delivery_option']) && $_POST['delivery_option'] && ! empty($_POST['delivery_date']) ) {
$order->update_meta_data( '_delivery_datetime', sanitize_text_field( $_POST['delivery_date'] ) );
$order->update_meta_data( '_delivery_option', 'date' );
} elseif( isset($_POST['delivery_asap']) && $_POST['delivery_asap'] ) {
$order->update_meta_data( '_delivery_option', 'azap' );
}
}
Code goes in function.php
file of your active child theme (or active theme). Tested and works.
2) Addition with radio buttons
It might be better to replace the checkboxes by radio buttons:
// Register main datetimepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_time_picker' );
function enabling_date_time_picker() {
// Only on front-end and checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) :
// Load the datetimepicker jQuery-ui plugin script
wp_enqueue_style( 'datetimepicker', get_stylesheet_directory_uri() . '/assets/css/jquery.datetimepicker.min.css', array());
wp_enqueue_script('datetimepicker', get_stylesheet_directory_uri() . '/js/jquery.datetimepicker.full.min.js', array('jquery'), '1.0', false );
endif;
}
// Display custom checkout fields (+ datetime picker)
add_action('woocommerce_before_order_notes', 'display_custom_checkout_fields', 10, 1 );
function display_custom_checkout_fields( $checkout ) {
// Define the time zone
date_default_timezone_set('Europe/Paris'); // <== Set the time zone (http://php.net/manual/en/timezones.php)
echo '<div id="my_custom_checkout_field">
<h3>'.__('Delivery Info').'</h3>';
// Hide datetimepicker container field
echo'<style> #datetimepicker_field.off { display:none; } </style>';
// Radio buttons field: Selected option
woocommerce_form_field( 'delivery_option', array(
'type' => 'radio',
'class' => array('my-field-class form-row-wide'),
'options' => array(
'asap' => __('As Soon As Possible'),
'date' => __('Select Delivery Date'),
),
), 'asap' );
// DateTimePicker
woocommerce_form_field( 'delivery_date', array(
'type' => 'text',
'class' => array('my-field-class form-row-wide off'),
'id' => 'datetimepicker',
'required' => false,
'label' => __('Select date'),
'placeholder' => __(''),
'options' => array('' => __('', 'woocommerce' ))
),'');
echo '</div>';
}
// The jQuery script
add_action( 'wp_footer', 'checkout_delivery_jquery_script');
function checkout_delivery_jquery_script() {
// Only on front-end and checkout page
if( is_checkout() && ! is_wc_endpoint_url() ) :
?>
<script>
jQuery(function($){
var d = '#datetimepicker',
f = d+'_field',
r = 'input[name="delivery_option"]';
$(f).hide();
// On radio button change
$(r).change(function(){
if( $(this).val() == 'date' ){
$(f).show();
} else {
$(f).hide();
}
});
// Enable the datetime picker field
$(d).datetimepicker({
format: 'd.m.Y H:i',
allowTimes:[ '11:00', '11:30', '12:00', '12:30', '13:00', '13:30', '14:00', '14:30',
'15:00', '15:30', '16:00', '16:30', '17:00', '17:30', '18:00', '18:30',
'19:00', '19:30', '20:00', '20:30', '21:00', '21:30', '22:00', '22:30']
});
});
</script>
<?php
endif;
}
// Check that the delivery date is not empty when it's selected
add_action( 'woocommerce_checkout_process', 'check_datetimepicker_field' );
function check_datetimepicker_field() {
if ( isset($_POST['delivery_option']) && $_POST['delivery_option'] === 'date'
&& isset($_POST['delivery_date']) && empty($_POST['delivery_date']) ) {
wc_add_notice( __( 'Error: You must choose a delivery date and time', 'woocommerce' ), 'error' );
}
}
// Check that the delivery date is not empty when it's selected
add_action( 'woocommerce_checkout_create_order', 'save_order_delivery_data', 10, 2 );
function save_order_delivery_data( $order, $data ) {
if ( isset($_POST['delivery_option']) && $_POST['delivery_option'] == 'date' && ! empty($_POST['delivery_date']) ) {
$order->update_meta_data( '_delivery_datetime', sanitize_text_field( $_POST['delivery_date'] ) );
}
if( isset($_POST['delivery_option']) ) {
$order->update_meta_data( '_delivery_option', esc_attr( $_POST['delivery_option'] ) );
}
}
Code goes in function.php
file of your active child theme (or active theme). Tested and works.
To get your delivery custom fields values, you will use:
1) From $order
, WC_Order
Object (using WC_Data
get_meta()
method):
$delivery_option = $order->get_meta('_delivery_option');
if( $delivery_option == 'date' ) {
$delivery_datetime = $order->get_meta('_delivery_datetime');
}
2) From $order_id
, the order ID (using WordPress get_post_meta()
function)
$delivery_option = get_post_meta($order_id, '_delivery_option', true);
if( $delivery_option == 'date' ) {
$delivery_datetime = get_post_meta($order_id, '_delivery_datetime', true);
}
The following: Display custom fields values in WooCommerce order and email notification
Related thread: Enable Datepicker in a WooCommerce Checkout custom text field
Upvotes: 3
Reputation: 405
Use radio buttons instead
woocommerce_form_field( 'order_delivery_method', array(
'type' => 'radio',
'class' => array('my-field-class form-row-wide'),
'options' => array(
'method_asap' => __('As Soon As Possible'),
'method_date' => __('Select Delivery Date'),
),
), $checkout->get_value('order_delivery_method'));
woocommerce_form_field( 'order_delivery_date', array(
'id' => 'DeliveryDatePicker',
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Delivery Date'),
'default' => 0,
), $checkout->get_value( 'order_delivery_date' ));
and append javascript with
$("#DeliveryDatePicker").hide();
$("input[name='order_delivery_method']").click(function () {
if($(this).val() == 'method_date') {
$("#DeliveryDatePicker").show();
} else {
$("#DeliveryDatePicker").hide();
}
});
There will be two radio buttons, if someone chooses Exact Date, dateform field will be shown.
Edit, Full Version:
// Register main datetimepicker jQuery plugin script
add_action( 'wp_enqueue_scripts', 'enabling_date_time_picker' );
function enabling_date_time_picker() {
// Only on front-end and checkout page
if( is_admin() || ! is_checkout() ) return;
// Load the datetimepicker jQuery-ui plugin script
wp_enqueue_style( 'datetimepicker', get_stylesheet_directory_uri() . '/assets/css/jquery.datetimepicker.min.css', array());
wp_enqueue_script('datetimepicker', get_stylesheet_directory_uri() . '/js/jquery.datetimepicker.full.min.js', array());
}
// Call datetimepicker functionality in your custom text field
add_action('woocommerce_before_order_notes', 'my_custom_checkout_field', 10, 1);
function my_custom_checkout_field( $checkout ) {
date_default_timezone_set('Europe');
$mydateoptions = array('' => __('', 'woocommerce' ));
echo '<div id="my_custom_checkout_field">
<h3>'.__('Delivery Info').'</h3>';
echo '
<script>
$("#DeliveryDatePicker").hide();
$("input[name=\'order_delivery_method\']").click(function () {
if($(this).val() == 'method_date') {
$("#DeliveryDatePicker").show();
} else {
$("#DeliveryDatePicker").hide();
}
});
jQuery(function($){
$("#DeliveryDatePicker").datetimepicker({format:\'d.m.Y H:i\', allowTimes:[
\'11:00\', \'11:30\', \'12:00\', \'12:30\', \'13:00\', \'13:30\', \'14:00\', \'14:30\',
\'15:00\', \'15:30\', \'16:00\', \'16:30\', \'17:00\', \'17:30\', \'18:00\', \'18:30\',
\'19:00\', \'19:30\', \'20:00\', \'20:30\', \'21:00\', \'21:30\', \'22:00\', \'22:30\']
});
});
</script>';
woocommerce_form_field( 'order_delivery_method', array(
'type' => 'radio',
'class' => array('my-field-class form-row-wide'),
'options' => array(
'method_asap' => __('As Soon As Possible'),
'method_date' => __('Select Delivery Date'),
),
), $checkout->get_value('order_delivery_method'));
woocommerce_form_field( 'order_delivery_date', array(
'id' => 'DeliveryDatePicker',
'type' => 'text',
'class' => array('my-field-class form-row-wide'),
'label' => __('Delivery Date'),
'default' => 0,
), $checkout->get_value( 'order_delivery_date' ));
echo '</div>';
}
Upvotes: 1