You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

WooCommerce商品详情页下拉选择后价格无法动态更新问题

WooCommerce动态定价Ajax修复方案

以下是针对你的动态定价插件Ajax失效问题的具体修复步骤,覆盖PHP、Ajax处理、前端JS三个核心部分:

核心问题梳理

  1. 未向前端传递Ajax必需的本地化参数(wc_price_calculator_params)
  2. 下拉框绑定的updateDescription()函数未定义,导致前端报错中断逻辑
  3. 钻石品质下拉的sendSelectedData函数缺失,且未将该参数传入Ajax请求
  4. 初始价格显示标签被注释,前端无法找到更新目标元素
  5. Ajax请求未正确终止,可能导致响应异常

1. PHP端代码修复(添加本地化参数与修正输出)

修改add_to_cart_product_pricing函数,补充脚本本地化传递,移除无效的onchange绑定,恢复初始价格显示:

add_action('woocommerce_before_add_to_cart_button', 'add_to_cart_product_pricing');
function add_to_cart_product_pricing()
{
    global $product;
    // 注册并本地化JS脚本,传递Ajax参数
    wp_enqueue_script('price-calculator', plugins_url('jewellery_pricing/assets/js/price-calculator.js', __FILE__), array('jquery'), '1.0', true);
    wp_localize_script('price-calculator', 'wc_price_calculator_params', array(
        'ajax_url' => admin_url('admin-ajax.php'),
        'nonce'    => wp_create_nonce('price_calculator_nonce')
    ));
    
    wp_enqueue_style('my-plugin-styles', plugins_url("jewellery_pricing/assets/css/diamond_style.css", __FILE__));

    if (is_product() && has_term(array('ring', 'rings'), 'product_cat')) {
        extract(get_all_product_data($product, true));

        $metal_purity_percent = get_metal_purity($metal_purity);
        $gold_value = ($gold_rate * $metal_purity_percent) / 100;
        $finalgold = $gold_value * $net_weight;

        // 恢复初始价格显示,确保前端有更新目标
        printf('<p class="gold-price" style="font-size: 28px;">%s</p>', get_displayed_price_html($finalgold, $product));

        echo '<div class="row">';
        // 戒指尺寸下拉
        echo '<div class="col-md-6"><label class="label_style" for="ring-size">' . __("Ring Size") . ':<br>
        <select id="ring-size" name="ring_size" class="selectoptionfield">';
        foreach (get_ring_sizes() as $ring_size) {
            printf('<option value="%s"%s>%s</option>', $ring_size, selected($ring_size, $def_ring_size), $ring_size);
        }
        echo '</select></div>';

        // 金属纯度下拉
        echo '<div class="col-md-6"><label for="metal-purity">' . __("Metal Purity") . ':<br>
        <select id="metal-purity" name="metal_purity" class="selectoptionfield">';
        foreach (get_metal_purity_14k_18k() as $purity) {
            printf('<option value="%s"%s>%s</option>', $purity, selected($purity, $metal_purity), $purity);
        }
        echo '</select></div>';

        // 钻石品质下拉
        echo '<div class="col-md-12"><label for="diamond-quality">' . __("Diamond Quality") . ':<br>
        <select id="diamond-quality" name="diamond_quality" class="selectoptionfield">';
        foreach (get_diamondqualityall() as $quality) {
            printf('<option value="%s"%s>%s</option>', $quality, selected($quality, $diamond_quality), $quality);
        }
        echo '</select></div>';

        echo '<input type="hidden" id="updated_gold_price" name="updated_gold_price" value="' . $finalgold. '" /></div>';
    }
}

2. Ajax处理函数修复(支持钻石品质参数与正确终止请求)

修改update_gold_price函数,补充钻石品质参数接收,添加请求终止逻辑:

add_action('wp_ajax_update_gold_price', 'update_gold_price');
add_action('wp_ajax_nopriv_update_gold_price', 'update_gold_price');
function update_gold_price()
{
    check_ajax_referer('price_calculator_nonce', 'security');

    if (isset($_REQUEST['product_data']) && !empty($_REQUEST['product_data'])) {
        $data = (array) $_REQUEST['product_data'];

        if (
            isset($data['product_id'], $data['ring_size'], $data['metal_purity'], $data['diamond_quality']) &&
            !empty($data['product_id']) && !empty($data['ring_size']) && !empty($data['metal_purity']) && !empty($data['diamond_quality'])
        ) {
            $product = wc_get_product(intval($data['product_id']));
            extract(get_all_product_data($product, true));

            $ring_size = esc_attr($data['ring_size']);
            $metal_purity = esc_attr($data['metal_purity']);
            $diamond_quality = esc_attr($data['diamond_quality']);

            // 基础价格计算
            $metal_purity_percent = get_metal_purity($metal_purity);
            $ring_grams_percent = get_ring_grams_percentage($ring_size);
            $gold_value = (($gold_rate * $metal_purity_percent) / 100);

            // 根据戒指尺寸调整金重价格
            if ($def_ring_size < $ring_size) {
                $net_weight_adj = $net_weight + $ring_grams_percent;
            } elseif ($def_ring_size === $ring_size) {
                $net_weight_adj = $net_weight;
            } else {
                $net_weight_adj = $net_weight - $ring_grams_percent;
            }
            $gold_price = $gold_value * $net_weight_adj;

            // 加入钻石品质价格(需确保get_diamond_price函数存在)
            $diamond_price = get_diamond_price($diamond_quality);
            $final_price = $gold_price + $diamond_price;

            // 返回JSON响应
            echo json_encode(array(
                'raw' => $final_price,
                'html' => get_displayed_price_html($final_price, $product)
            ));
        }
    }
    wp_die(); // 必须终止Ajax请求,避免多余输出
} 

3. 前端JS修复(统一逻辑与补全缺失函数)

修改price-calculator.js,统一价格更新逻辑,补全缺失的函数定义:

jQuery(function ($) {
  if (typeof wc_price_calculator_params === 'undefined') return false;

  // 初始化表单与参数
  var $form = $('form.cart'),
      ringSize = $('select#ring-size').val(),
      metalPurity = $('select#metal-purity').val(),
      diamondQuality = $('select#diamond-quality').val(),
      productId = $form.find('button[name=add-to-cart]').val();

  // 统一价格更新函数
  function updatePrice() {
    $.ajax({
      type: 'POST',
      url: wc_price_calculator_params.ajax_url,
      data: {
        action: 'update_gold_price',
        product_data: {
          product_id: productId,
          ring_size: ringSize,
          metal_purity: metalPurity,
          diamond_quality: diamondQuality
        },
        security: wc_price_calculator_params.nonce,
      },
      success: function (res) {
        var response = $.parseJSON(res);
        $('#updated_gold_price').val(response.raw);
        $('.gold-price').html(response.html);
      },
      error: function (err) {
        console.error('价格更新失败:', err);
      },
    });
  }

  // 绑定下拉框change事件
  $form.on('change', 'select#ring-size', function () {
    ringSize = $(this).val();
    updatePrice();
  });

  $form.on('change', 'select#metal-purity', function () {
    metalPurity = $(this).val();
    updatePrice();
  });

  $form.on('change', 'select#diamond-quality', function () {
    diamondQuality = $(this).val();
    updatePrice();
  });

  // 补全原绑定的缺失函数,避免控制台报错
  window.updateDescription = function() {
    // 可添加描述更新逻辑(如根据选择修改产品详情)
  };

  window.sendSelectedData = function() {
    updatePrice(); // 复用价格更新逻辑
  };
});

额外检查项

  1. 确保get_all_product_data、get_diamond_price等自定义函数能正确返回数据
  2. 打开浏览器控制台,检查是否有404(脚本路径错误)或500(PHP逻辑错误)
  3. 可在Ajax函数中临时添加wp_die(print_r($_REQUEST, true))调试参数接收情况

内容的提问来源于stack exchange,提问作者Nilima Bose

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.28 15:15:53