Dmitry
Dmitry

Reputation: 167

Choosing a date and time after choosing the WooCommerce delivery method

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:

  1. ASAP

  2. 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

Answers (2)

LoicTheAztec
LoicTheAztec

Reputation: 254286

Update with an addition - The following code will:

  • show / hide the date-time picker field depending on the selected checkbox…
  • process the date field, checking that is not empty when visible
  • save the selected option and the chosen date time (if the option is selected)

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.


Get your delivery custom fields values

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

Nevermind23
Nevermind23

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

Related Questions