Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Mini cart quantity change in Woocommerce

I have read like every single topic about woocommerce but cannot find out how to add a minus button which decreases the quantity of a cart item (with ajax preferably) in the Woocommerce MiniCart.

I did manage to add a button which increases the quantity using the woocommerce shortcode and via several other code samples. However, I cannot find how to decrease the quantity anywhere.

There are multiple questions about this, none answered. Or I`m searhing in the wrong directory.

However, can someone give me a code example on how to decrease cart`s quantity for a product out of the box? I already tried a custom php file with these lines of code:

$cartKey = $_POST['cart_item_key']; //The cart key required by set_quantity method
$cartQty = $_POST['cart_item_qty']; //the quantity I provide in my post

global $woocommerce;
echo $woocommerce->cart->set_quantity($cartKey,$cartQty);

But calling this via AJAX post gives me an error (internal server error). I also tried add to cart with negative quantity, did not work either.

UPDATE: adding this code to a WP page template and calling that page does not give me the error anymore. However, after calling the code, it does not update the cart.

What can I do? Thanks a lot I hope someone can help here!

like image 495
Marcel Avatar asked Sep 05 '14 07:09

Marcel


1 Answers

Ok, so I figured this out. What I did:

1: Create a WP page responsible for handling the AJAX update cart. I think you can do this with just a simple PHP file too, but I just created a custom WP template for now. So I added a page template called 'template-setquantity.php' with the following contents:

    <?php   
    /**
    * Template Name: Request template for Set Quantity
    * This page updates mini cart quantity for a product based on the post value
    */
    //I dont think this line is needed
    global $woo_options;
    ?>
    <html>
    <head>
     <?php wp_head(); ?>
    </head>
    <body>
     //the cart key stores information about cart
     $cartKeySanitized = filter_var($_POST['cart_item_key'], FILTER_SANITIZE_STRING);
     //the new qty you want for the product in cart
     $cartQtySanitized = filter_var($_POST['cart_item_qty'], FILTER_SANITIZE_STRING);  
     //update the quantity
     global $woocommerce;
     ob_start();
     $woocommerce->cart->set_quantity($cartKeySanitized,$cartQtySanitized); 
     ob_get_clean();
     wp_footer(); ?>
     <?php woo_foot(); ?>
    </body>
    </html>
  1. Create a wordpress backend page using this template. For this tutorial the url should be: updatecart

  2. Now copy over the mini-cart.php from woocommerce to your custom theme. So I created the dir woocommerce/cart in my custom theme and copied the file mini-cart.php into this folder

  3. Update the mini-cart.php template to add your plus and minus buttons to update quantity in mini-cart. For me it meant adding the following code, somewhere in the loop of each product:

    <?php
    //btn add
    echo do_shortcode('[add_to_cart id="'.$cart_item['product_id'].'" show_price="false" btn_text="+" class="btnAdd" ]');
    //btn minus, the cart_item_key and $cart_item['.. is available already in scope.
    echo '<a class="btnMinus" onClick="updateQty(\''.$cart_item_key.'\','.($cart_item['quantity']-1).')"> - </a>';
    ?>
    
  4. So now we have setup the page which catches requests to update quantity and we have added or plus and minus button to each product in the mini cart. As final step we need to create a JS function which does 2 things: AJAX call to our updatecart template page and AJAX call to refresh the cart contents visually 1.

  5. In my case, I added these functions to the footer. As you have read in step 4, the function of the minus buttons for onClick is updateQty, so that has to be our JS function name. Paste the following JS code to for example your footer (please note I use Jquery):

    <script type="text/javascript">
    function updateQty(key,qty){
     url = 'http://yourdomain.com/updatecart/';
     data = "cart_item_key="+key+"&cart_item_qty="+qty;
    
     jQuery.post( url, data ) .done(function( data ) {
      //function updateCartFragment 
      updateCartFragment();
     });
    }
    
    function updateCartFragment() {
     $fragment_refresh = {
      url: woocommerce_params.ajax_url,
      type: 'POST',
      data: { action: 'woocommerce_get_refreshed_fragments' },
      success: function( data ) {
        if ( data && data.fragments ) {          
            jQuery.each( data.fragments, function( key, value ) {
                jQuery(key).replaceWith(value);
            });
    
            if ( $supports_html5_storage ) {
                sessionStorage.setItem( "wc_fragments", JSON.stringify( data.fragments ) );
                sessionStorage.setItem( "wc_cart_hash", data.cart_hash );
            }                
            jQuery('body').trigger( 'wc_fragments_refreshed' );
        }
      }
     };
    
     //Always perform fragment refresh
     jQuery.ajax( $fragment_refresh );  
    }
    </script>
    

I hope this helps!

NOTE that in later versions of Woocommerce I would be better to replace the global $woocommerce with function WC() (http://docs.woothemes.com/wc-apidocs/function-WC.html)

like image 105
Marcel Avatar answered Sep 19 '22 13:09

Marcel