WooCommerce – 数量变化时自动更新总价

我一直在寻找好几天但我还没回答。 基本上,我正在尝试用ajax调用替换woocommerce标准“更新购物车”按钮,这会在数量变化时自动更新订单总价。 这是我的HTML

  

在functions.php中,我有一个更新总计的函数:

 public function update_total_price() { check_ajax_referer( 'update_total_price', 'security' ); if ( ! defined('WOOCOMMERCE_CART') ) { define( 'WOOCOMMERCE_CART', true ); } $cart_updated = false; $cart_totals = isset( $_POST['cart'] ) ? $_POST['cart'] : ''; if ( sizeof( WC()->cart->get_cart() ) > 0 ) { foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) { $_product = $values['data']; // Skip product if no updated quantity was posted if ( ! isset( $_POST['quantity'] ) ) { // if ( ! isset( $cart_totals[ $cart_item_key ]['qty'] ) ) { continue; } // Sanitize $quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key ); // $quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', $cart_totals[ $cart_item_key ]['qty'] ) ), $cart_item_key ); if ( '' === $quantity || $quantity == $values['quantity'] ) continue; // Update cart validation $passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity ); // is_sold_individually if ( $_product->is_sold_individually() && $quantity > 1 ) { wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'woocommerce' ), $_product->get_title() ), 'error' ); $passed_validation = false; } if ( $passed_validation ) { WC()->cart->set_quantity( $cart_item_key, $quantity, false ); } $cart_updated = true; } } // Trigger action - let 3rd parties update the cart if they need to and update the $cart_updated variable $cart_updated = apply_filters( 'woocommerce_update_cart_action_cart_updated', $cart_updated ); if ( $cart_updated ) { // Recalc our totals WC()->cart->calculate_totals(); woocommerce_cart_totals(); exit; } } 

而Jquery代码是:

 jQuery( function( $ ) { // wc_cart_params is required to continue, ensure the object exists if ( typeof wc_cart_params === 'undefined' ) { return false; } // Cart price update depends on quantity //$( document ).on( 'click', '.quantity', function() { $( document ).on( 'change', '.quantity, input[type=number]', function() { var qty = $( this ).val(); var currentVal = parseFloat( qty); $( 'div.cart_totals' ).block({ message: null, overlayCSS: { background: '#fff url(' + wc_cart_params.ajax_loader_url + ') no-repeat center', backgroundSize: '16px 16px', opacity: 0.6 } }); var data = { action: 'rf_update_total_price', security: rf_cart_params.rf_update_total_price_nonce, quantity: currentVal }; $.post( rf_cart_params.ajax_url, data, function( response ) { $( 'div.cart_totals' ).replaceWith( response ); $( 'body' ).trigger( 'rf_update_total_price' ); }); return false; }); }); 

如果购物车中只有一个产品,则上述代码效果很好。 在此处输入图像描述

但是当我添加一些其他产品并更改其中一个产品的数量时,我的function使用我所有产品的最后一个数量值。

在此处输入图像描述

例如,第二张图像的总价格必须为7000(2000 * 1 + 2500 * 2),但它是9000(2000 * 2 + 2500 * 2)。 我是ajax和jquery的新手,所以感谢任何帮助。

这是因为您正在更新所有购物车,而不仅仅是产品。

首先,您需要在javascript脚本上发送项目购物车哈希(它不是安全散列,但产品散列包含所有产品变体):

 var item_hash = $( this ).attr( 'name' ).replace(/cart\[([\w]+)\]\[qty\]/g, "$1"); var data = { action: 'rf_update_total_price', security: rf_cart_params.rf_update_total_price_nonce, quantity: currentVal, hash : item_hash }; 

然后你可以编辑你的function update_total_price ,我简化了;)

 function update_total_price() { // Skip product if no updated quantity was posted or no hash on WC_Cart if( !isset( $_POST['hash'] ) || !isset( $_POST['quantity'] ) ){ exit; } $cart_item_key = $_POST['hash']; if( !isset( WC()->cart->get_cart()[ $cart_item_key ] ) ){ exit; } $values = WC()->cart->get_cart()[ $cart_item_key ]; $_product = $values['data']; // Sanitize $quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key ); if ( '' === $quantity || $quantity == $values['quantity'] ) exit; // Update cart validation $passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $values, $quantity ); // is_sold_individually if ( $_product->is_sold_individually() && $quantity > 1 ) { wc_add_notice( sprintf( __( 'You can only have 1 %s in your cart.', 'woocommerce' ), $_product->get_title() ), 'error' ); $passed_validation = false; } if ( $passed_validation ) { WC()->cart->set_quantity( $cart_item_key, $quantity, false ); } // Recalc our totals WC()->cart->calculate_totals(); woocommerce_cart_totals(); exit; } 

这是实现这一目标的更简单方法。 所有功劳归功于Reigel Gallarde

 // we are going to hook this on priority 31, so that it would display below add to cart button. add_action( 'woocommerce_single_product_summary', 'woocommerce_total_product_price', 31 ); function woocommerce_total_product_price() { global $woocommerce, $product; // let's setup our divs echo sprintf('',__('Product Total:','woocommerce'),''.$product->get_price().''); echo sprintf('',__('Cart Total:','woocommerce'),''.$product->get_price().''); ?>