基于商品ID隐藏WooCommerce结账页面自定义复选框
WooCommerce:特定商品加入购物车时无法隐藏自定义结账复选框
现有功能代码(结账页添加复选框并添加额外费用)
这段代码用于在WooCommerce结账页面添加一个复选框,勾选后会为订单增加30₾的包装费用:
add_action('woocommerce_after_checkout_billing_form', 'checkout_shipping_form_packing_addition', 20); function checkout_shipping_form_packing_addition() { $domain = 'woocommerce'; echo '<tr class="packing-select"><th>' . __('სამაჯური', $domain) . '</th><td>'; $chosen = WC()->session->get('chosen_packing'); // 添加自定义复选框字段 woocommerce_form_field('chosen_packing', array( 'type' => 'checkbox', 'class' => array('form-row-wide packing'), 'label' => __('სამაჯურის ღირებულება 30₾', 'woocommerce'), 'description' => __('აღნიშნული სერვისით სარგებლობისთვის საჭიროა სამაჯურის შეძენა, თუ გსურთ შეძენა, მონიშნეთ ეს ველი, თუ უკვე გაქვთ სამაჯური ან ადგილზე გადაიხდით სამაჯურის ღირებულებას დატოვეთ მონიშვნის გარეშე'), 'required' => false, ), $chosen); echo '</td></tr>'; } // jQuery - Ajax 脚本 add_action('wp_footer', 'checkout_shipping_packing_script'); function checkout_shipping_packing_script() { // 仅在结账页执行 if (is_checkout() && !is_wc_endpoint_url()) : ?> <script type="text/javascript"> jQuery(function($) { $('form.checkout').on('change', 'input#chosen_packing', function() { $.ajax({ type: 'POST', url: wc_checkout_params.ajax_url, data: { 'action': 'woo_get_ajax_data', 'packing': $(this).prop('checked') ? 1 : 0, }, success: function(result) { $('body').trigger('update_checkout'); console.log('response: ' + result); // 测试用,可删除 }, error: function(error) { console.log(error); // 测试用,可删除 } }); }); }); </script> <?php else: WC()->session->__unset('chosen_packing'); endif; } // PHP Ajax(接收请求并保存到WC会话) add_action('wp_ajax_woo_get_ajax_data', 'woo_get_ajax_data'); add_action('wp_ajax_nopriv_woo_get_ajax_data', 'woo_get_ajax_data'); function woo_get_ajax_data() { if (isset($_POST['packing'])) { $packing = sanitize_key($_POST['packing']); WC()->session->set('chosen_packing', $packing); echo json_encode($packing); } die(); // 必须放在最后,避免500错误 } // 添加自定义动态包装费用 add_action('woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1); function add_packaging_fee($cart) { if (is_admin() && !defined('DOING_AJAX')) return; if( WC()->session->get('chosen_packing') ){ $label = __('სამაჯური', 'woocommerce'); $cost = 30; $cart->add_fee($label, $cost); } }
尝试的无效代码(隐藏复选框)
尝试用以下代码在商品ID为15163的商品加入购物车时隐藏该复选框,但无效(该方法对标准账单字段有效,但对这个自定义复选框无效):
add_filter( 'woocommerce_checkout_fields' , 'disabling' ); function disabling($fields){ $product_id = array(15163); // 触发隐藏的商品ID $in_cart = false; foreach( WC()->cart->get_cart() as $cart_item ) { $product_in_cart = $cart_item['product_id']; if ( $product_in_cart === $product_id ) $in_cart = true; // 检查商品是否在购物车中 } if ( $in_cart ){ unset($fields['billing']['chosen_packing']); unset($fields['shipping']['chosen_packing']); return $fields; } else { return $fields; } }
问题原因及解决方案
问题原因
你尝试的代码无效,是因为这个自定义复选框并非通过woocommerce_checkout_fields过滤器注册的标准字段,而是直接通过woocommerce_after_checkout_billing_form钩子输出到页面的,所以无法通过unset($fields['billing']['chosen_packing'])来移除它。
解决方案
修改原来的checkout_shipping_form_packing_addition函数,先判断购物车中是否包含指定商品,再决定是否输出复选框:
add_action('woocommerce_after_checkout_billing_form', 'checkout_shipping_form_packing_addition', 20); function checkout_shipping_form_packing_addition() { // 检查购物车是否包含ID为15163的商品 $target_product_id = 15163; $in_cart = false; foreach( WC()->cart->get_cart() as $cart_item ) { if ( $cart_item['product_id'] === $target_product_id ) { $in_cart = true; break; } } // 如果包含目标商品,直接返回,不输出复选框 if ($in_cart) { return; } // 原有的复选框输出代码 $domain = 'woocommerce'; echo '<tr class="packing-select"><th>' . __('სამაჯური', $domain) . '</th><td>'; $chosen = WC()->session->get('chosen_packing'); woocommerce_form_field('chosen_packing', array( 'type' => 'checkbox', 'class' => array('form-row-wide packing'), 'label' => __('სამაჯურის ღირებულება 30₾', 'woocommerce'), 'description' => __('აღნიშნული სერვისით სარგებლობისთვის საჭიროა სამაჯურის შეძენა, თუ გსურთ შეძენა, მონიშნეთ ეს ველი, თუ უკვე გაქვთ სამაჯური ან ადგილზე გადაიხდით სამაჯურის ღირებულებას დატოვეთ მონიშვნის გარეშე'), 'required' => false, ), $chosen); echo '</td></tr>'; }
同时,为了避免用户在添加目标商品前已经勾选了复选框,还需要修改add_packaging_fee函数,确保购物车中有目标商品时不添加包装费用:
// 添加自定义动态包装费用 add_action('woocommerce_cart_calculate_fees', 'add_packaging_fee', 20, 1); function add_packaging_fee($cart) { if (is_admin() && !defined('DOING_AJAX')) return; // 检查购物车是否包含目标商品 $target_product_id = 15163; $in_cart = false; foreach( $cart->get_cart() as $cart_item ) { if ( $cart_item['product_id'] === $target_product_id ) { $in_cart = true; break; } } // 如果没有目标商品且勾选了复选框,才添加费用 if( !$in_cart && WC()->session->get('chosen_packing') ){ $label = __('სამაჯური', 'woocommerce'); $cost = 30; $cart->add_fee($label, $cost); } }
这样修改后,当购物车中加入ID为15163的商品时,结账页的包装复选框会被隐藏,同时也不会再添加对应的包装费用。
内容的提问来源于stack exchange,提问作者Irakli Mosidze
相关产品推荐
相关产品推荐

