如何在WooCommerce结账字段中启用Datepicker日期选择器?
解决WooCommerce结账页添加Checkin/Checkout日期选择器的问题
兄弟,先给你提个醒——直接修改WooCommerce核心的WC_Countries类绝对是个坏主意!下次插件一更新,你的改动就全没了,得用官方提供的钩子来做才靠谱。下面是完整的可行方案:
1. 替换结账字段(用钩子,不碰核心)
把这段代码添加到你主题的functions.php文件里,它会安全替换默认的address1/address2字段为checkin和checkout字段:
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' ); function custom_override_checkout_fields( $fields ) { // 移除默认的地址字段 unset($fields['billing']['billing_address_1']); unset($fields['billing']['billing_address_2']); unset($fields['shipping']['shipping_address_1']); unset($fields['shipping']['shipping_address_2']); // 添加Checkin字段 $fields['billing']['billing_checkin'] = array( 'label' => __( 'Check In', 'woocommerce' ), 'placeholder' => _x( 'Check In Date', 'placeholder', 'woocommerce' ), 'required' => true, 'class' => array( 'form-row-wide', 'datepicker-field' ), 'clear' => true, 'priority' => 50, ); // 添加Checkout字段 $fields['billing']['billing_checkout'] = array( 'label' => __( 'Check Out', 'woocommerce' ), 'placeholder' => _x( 'Check Out Date', 'placeholder', 'woocommerce' ), 'required' => true, 'class' => array( 'form-row-wide', 'datepicker-field' ), 'clear' => true, 'priority' => 60, ); // 如果需要配送地址同步修改,复制字段到shipping数组 $fields['shipping']['shipping_checkin'] = $fields['billing']['billing_checkin']; $fields['shipping']['shipping_checkout'] = $fields['billing']['billing_checkout']; return $fields; }
2. 加载jQuery UI Datepicker并初始化
你的JS没生效,很大原因是没加载Datepicker组件,而且选择器不对。按下面两步来:
第一步:加载Datepicker资源(加到functions.php)
add_action( 'wp_enqueue_scripts', 'enqueue_datepicker_scripts' ); function enqueue_datepicker_scripts() { // 只在结账页加载,节省资源 if( is_checkout() && ! is_wc_endpoint_url() ) { wp_enqueue_style( 'jquery-ui-datepicker' ); wp_enqueue_script( 'custom-datepicker', get_stylesheet_directory_uri() . '/custom.scripts.js', array( 'jquery', 'jquery-ui-datepicker' ), '1.0', true ); } }
第二步:修改custom.scripts.js代码
替换你原来的代码,这次用正确的选择器,还加了日期逻辑(离店日期不能早于入住日期):
jQuery(document).ready(function($) { // 初始化入住日期选择器 $('.billing_checkin_field input').datepicker({ dateFormat: 'yy-mm-dd', // 统一格式方便存储 minDate: 0, // 禁止选择今天之前的日期 onSelect: function(selectedDate) { // 自动设置离店日期的最小可选值 $('.billing_checkout_field input').datepicker('option', 'minDate', selectedDate); } }); // 初始化离店日期选择器 $('.billing_checkout_field input').datepicker({ dateFormat: 'yy-mm-dd', minDate: 0 }); // 同步处理配送地址的日期字段(如果需要的话) $('.shipping_checkin_field input').datepicker({ dateFormat: 'yy-mm-dd', minDate: 0, onSelect: function(selectedDate) { $('.shipping_checkout_field input').datepicker('option', 'minDate', selectedDate); } }); $('.shipping_checkout_field input').datepicker({ dateFormat: 'yy-mm-dd', minDate: 0 }); });
3. 保存并显示日期数据
最后要确保订单能保存这两个日期,并且在后台和邮件里显示,把这段代码加到functions.php:
// 保存结账字段数据 add_action( 'woocommerce_checkout_update_order_meta', 'save_checkin_checkout_dates' ); function save_checkin_checkout_dates( $order_id ) { if ( ! empty( $_POST['billing_checkin'] ) ) { update_post_meta( $order_id, '_billing_checkin', sanitize_text_field( $_POST['billing_checkin'] ) ); } if ( ! empty( $_POST['billing_checkout'] ) ) { update_post_meta( $order_id, '_billing_checkout', sanitize_text_field( $_POST['billing_checkout'] ) ); } } // 在后台订单详情页显示日期 add_action( 'woocommerce_admin_order_data_after_billing_address', 'display_checkin_checkout_dates_in_admin' ); function display_checkin_checkout_dates_in_admin( $order ) { echo '<p><strong>' . __( 'Check In Date', 'woocommerce' ) . ':</strong> ' . get_post_meta( $order->get_id(), '_billing_checkin', true ) . '</p>'; echo '<p><strong>' . __( 'Check Out Date', 'woocommerce' ) . ':</strong> ' . get_post_meta( $order->get_id(), '_billing_checkout', true ) . '</p>'; } // 在订单邮件里显示日期 add_action( 'woocommerce_email_after_order_table', 'display_checkin_checkout_dates_in_emails', 20, 4 ); function display_checkin_checkout_dates_in_emails( $order, $sent_to_admin, $plain_text, $email ) { echo '<h3>' . __( 'Stay Dates', 'woocommerce' ) . '</h3>'; echo '<p><strong>' . __( 'Check In', 'woocommerce' ) . ':</strong> ' . get_post_meta( $order->get_id(), '_billing_checkin', true ) . '</p>'; echo '<p><strong>' . __( 'Check Out', 'woocommerce' ) . ':</strong> ' . get_post_meta( $order->get_id(), '_billing_checkout', true ) . '</p>'; }
为什么你原来的方法没生效?
- 直接改核心文件:WooCommerce更新会覆盖,而且你给两个字段设了相同的
id="datepicker",导致JS无法正确识别。 - JS选择器错误:你用的
#sandbox-container .input-daterange和WooCommerce结账字段的DOM结构完全不匹配。 - 未加载Datepicker组件:默认WordPress不加载jQuery UI的Datepicker,必须手动引入。
内容的提问来源于stack exchange,提问作者marcin
相关产品推荐
相关产品推荐

