我正在尝试向我的 WooCommerce 网站添加自定义字段,以根据客户在选择产品变体时选择的保修状态更新价格。具体来说,我希望根据保修是否过期、1-6个月内、6个月以上或未激活来调整价格。
我已经实现了以下代码,它可以在页面上正确显示保修选项和调整后的价格。然而,当变化变化时,价格不会正确更新,从而导致计算错误。这是我的代码:
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
}
主要问题:当用户在版本之间切换时,价格不会根据所选的保修状态正确更新。如何确保价格在变化时重新计算和更新? 我将不胜感激任何解决此问题的建议!谢谢!
首先,最好将变化保修价格 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);
})