求助:WooCommerce自定义复选框动态修改商品价格失效
问题:WooCommerce自定义复选框无法动态更新商品价格
我需要实现基于自定义复选框动态修改WooCommerce商品价格的功能:勾选复选框后实时更新商品显示价格,尤其是两个复选框同时勾选时的价格叠加计算。但目前的PHP和jQuery代码完全无法正常运行——我试过重构条件判断、新增函数,甚至测试用的alert都触发不了,根本达不到预期效果。
相关代码
测试用代码片段
jQuery测试代码
jQuery(function($) { var cb = 'input[name="extra1_option"]' cb1 = 'input[name="extra2_option"]' cb2 = 'input[name="extra1_option"], input[name="extra2_option"]' pp = 'price'; $(cb2).on( 'change', function(){ if( $(cb).prop('checked') === true){ $(pp).html('<?php echo $disp_price_sum_p_html; ?>'); } else if( $(cb1).prop('checked') === true){ $(pp).html('<?php echo $disp_price_sum_n_html; ?>'); } else if( ($(cb).is(':checked') === true) && ($(cb1).prop('checked') === true)){ $(pp).html('<?php echo $disp_price_sum_pn_html; ?>'); } else $(pp).html('<?php echo $active_price_html; ?>'); }) });
测试用HTML/PHP代码
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.7.1/jquery.min.js"></script> <?php $active_price = 100; $extra_price1 = 2; $extra_price2 = 3; $extra_price1_html = 2; $extra_price2_html = 3; $active_price_html = 100; $disp_price_sum_n_html = $active_price + $extra_price1; $disp_price_sum_n_html = $active_price + $extra_price2; $disp_price_sum_pn_html = $active_price + $extra_price1 + $extra_price2; echo '<div class="hidden-field"> <p class="form-row form-row-wide" id="extra1_option_field" data-priority=""> <label class="checkbox"> Extra Field 1: '. ' <input type="checkbox" class="input-checkbox " name="extra1_option" id="extra1_option" value="extra1"> + ' . $extra_price1_html .'</label></span></p> <input type="hidden" name="extra_price1" value="' . $extra_price1 . '"> <p class="form-row form-row-wide" id="extra2_option_field" data-priority=""> <label class="checkbox"> Extra Field 2: '. ' <input type="checkbox" class="input-checkbox " name="extra2_option" id="extra2_option" value="extra2"> + ' . $extra_price2_html . '</label></span></p> <input type="hidden" name="extra_price1" value="' . $extra_price1 . '"> <input type="hidden" name="extra_price2" value="' . $extra_price2 . '"> <input type="hidden" name="active_price" value="' . $active_price . '"> <p>Price: ' . $active_price .'</p> </div>'; ?>
正式PHP函数
function product_option_custom_field(){ global $product; $active_price = (float) $product->get_price(); $extra_price1 = (float) $product->get_meta( '_extra_field1' ); $extra_price2 = (float) $product->get_meta( '_extra_field2' ); $extra_price1_html = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $extra_price1 ) ) ) ); $extra_price2_html = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $extra_price2 ) ) ) ); $active_price_html = wc_price( wc_get_price_to_display( $product ) ); $disp_price_sum_p_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price1) ) ); $disp_price_sum_n_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price2) ) ); $disp_price_sum_pn_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price1 + $extra_price2) ) ); echo '<div class="hidden-field"> <p class="form-row form-row-wide" id="extra1_option_field" data-priority=""> <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Extra Field 1:", "Woocommerce") . ' <input type="checkbox" class="input-checkbox " name="extra1_option" id="extra1_option" value="1"> + ' . $extra_price1_html . '</label></span></p> <input type="hidden" name="extra_price2" value="' . $extra_price2 . '"> <p class="form-row form-row-wide" id="extra2_option_field" data-priority=""> <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Extra field 2:", "Woocommerce") . ' <input type="checkbox" class="input-checkbox " name="extra2_option" id="extra2_option" value="1"> + ' . $extra_price2_html . '</label></span></p> <input type="hidden" name="extra_price2" value="' . $extra_price2 . '"> <input type="hidden" name="active_price" value="' . $active_price . '"></div>'; }
正式jQuery代码
<script type="text/javascript"> jQuery(function($) { var cb = 'input[name="extra1_option"]' cb1 = 'input[name="extra2_option"]' cb2 = 'input[name="extra1_option"], input[name="extra2_option"]' pp = 'p.price'; $(cb2).on( 'change', function(){ if( $(cb).prop('checked') === true){ $(pp).html('<?php echo $disp_price_sum_p_html; ?>'); } else if( $(cb1).prop('checked') === true){ $(pp).html('<?php echo $disp_price_sum_n_html; ?>'); } else if( ($(cb).is(':checked') === true) && ($(cb1).prop('checked') === true)){ $(pp).html('<?php echo $disp_price_sum_pn_html; ?>'); } else $(pp).html('<?php echo $active_price_html; ?>'); }) }); </script>
测试用函数
const updatePrice = () => { var extra1Checked = $('input[name="extra1_option"]').is(':checked'); var extra2Checked = $('input[name="extra2_option"]').is(':checked'); if (extra1Checked && extra2Checked) alert("a"); else if (extra1Checked) alert("a1"); else if (extra2Checked) alert("a2"); $priceParagraph.html($priceParagraph.data(priceData)); } $('div.hidden-field input.input-checkbox').on('change', updatePrice); updatePrice(); });
解决方案
问题排查
- JS变量语法错误:所有变量定义缺少分号,导致代码解析失败。
- 条件判断顺序错误:同时勾选的判断放在单个勾选之后,永远不会触发(单个勾选条件会先匹配)。
- DOM选择器问题:测试代码中
pp = 'price'未指定元素类型,正式代码需确保价格元素类名是price。 - PHP笔误:测试用PHP重复赋值
$disp_price_sum_n_html,正式PHP重复输出name="extra_price2"的隐藏域。 - 测试函数语法错误:末尾多了
});,且$priceParagraph未定义。
修复后的完整代码
修正后的PHP函数
function product_option_custom_field(){ global $product; $active_price = (float) $product->get_price(); $extra_price1 = (float) $product->get_meta( '_extra_field1' ); $extra_price2 = (float) $product->get_meta( '_extra_field2' ); $extra_price1_html = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $extra_price1 ) ) ) ); $extra_price2_html = strip_tags( wc_price( wc_get_price_to_display( $product, array('price' => $extra_price2 ) ) ) ); $active_price_html = wc_price( wc_get_price_to_display( $product ) ); $disp_price_sum_p_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price1) ) ); $disp_price_sum_n_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price2) ) ); $disp_price_sum_pn_html = wc_price( wc_get_price_to_display( $product, array('price' => $active_price + $extra_price1 + $extra_price2) ) ); echo '<div class="hidden-field"> <p class="form-row form-row-wide" id="extra1_option_field" data-priority=""> <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Extra Field 1:", "woocommerce") . ' <input type="checkbox" class="input-checkbox " name="extra1_option" id="extra1_option" value="1"> + ' . $extra_price1_html . '</label></span></p> <input type="hidden" name="extra_price1" value="' . $extra_price1 . '"> <p class="form-row form-row-wide" id="extra2_option_field" data-priority=""> <span class="woocommerce-input-wrapper"><label class="checkbox"> ' . __("Extra field 2:", "woocommerce") . ' <input type="checkbox" class="input-checkbox " name="extra2_option" id="extra2_option" value="1"> + ' . $extra_price2_html . '</label></span></p> <input type="hidden" name="extra_price2" value="' . $extra_price2 . '"> <input type="hidden" name="active_price" value="' . $active_price . '"></div>'; } // 挂钩到WooCommerce商品页面 add_action('woocommerce_single_product_summary', 'product_option_custom_field', 25);
修正后的jQuery代码
<script type="text/javascript"> jQuery(function($) { // 修正变量定义,添加分号 var cb = 'input[name="extra1_option"]'; var cb1 = 'input[name="extra2_option"]'; var cb2 = 'input[name="extra1_option"], input[name="extra2_option"]'; var pp = 'p.price'; // 确保选择器正确指向价格元素 $(cb2).on('change', function(){ // 调整判断顺序,先检查同时勾选的情况 if ($(cb).is(':checked') && $(cb1).is(':checked')) { $(pp).html('<?php echo $disp_price_sum_pn_html; ?>'); } else if ($(cb).is(':checked')) { $(pp).html('<?php echo $disp_price_sum_p_html; ?>'); } else if ($(cb1).is(':checked')) { $(pp).html('<?php echo $disp_price_sum_n_html; ?>'); } else { $(pp).html('<?php echo $active_price_html; ?>'); } }); // 页面加载时初始化价格状态 $(cb2).trigger('change'); }); </script>
额外注意事项
- 确认WooCommerce商品价格元素确实使用
p.price类,若结构不同需调整选择器。 - 若为可变商品,需额外处理变体切换时的价格重置逻辑。
- 如需将额外价格同步到购物车,需添加
woocommerce_add_cart_item_data和woocommerce_get_cart_item_from_session等钩子处理价格计算。
内容的提问来源于stack exchange,提问作者Mat Czer
相关产品推荐
相关产品推荐

