2014-10-01 7 views
7

Ich habe mehrere Tage gesucht, aber ich habe noch keine Antwort. Im Grunde versuche ich, woocommerce Standart "update cart" Knopf mit Ajax Anruf zu ersetzen, der den Gesamtpreis der Bestellung automatisch aktualisiert, wenn sich die Menge ändert. Das ist mein htmlWooCommerce - Auto Update Gesamtpreis, wenn Menge geändert

<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> 

In functions.php ich eine Funktion zum Aktualisieren Summen haben:

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

    } 

und jQuery-Code ist:

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

Der obige Code funktioniert nur groß, wenn Ein Produkt befindet sich im Warenkorb.

Aber wenn ich ein anderes Produkt hinzufüge und die Quantität von einem von ihnen ändere, verwende meine Funktion letzten Wert der Quantität für alle meine Produkte.

enter image description here

Zum Beispiel darf den Gesamtpreis für das zweite Bild sein 7000 (2000 * 1 + 2500 * 2), aber es ist 9000 (2000 * 2 + 2500 * 2). Ich bin neu bei Ajax und Jquery und schätze jede Hilfe.

Antwort

5

Es ist, weil Sie alle Ihre Einkaufswagen aktualisieren, nicht nur ein Produkt.

Zuerst müssen Sie den Artikel Wagen Hash senden (es ist kein Sicherheits Hash, aber das Produkt Hash mit dem alle Variationsprodukt) auf dem JavaScript-Skript:

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

Dann können Sie Ihre function update_total_price bearbeiten, ich habe vereinfacht;)

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; 
} 
+0

XcID, es funktioniert super! Vielen Dank! – grimasa

+0

Was hier fehlt ist, wie wird 'rf_cart_params' eingestellt ..? Wenn ich die obige jQuery-Funktion aufruft, bekomme ich einen 'ReferenceError: rf_cart_params is not defined'. Vielleicht ist der Grund, dass ich die Warenkorbseite nicht einmal geladen habe, ich zeige den Einkaufswagen auf der Produktarchivseite (eigentlich habe ich es überprüft, als ich den Code auf der ursprünglichen Warenkorbseite ausprobiere, es ist das gleiche Problem ..). Also, wie bekomme ich die Skripte geladen/Variablen gesetzt ..? – honk31

+0

tatsächlich auf der Warenkorbseite Ich habe jetzt das Objekt gefunden, aber es heißt 'wc_cart_params'. werde versuchen, diese auf meiner Archivseite zu enque .. – honk31

3

Hier ist ein einfacher Weg dies zu erreichen. Der gesamte Kredit geht an 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('<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 
} 
+0

diese Antwort hat wirklich nichts mit der Frage zu tun. während es den Preis richtig berechnen kann, ist dieses Tool nur, um den Preis auf der Produktseite zu berechnen, während die Frage in Bezug auf die Warenkorbseite ist. Wenn Sie die Menge auf der Warenkorbseite ändern und diese nicht an wc senden, kann sich der Preis ändern, der Einkaufswagen jedoch nicht. – honk31

+0

@ honk31 du hast recht! hatte es nicht bemerkt. Ich denke, es ist immer noch wert, hier zu bleiben, weil es jemandem in der Zukunft helfen könnte – adamj

Verwandte Themen