基于邮政编码动态更新Woocommerce结账页单选自定义字段选项
实现方案
你需要新增AJAX处理逻辑+前端监听代码,和你现有的自定义字段代码配合即可实现需求,完整操作如下:
1. 保留你现有的自定义字段代码
你贴的原有代码不需要修改,继续放在主题functions.php文件或者自定义功能插件中即可。
2. 新增后端AJAX接口,用于根据邮编返回对应配送时段
把以下代码同样加到functions.php或者自定义插件中:
// 注册AJAX接口(登录用户可用) add_action('wp_ajax_get_delivery_hours_by_postcode', 'cc_get_delivery_hours'); // 注册AJAX接口(未登录用户可用) add_action('wp_ajax_nopriv_get_delivery_hours_by_postcode', 'cc_get_delivery_hours'); function cc_get_delivery_hours() { // 校验请求合法性 if (!isset($_POST['postcode']) || empty($_POST['postcode'])) { wp_send_json_error(['msg' => '邮编不能为空']); } $postcode = sanitize_text_field($_POST['postcode']); // 这里按照你的业务规则配置邮编和配送时段的映射关系,以下为示例 $allowed_hours = []; // 示例:邮编开头为10001的区域可配送时段为11点到17点半 if (str_starts_with($postcode, '10001')) { $allowed_hours = [ '' => __('Select:'), 'F1' => __('11:00 – 13:00'), 'F2' => __('13:00 – 15:00'), 'F3' => __('16:00 – 17:30') ]; } // 示例:邮编开头为10002的区域可配送时段为16点到21点 elseif (str_starts_with($postcode, '10002')) { $allowed_hours = [ '' => __('Select:'), 'F3' => __('16:00 – 17:30'), 'F4' => __('17:30 – 19:00'), 'F5' => __('19:00 – 21:00') ]; } // 其他邮编默认返回全部时段 else { $allowed_hours = [ '' => __('Select:'), 'F1' => __('11:00 – 13:00'), 'F2' => __('13:00 – 15:00'), 'F3' => __('16:00 – 17:30'), 'F4' => __('17:30 – 19:00'), 'F5' => __('19:00 – 21:00') ]; } wp_send_json_success($allowed_hours); }
3. 新增前端监听代码,实现邮编变更时同步更新单选选项
把以下代码同样加到functions.php或者自定义插件中,作用是在结账页注入JS逻辑:
add_action('woocommerce_after_checkout_form', 'cc_delivery_hours_sync_script'); function cc_delivery_hours_sync_script() { ?> <script> jQuery(document).ready(function($) { // 节流函数,避免频繁触发请求 let timer = null; function updateDeliveryHours() { const postcode = $('#billing_postcode').val().trim(); if (postcode.length < 4) return; // 邮编长度不够时不触发请求,可自行调整阈值 clearTimeout(timer); timer = setTimeout(function() { $.ajax({ url: '<?php echo admin_url('admin-ajax.php'); ?>', type: 'POST', data: { action: 'get_delivery_hours_by_postcode', postcode: postcode }, beforeSend: function() { // 加载时禁用单选框,避免用户操作 $('#deliveryhours_field').block({message: null, overlayCSS: {background: '#fff', opacity: 0.6}}); }, success: function(res) { if (res.success) { const hoursOptions = res.data; const $radioWrap = $('#deliveryhours_field .woocommerce-input-wrapper'); // 清空原有选项 $radioWrap.empty(); // 遍历生成新的单选选项 $.each(hoursOptions, function(key, label) { const radioId = 'deliveryhours_' + key; $radioWrap.append(` <p class="form-row form-row-wide"> <input type="radio" class="input-radio" name="deliveryhours" id="${radioId}" value="${key}" /> <label for="${radioId}" class="radio">${label}</label> </p> `); }); } }, complete: function() { $('#deliveryhours_field').unblock(); } }); }, 500); // 输入停止500毫秒后触发请求,可自行调整 } // 页面初始化时触发一次 updateDeliveryHours(); // 监听邮编输入变更事件 $('body').on('change input', '#billing_postcode', updateDeliveryHours); // 监听地址自动填充事件(兼容Woocommerce地址自动补全功能) $('body').on('updated_checkout', updateDeliveryHours); }); </script> <?php }
注意事项
- 你可以自行修改
cc_get_delivery_hours函数中的邮编和配送时段映射规则,匹配你的实际业务需求 - 如果你的结账页邮编字段ID不是
billing_postcode,替换成你实际使用的字段ID即可 - 测试时注意清空浏览器缓存和Woocommerce购物车缓存,避免旧代码影响效果
内容的提问来源于stack exchange,提问作者Joruus
相关产品推荐
相关产品推荐

