Intereting Posts
Изменение времени подключения базы данных laravel Захват и управление данными электронной почты с помощью PHP Добавление заголовков столбцов в файл CSV с помощью PHP IE (HTTPS): генерация PDF из php-файла не работает Как добавить xml-данные в xml-файл без перезаписи существующих данных с помощью php? Невозможно разобрать RSS XML с PHP CodeIgniter: пытается вызвать метод конструктора, чтобы проверить, зарегистрирован ли пользователь (вызывает бесконечный цикл перенаправления) Как показать / скрыть элементы с помощью PHP и как отправить пользователя на другую страницу PHP, передать параметры из командной строки в скрипт PHP Slim PUT возвращает NULL PHP и Postgres: ловушки ошибок? Корейский Syllable PHP или JavaScript Romanizer (или любая другая альтернатива?) глобальные переменные равны нулю при использовании PHPUnit Правильный / принятый способ обновления записи ATOM Нужна ваша помощь, данные IOS Swift Post для Json Alamofire

WooCommerce – автоматическое обновление общей цены при изменении количества

Я искал несколько дней, но ответа пока нет. В основном, я пытаюсь заменить стандартную кнопку «Обновить корзину» woocommerce с помощью ajax-вызова, который автоматически обновляет общую стоимость заказа при изменении количества. Это мой html

<div class="cart_item"> <div class="product-thumbnail"> <a href="http://example.com"><img width="90" height="90" src="path to thumbnail"/></a> </div> <div class="product-name"> <a class="cart-page-product__title" href="http://example.com">Product1 name</a> </div> <div class="product-quantity"> <div class="quantity"> <input type="number" step="1" name="cart[some_security_key][qty]" value="1" class="input-text qty text" size="4"/> </div> </div> <div class="product-subtotal"><span class="amount">2 000</span></div> <div class="product-remove"> <a class="product-remove_link" href="http://example.com/?remove_item">&times;</a> </div> </div> <div class="cart_item"> <div class="product-thumbnail"> <a href="http://example.com"><img width="90" height="90" src="path to thumbnail"/></a> </div> <div class="product-name"> <a class="cart-page-product__title" href="http://example.com">Product2 name</a> </div> <div class="product-quantity"> <div class="quantity"> <input type="number" step="1" name="cart[some_security_key][qty]" value="1" class="input-text qty text" size="4"/> </div> </div> <div class="product-subtotal"><span class="amount">2 000</span></div> <div class="product-remove"> <a class="product-remove_link" href="http://example.com/?remove_item">&times;</a> </div> </div> 

В 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; }); }); 

Вышеприведенный код отлично работает, если в тележке находится только один продукт. введите описание изображения здесь

Но когда я добавляю какой-то другой продукт и изменяю количество одного из них, моя функция использует последнее значение количества для всех моих продуктов.

введите описание изображения здесь

Например, общая стоимость второго изображения должна быть 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; } 

Вот более простой способ добиться этого. Весь кредит принадлежит Рейгел Галлард .

 // 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('<div id="product_total_price" style="margin-bottom:20px;display:none">%s %s</div>',__('Product Total:','woocommerce'),'<span class="price">'.$product->get_price().'</span>'); echo sprintf('<div id="cart_total_price" style="margin-bottom:20px;display:none">%s %s</div>',__('Cart Total:','woocommerce'),'<span class="price">'.$product->get_price().'</span>'); ?> <script> jQuery(function($){ var price = <?php echo $product->get_price(); ?>, current_cart_total = <?php echo $woocommerce->cart->cart_contents_total; ?>, currency = '<?php echo get_woocommerce_currency_symbol(); ?>'; $('[name=quantity]').change(function(){ if (!(this.value < 1)) { var product_total = parseFloat(price * this.value), cart_total = parseFloat(product_total + current_cart_total); $('#product_total_price .price').html( currency + product_total.toFixed(2)); $('#cart_total_price .price').html( currency + cart_total.toFixed(2)); } $('#product_total_price,#cart_total_price').toggle(!(this.value <= 1)); }); }); </script> <?php }