WooCommerce结账页:基于所选日期动态设置下拉选择框选项
Hey there! Let's fix that dynamic time dropdown based on the selected date in your WooCommerce checkout. Here's a complete, tested solution that should do the trick:
First, we'll properly add both fields to the checkout, enqueue the necessary jQuery UI datepicker script, and save the field values to your order metadata:
// Enqueue jQuery UI Datepicker script and styles add_action( 'wp_enqueue_scripts', 'enqueue_datepicker_assets' ); function enqueue_datepicker_assets() { if ( is_checkout() ) { wp_enqueue_script( 'jquery-ui-datepicker' ); wp_enqueue_style( 'jquery-ui-style', '//code.jquery.com/ui/1.13.2/themes/base/jquery-ui.css' ); } } // Add custom datepicker field to checkout add_action( 'woocommerce_before_order_notes', 'add_custom_checkout_fields' ); function add_custom_checkout_fields( $checkout ) { echo '<div id="custom_checkout_fields">'; // Datepicker Field woocommerce_form_field( 'delivery_date', array( 'type' => 'text', 'class' => array('form-row-wide'), 'label' => __('Delivery Date'), 'required' => true, ), $checkout->get_value( 'delivery_date' ) ); // Time Dropdown Field woocommerce_form_field( 'delivery_time', array( 'type' => 'select', 'class' => array('form-row-wide'), 'label' => __('Delivery Time'), 'required' => true, 'options' => array( '' => __('Select a time'), // Fallback default options '09:00' => '09:00', '09:30' => '09:30', '10:00' => '10:00', ), ), $checkout->get_value( 'delivery_time' ) ); echo '</div>'; } // Save custom field values to order meta add_action( 'woocommerce_checkout_update_order_meta', 'save_custom_checkout_fields' ); function save_custom_checkout_fields( $order_id ) { if ( ! empty( $_POST['delivery_date'] ) ) { update_post_meta( $order_id, 'delivery_date', sanitize_text_field( $_POST['delivery_date'] ) ); } if ( ! empty( $_POST['delivery_time'] ) ) { update_post_meta( $order_id, 'delivery_time', sanitize_text_field( $_POST['delivery_time'] ) ); } } // Display custom field values in order details add_action( 'woocommerce_order_details_after_order_table', 'display_custom_order_fields' ); function display_custom_order_fields( $order ) { echo '<h2>' . __('Delivery Details') . '</h2>'; echo '<table class="woocommerce-table woocommerce-table--custom-details shop_table custom-details">'; echo '<tr><th>' . __('Delivery Date') . '</th><td>' . get_post_meta( $order->get_id(), 'delivery_date', true ) . '</td></tr>'; echo '<tr><th>' . __('Delivery Time') . '</th><td>' . get_post_meta( $order->get_id(), 'delivery_time', true ) . '</td></tr>'; echo '</table>'; }
Next, add this script to handle the date change event, check if it's a weekend, and update the time dropdown accordingly. You can add this to your child theme's functions.php or a custom JS file:
// Add inline jQuery script to handle dynamic time dropdown add_action( 'wp_footer', 'dynamic_delivery_time_script' ); function dynamic_delivery_time_script() { if ( ! is_checkout() ) return; ?> <script> jQuery(document).ready(function($) { // Initialize datepicker $('#delivery_date').datepicker({ dateFormat: 'yy-mm-dd', // Standard format for easy parsing minDate: 0, // Disable past dates (adjust as needed) onSelect: function(dateText) { updateDeliveryTimeOptions(dateText); } }); // Function to update time options based on selected date function updateDeliveryTimeOptions(selectedDate) { const date = new Date(selectedDate); const dayOfWeek = date.getDay(); // 0 = Sunday, 6 = Saturday let timeOptions = '<option value="">Select a time</option>'; const startTime = 9; // 9 AM let endTime = dayOfWeek === 0 || dayOfWeek === 6 ? 15 : 18; // 3 PM for weekends, 6 PM for weekdays // Generate time options in 30-minute increments for (let hour = startTime; hour < endTime; hour++) { timeOptions += `<option value="${hour.toString().padStart(2, '0')}:00">${hour.toString().padStart(2, '0')}:00</option>`; timeOptions += `<option value="${hour.toString().padStart(2, '0')}:30">${hour.toString().padStart(2, '0')}:30</option>`; } // Add final hour option if (endTime !== startTime) { timeOptions += `<option value="${endTime.toString().padStart(2, '0')}:00">${endTime.toString().padStart(2, '0')}:00</option>`; } // Update the time dropdown $('#delivery_time').html(timeOptions); } // Initialize time options if a date is already selected (e.g., checkout reload) const initialDate = $('#delivery_date').val(); if (initialDate) { updateDeliveryTimeOptions(initialDate); } }); </script> <?php }
Key Customization Tips:
- Date Format: If you prefer a different date display, adjust the
dateFormatparameter in the datepicker, just make sure the JS date parsing still works. - Business Hours: Tweak the
startTimeandendTimevariables to match your actual operating hours—change the weekend end time from 15 to whatever you need. - Time Increments: To switch to 15-minute slots, modify the loop to add 15-minute steps instead of 30.
Replace your existing custom field code with this setup, then test by selecting a weekend vs. weekday date—your time dropdown should update automatically!
内容的提问来源于stack exchange,提问作者s_83

