下面的代码适用于使用 WooCommerce 添加到购物车的简单产品,但不适用于可变产品。有人可以帮我吗?因为此代码适用于最新的 WC,所以请不要删除此问题,因为网上有很多此代码根本不起作用。
我收到的错误是在通知中说我应该选择一个产品选项,即使我选择了一个。
JS:
jQuery(function($) {
$('form.cart').on('submit', function(e) {
e.preventDefault();
var form = $(this);
form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });
var formData = new FormData(form.context);
formData.append('add-to-cart', form.find('[name=add-to-cart]').val() );
var $thisbutton = form.find('.single_add_to_cart_button'); //
// Ajax action
$.ajax({
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'ace_add_to_cart' ),
data: formData,
type: 'POST',
processData: false,
contentType: false,
beforeSend: function (response) {
$thisbutton.removeClass('added').addClass('loading');
},
complete: function( response ) {
response = response.responseJSON;
if ( ! response ) {
return;
}
if ( response.error && response.product_url ) {
window.location = response.product_url;
return;
}
// Redirect to cart option
if ( wc_add_to_cart_params.cart_redirect_after_add === 'yes' ) {
window.location = wc_add_to_cart_params.cart_url;
return;
}
// Trigger event so themes can refresh other areas.
$( document.body ).trigger( 'added_to_cart', [ response.fragments, response.cart_hash, $thisbutton ] );
// Remove existing notices
$( '.woocommerce-error, .woocommerce-message, .woocommerce-info' ).remove();
// Add new notices
form.closest('.product').before(response.fragments.notices_html)
form.unblock();
}
});
});
});
PHP:
/* WOOCOMMERCE AJAX ADD TO CART
--------------------------------------------------- */
function ace_ajax_add_to_cart_handler() {
WC_Form_Handler::add_to_cart_action();
WC_AJAX::get_refreshed_fragments();
}
/* Add fragments for notices. */
function ace_ajax_add_to_cart_add_fragments( $fragments ) {
$all_notices = WC()->session->get( 'wc_notices', array() );
$notice_types = apply_filters( 'woocommerce_notice_types', array( 'error', 'success', 'notice' ) );
ob_start();
foreach ( $notice_types as $notice_type ) {
if ( wc_notice_count( $notice_type ) > 0 ) {
wc_get_template( "notices/{$notice_type}.php", array(
'messages' => array_filter( $all_notices[ $notice_type ] ),
'notices' => array_filter( $all_notices[ $notice_type ] ),
) );
}
}
$fragments['notices_html'] = ob_get_clean();
wc_clear_notices();
return $fragments;
}
add_action( 'wc_ajax_ace_add_to_cart', 'ace_ajax_add_to_cart_handler' );
add_action( 'wc_ajax_nopriv_ace_add_to_cart', 'ace_ajax_add_to_cart_handler' );
remove_action( 'wp_loaded', array( 'WC_Form_Handler', 'add_to_cart_action' ), 20 ); // Remove WC Core add to cart handler to prevent double-add
add_filter( 'woocommerce_add_to_cart_fragments', 'ace_ajax_add_to_cart_add_fragments' );
要在单一产品页面上为简单和可变产品启用Ajax添加到购物车,您需要一些不同的东西,构建自定义Ajax添加到购物车功能还可以处理自定义产品字段和购物车项目数据操作 (WooCommerce 默认 Ajax 添加到购物车不允许的内容)。
尝试在 WooCommerce 版本 4.9.0 上进行全面测试的以下操作:
add_action( 'wp_footer', 'single_product_ajax_add_to_cart_js_script' );
function single_product_ajax_add_to_cart_js_script() {
?>
<script>
(function($) {
$('form.cart').on('submit', function(e) {
e.preventDefault();
var form = $(this),
mainId = form.find('.single_add_to_cart_button').val(),
fData = form.serializeArray();
form.block({ message: null, overlayCSS: { background: '#fff', opacity: 0.6 } });
if ( mainId === '' ) {
mainId = form.find('input[name="product_id"]').val();
}
if ( typeof wc_add_to_cart_params === 'undefined' )
return false;
$.ajax({
type: 'POST',
url: wc_add_to_cart_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'custom_add_to_cart' ),
data : {
'product_id': mainId,
'form_data' : fData
},
success: function (response) {
$(document.body).trigger("wc_fragment_refresh");
$('.woocommerce-error,.woocommerce-message').remove();
$('input[name="quantity"]').val(1);
$('.content-area').before(response);
form.unblock();
// console.log(response);
},
error: function (error) {
form.unblock();
// console.log(error);
}
});
});
})(jQuery);
</script>
<?php
}
add_action( 'wc_ajax_custom_add_to_cart', 'custom_add_to_cart_handler' );
add_action( 'wc_ajax_nopriv_custom_add_to_cart', 'custom_add_to_cart_handler' );
function custom_add_to_cart_handler() {
if( isset($_POST['product_id']) && isset($_POST['form_data']) ) {
$product_id = $_POST['product_id'];
$variation = $cart_item_data = $custom_data = array(); // Initializing
$variation_id = 0; // Initializing
foreach( $_POST['form_data'] as $values ) {
if ( strpos( $values['name'], 'attributes_' ) !== false ) {
$variation[$values['name']] = $values['value'];
} elseif ( $values['name'] === 'quantity' ) {
$quantity = $values['value'];
} elseif ( $values['name'] === 'variation_id' ) {
$variation_id = $values['value'];
} elseif ( $values['name'] !== 'add_to_cart' ) {
$custom_data[$values['name']] = esc_attr($values['value']);
}
}
$product = wc_get_product( $variation_id ? $variation_id : $product_id );
// Allow product custom fields to be added as custom cart item data from $custom_data additional array variable
$cart_item_data = (array) apply_filters( 'woocommerce_add_cart_item_data', $cart_item_data, $product_id, $variation_id, $quantity, $custom_data );
// Add to cart
$cart_item_key = WC()->cart->add_to_cart( $product_id, $quantity, $variation_id, $variation, $cart_item_data );
if ( $cart_item_key ) {
// Add to cart successful notice
wc_add_notice( sprintf(
'<a href="%s" class="button wc-forward">%s</a> %d × "%s" %s' ,
wc_get_cart_url(),
__("View cart", "woocommerce"),
$quantity,
$product->get_name(),
__("has been added to your cart", "woocommerce")
) );
}
wc_print_notices(); // Return printed notices to jQuery response.
wp_die();
}
}
代码位于活动子主题(或活动主题)的functions.php 文件中。已测试并有效。所有通知均已启用并即时显示:
为此,我们使用
woocommerce_add_cart_item_data
在我们的自定义 Ajax 添加到购物车代码中启用了 WooCommerce 专用挂钩,允许将产品自定义字段添加为自定义购物车项目数据或动态操作购物车数据。如果我们使用以下代码添加产品自定义输入文本字段:
add_action( 'woocommerce_before_add_to_cart_button', 'product_additional_custom_fields' );
function product_additional_custom_fields() {
echo '<table class="variations" cellspacing="0" width="100px">
<tbody><tr>
<td class="label" style="width:100px"><label for="engraving">' . __("Engraving text") . '</label></td>
<td class="value">
<input type="text" name="engraving" id="engraving" value="" />
</td>
</tr></tbody>
</table>
</br>';
}
然后,如果您想将字段值作为自定义购物车项目数据传递,您将使用
add_filter( 'woocommerce_add_cart_item_data', 'add_cart_item_custom_data', 10, 5 );
function add_cart_item_custom_data( $cart_item_data, $product_id, $variation_id = 0, $quantity, $custom_data = array() ) {
if ( isset($custom_data['engraving']) && ! empty($custom_data['engraving']) ) {
$cart_item_data['engraving'] = sanitize_text_field($custom_data['engraving']);
}
return $cart_item_data;
}
您可以检查以下内容,这些内容将显示在购物车中并结帐自定义购物车商品数据:
add_filter( 'woocommerce_get_item_data', 'display_on_cart_and_checkout', 10, 2 );
function display_on_cart_and_checkout( $cart_data, $cart_item ) {
if ( isset($cart_item['engraving']) ) {
$cart_data[] = array(
"name" => __("Engraving text", "woocommerce"),
"value" => $cart_item['engraving']
);
}
return $cart_data;
}
代码位于活动子主题(或活动主题)的functions.php 文件中。已测试并有效。
备注:
$('.content-area').before(response);
替换为
$('.products').before(response);
正确显示通知...
$(document.body).trigger("wc_fragment_refresh");
问候