WooCommerce 变体更改的自定义字段选项价格更新问题

问题描述 投票:0回答:1

我正在尝试向我的 WooCommerce 网站添加自定义字段,以根据客户在选择产品变体时选择的保修状态更新价格。具体来说,我希望根据保修是否过期、1-6个月内、6个月以上或未激活来调整价格。

screenshot

我已经实现了以下代码,它可以在页面上正确显示保修选项和调整后的价格。然而,当变化变化时,价格不会正确更新,从而导致计算错误。这是我的代码:

add_action('woocommerce_single_variation', 'add_custom_options', 5);
function add_custom_options() {
    ?>
    <div class="custom-options-wrapper" style="width: 100%;">
        <h4>Great, let's talk about the more details:</h4>
        <div class="custom-warranty-option" style="margin-bottom: 20px;">
            <label>1. Is it still under warranty?</label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="no" required> No, the warranty has expired.
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="1-6months" required> Yes, 1-6 months warranty
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="over6months" required> Yes, over 6 months warranty
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="unactivated" required> Yes, 1 year warranty & unactivated
            </label>
        </div>
    </div>

    <script type="text/javascript">
    jQuery(document).ready(function($) {
        var originalPrice;

        function getOriginalPrice() {
            var priceText = $('.woocommerce-variation-price .woocommerce-Price-amount.amount').first().text();
            return parseFloat(priceText.replace(/[^\d.]/g, ''));
        }

        function updatePrice() {
            if (isNaN(originalPrice)) {
                originalPrice = getOriginalPrice();
            }

            var warrantyMultiplier = 1.00;

            if ($('input[name="warranty_status"]:checked').val() === 'no') {
                warrantyMultiplier = 0.90; // No warranty, deduct 10%
            } else if ($('input[name="warranty_status"]:checked').val() === '1-6months') {
                warrantyMultiplier = 0.92; // 1-6 months warranty, deduct 8%
            } else if ($('input[name="warranty_status"]:checked').val() === 'over6months') {
                warrantyMultiplier = 0.95; // Over 6 months warranty, deduct 5%
            }

            var newPrice = Math.round(originalPrice * warrantyMultiplier);

            $('.woocommerce-variation-price .woocommerce-Price-amount.amount').html('<bdi><span class="woocommerce-Price-currencySymbol">$</span>' + newPrice + '</bdi>');

            // Update hidden input to ensure the new price is used when added to the cart
            $('#custom_price').val(newPrice);
        }

        // Clear the selected state of all custom options
        function resetCustomOptions() {
            $('input[name="warranty_status"]').prop('checked', false);
        }

        $('form.variations_form').on('woocommerce_variation_has_changed', function() {
            resetCustomOptions();  // Reset custom options
            originalPrice = getOriginalPrice();  // Get new price each time a variation is switched
            updatePrice();
        });

        $('input[name="warranty_status"]').change(function() {
            updatePrice();
        });

        originalPrice = getOriginalPrice();
        updatePrice();
    });
    </script>
   
    <?php
}

主要问题:当用户在版本之间切换时,价格不会根据所选的保修状态正确更新。如何确保价格在变化时重新计算和更新? 我将不胜感激任何解决此问题的建议!谢谢!

php jquery wordpress woocommerce product-variations
1个回答
0
投票

首先,最好将变化保修价格 HTML 包含到可变产品数据表单中。然后您应该使用 WooCommerce 变体 JS 事件来设置您的价格。

尝试以下修改后的代码:

// Add variation warranty prices html to the variable product data form
add_action( 'woocommerce_available_variation', 'add_variation_custom_warranty_prices_html', 10, 3 );
function add_variation_custom_warranty_prices_html( $variation_data, $product, $variation ) {
    $variation_data['warranty_prices'] = array(
        'no'            => wc_price($variation_data['display_price'] * 0.9),
        '1-6months'     => wc_price($variation_data['display_price'] * 0.92),
        'over6months'   => wc_price($variation_data['display_price'] * 0.95),
        'inactivated'   => wc_price($variation_data['display_price']),
    );
    return  $variation_data;
}

add_action( 'woocommerce_single_variation', 'add_custom_warranty_options', 5 );
function add_custom_warranty_options() {
    // HTML output
    echo '<div class="custom-options-wrapper" style="width: 100%;">
        <h4>'. esc_html__("Great, let's talk about the more details:") . '</h4>
        <div class="custom-warranty-option" style="margin-bottom: 20px;">
            <label>'. esc_html__("1. Is it still under warranty?") . '</label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="no" required> '. esc_html__("No, the warranty has expired.") . '
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="1-6months" required> '. esc_html__("Yes, 1-6 months warranty") . '
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="over6months" required> '. esc_html__("Yes, over 6 months warranty") . '
            </label>
            <label style="display: block;">
                <input type="radio" name="warranty_status" value="inactivated" required> '. esc_html__("Yes, 1 year warranty & inactivated") . '
            </label>
        </div>
    </div>';

    // Enqueued Javascript
    wc_enqueue_js( "var warrantyPrices = undefined, selectedWarranty = undefined;
    function updateVariationPriceHtml( warrantyPrices, selectedWarranty ) {
        $.each( warrantyPrices, function( warrantyOption, priceHtml ){
            if( warrantyPrices === undefined || selectedWarranty === undefined ) {
                return false;
            }
            if ( selectedWarranty === warrantyOption ) {
                $('.woocommerce-variation-price > .price').html(priceHtml);
            }
        });
    }

    $('form.variations_form').on('show_variation', function(event, data){ 
        warrantyPrices = data.warranty_prices;
        updateVariationPriceHtml( warrantyPrices, selectedWarranty );
    }).on('hide_variation', function() {
        warrantyPrices = selectedWarranty = undefined;
        $('input[name=warranty_status]').prop('checked', false);
    }).on('change', 'input[name=warranty_status]', function(){
        selectedWarranty = $(this).val();
        updateVariationPriceHtml( warrantyPrices, selectedWarranty );
    });" );
}

代码位于子主题的functions.php文件中(或插件中)。

现在可以正常工作了。


添加: 在版本更改时重置所选的保修选项

要重置变体更改时选择的保修选项,您可以更改“show_variation”JS 事件,例如:

$('form.variations_form').on('show_variation', function(event, data){ 
    warrantyPrices = data.warranty_prices;
    selectedWarranty = undefined;
    $('input[name=warranty_status]').prop('checked', false);
})
© www.soinside.com 2019 - 2024. All rights reserved.