On the checkout page, there are delivery methods, if a specific delivery method (only 1) is selected, then a drop-down list with the delivery time should appear. This field is implemented using the ACF plugin with Repeater and the field type is Text. The time selected by the user should be displayed in the order details in the WooCommerce admin panel.
Based on the theme code that I got, I wrote the next code:
<div id="delivery_times" class="form-group d-none">
<label class="text-bold" for="select_time">Delivery time: </label>
<select id="select_time" class="form-control mb-1">
<option value="" selected>Select time</option>
<?php
$delivery_times = get_field('delivery_times', 'options');
$count = 0;
foreach ($delivery_times as $delivery_time):
echo '<option value="'.$delivery_time['range_time'].'" data-pickup="'.$count.'">'.$delivery_time['range_time'].'</option>';
$count++;
endforeach;
?>
</select>
</div>
$("#shipping_speed").change(function(){
var delivery_time = $(this).children("option:selected").data("type");
if(delivery_time == "tomorrow"){
$("#delivery_times").removeClass("d-none");
}else{
$("#delivery_times").addClass("d-none");
$("#select_time option[value='']").prop('selected',true);
}
});
And now I need to save the selected data and display it somehow in the order details for the administrator, but I don’t found the implementation of something similar in my theme. Please tell me how I can save this data from the ACF field to the order details?
Updated:
First on your html <select>
the attibute name="select_time"
is missing, so replace the line:
<select id="select_time" class="form-control mb-1">
by this line:
<select id="select_time" name="select_time" class="form-control mb-1">
Now you can use the following code snippet to save the chosen value as order meta data:
// Save the custom checkout field as the order meta
add_action( 'woocommerce_checkout_create_order', 'custom_checkout_field_update_order_meta', 10, 2 );
function custom_checkout_field_update_order_meta( $order, $data ) {
if ( isset($_POST['select_time']) ) {
$order->update_meta_data( 'delivery_time', esc_attr($_POST['select_time']) );
}
}
Then to display it in admin single order pages under shipping address:
add_action( 'woocommerce_admin_order_data_after_shipping_address', 'display_admin_order_select_time_custom_field' );
function display_admin_order_select_time_custom_field( $order ){
$delivery_time = $order->get_meta('delivery_time');
if( ! empty($delivery_time) ) {
echo '<p class="delivery_time"><strong>'. __("Delivery time", "woocommerce").'</strong>: '.$delivery_time.'</p>';
}
}
Then you can display this delivery time on customer orders and email notifications:
add_filter( 'woocommerce_get_order_item_totals', 'delivery_time_as_order_item_total_row', 10, 3 );
function delivery_time_as_order_item_total_row( $total_rows, $order, $tax_display ){
$delivery_time = $order->get_meta( 'delivery_time' ); // Get delivery time
$new_total_rows = array(); // Initializing
if( empty($delivery_time) ) {
return $total_rows; // Exit
}
// Loop through total rows
foreach( $total_rows as $key => $value ){
if( 'payment_method' == $key ) {
$new_total_rows['delivery_time'] = array(
'label' => __("Delivery time", "woocommerce"),
'value' => $delivery_time,
);
}
$new_total_rows[$key] = $total_rows[$key];
}
return $new_total_rows;
}
Code goes in functions.php file of the active child theme (or active theme). It should work.