Rasmus Lian
Rasmus Lian

Reputation: 427

WooCommerce set cart quantity with AJAX?

I've now been scratching my head about this for several days and need some pointers.

I'm making a custom theme totally from scratch for a WooCommerce site and now I'm trying to get the cart functionality to work. I'm stuck at trying to have buttons (+/-) for updating the quantity of a product item in the cart.

The problem to me seems to be that the WC() I use inside functions.php is not the same instance as the current frontend-session, or something among those lines. At least my thought for now.

If I've debugged correctly the WC()->cart->set_quantity($cart_item_key, 0) gives no error (if using number 0), all other numbers gives '500 (Internal Server Error)'. But even with 0 quantity in cart is never changed nonetheless.

I've enqueued the scripts correctly so the AJAX function call executes fine when the button is clicked.

Here's my HTML and PHP (simplified)

<div class="cart-items">
    <?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
    <div class="cart-item">
        <div class="quantity" id="cart-qty-<?php echo $cart_item_key ?>">
            <button class="minus" id="cart-subtract"
                onclick="updateCartQuantity('<?php echo $cart_item_key ?>', '<?php echo $cart_item['quantity'] ?>', -1)">-</button>
            <p><?php echo $cart_item['quantity'] ?></p>
            <button class="plus" id="cart-add">+</button>
        </div>
    </div>
    <? endforeach; ?>
</div>

Here's my JS (inside a file called shopping-ajax.js)

function updateCartQuantity(cart_item_key, current_qty, value) {
  function qty_cart() {
    jQuery.ajax({
      type: "POST",
      url: my_ajax_object.ajax_url,
      data: {
        action: "update_cart",
        hash: cart_item_key,
        quantity: current_qty,
        value: value,
      },
      success: function (data) {
        console.log(data);
      },
      error: function (data) {
        console.log(data);
      },
    });
  }

  qty_cart();
}

Here's my PHP function (inside functions.php)

function updateCartQuantity(){
    $cart_item_key = $_REQUEST['cart_item_key'];
    $quantity = $_REQUEST['quantity'];
    $value = $_REQUEST['value'];
    
    WC()->cart->set_quantity($cart_item_key, $quantity + $value);

    echo $quantity + $value;
    wp_die();
}
add_action( 'wp_ajax_nopriv_update_cart', 'updateCartQuantity' );
add_action( 'wp_ajax_update_cart', 'updateCartQuantity' );

A massive thanks for any help or pointer in advance!

Upvotes: 3

Views: 6326

Answers (1)

Rajeev Singh
Rajeev Singh

Reputation: 1799

You should manage product qty according to the qty input box(change qty).

My JS:

location: theme directory -> js -> custom.js

jQuery( function( $ ) {
    $( document ).on( 'change', 'input.qty', function() {
        var $thisbutton = $(this);
        var item_hash = $( this ).attr( 'name' ).replace(/cart\[([\w]+)\]\[qty\]/g, "$1");
        var item_quantity = $( this ).val();
        var currentVal = parseFloat(item_quantity);
        $.ajax({
            type: 'POST',
            url: cart_qty_ajax.ajax_url,
            data: {
                action: 'my_cart_qty',
                hash: item_hash,
                quantity: currentVal
            },
            success: function(response) {
                jQuery(document.body).trigger('added_to_cart', [response.fragments, response.cart_hash, $thisbutton]);
                //jQuery(document.body).trigger('update_checkout');
            }
        });  
    });
});

fuctions.php -

Setup Enqueue Ajax Scripts:

function enqueue_cart_qty_ajax() {

    wp_register_script( 'my_cart_qty-ajax-js', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
    wp_localize_script( 'my_cart_qty-ajax-js', 'cart_qty_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
    wp_enqueue_script( 'my_cart_qty-ajax-js' );

}
add_action('wp_enqueue_scripts', 'enqueue_cart_qty_ajax');

Ajax call -

function ajax_my_cart_qty() {

    // Set item key as the hash found in input.qty's name
    $cart_item_key = $_POST['hash'];

    // Get the array of values owned by the product we're updating
    $threeball_product_values = WC()->cart->get_cart_item( $cart_item_key );

    // Get the quantity of the item in the cart
    $threeball_product_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 );

    // Update cart validation
    $passed_validation  = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $threeball_product_values, $threeball_product_quantity );

    // Update the quantity of the item in the cart
    if ( $passed_validation ) {
        WC()->cart->set_quantity( $cart_item_key, $threeball_product_quantity, true );
    }

    // Refresh the page
    echo do_shortcode( '[woocommerce_cart]' );

    die();

}

add_action('wp_ajax_my_cart_qty', 'ajax_my_cart_qty');
add_action('wp_ajax_nopriv_my_cart_qty', 'ajax_my_cart_qty');

Upvotes: 5

Related Questions