WooCommerce add to cart with quantity and AJAX

This post is more than 11 years old.

WooCommerce is a great e-commerce plugin for WordPress. It has some very nice basic features, but it’s also easy to customise and extend. On single product pages, you can add to cart with a quantity other than just one, and on the purchase page you can add to cart via AJAX without leaving the page. Wouldn’t it be nice to add to cart with both quantity and AJAX?

This simple approach is a modification of Mike Jolley’s solution to putting a quantity for simple products on the WooCommerce purchase page. With just a few tweaks, it can be made to add to cart with AJAX. First step is to make sure that the add-to-cart button can be found by WooCommerce’s AJAX add-to-cart script by giving it a quantity and a product ID, and a couple of extra CSS classes:

<button type="submit"
    data-quantity="1" data-product_id="<?php echo $product->id; ?>"
    class="button alt ajax_add_to_cart add_to_cart_button product_type_simple">
    <?php echo $label; ?>
</button>

Next step is to add some JavaScript that copies the quantity across to the add-to-cart button when it changes.

Edit: update the data, not the attribute — it matters!

/* when product quantity changes, update quantity attribute on add-to-cart button */
$("form.cart").on("change", "input.qty", function() {
    if (this.value === "0")
        this.value = "1";

    $(this.form).find("button[data-quantity]").data("quantity", this.value);
});

It would also be nice to only have one “view cart” link, so let’s remove the old ones when we’re adding a new one:

/* remove old "view cart" text, only need latest one thanks! */
$(document.body).on("adding_to_cart", function() {
    $("a.added_to_cart").remove();
});

To add this to your website, download both scripts from Gist, put the add-to-cart template into the folder woocommerce/loop in your theme, and put the accompanying JavaScript file into the folder js in your theme. You’ll probably need to create those folders in your theme.

For another approach that doesn’t require modification of any templates, you can use some of the WooCommerce action and filter hooks to intercept and modify bits of the purchase page as it’s being built. The trick is to use the woocommerce_loop_add_to_cart_link filter hook to replace the add-to-cart link with the output of woocommerce_simple_add_to_cart(), which gives you the quantity field and add-to-cart button, and use a little regular expression magic to give it the classes and data attributes it needs:

Edit: WooCommerce 2.1 no longer passes the 3rd parameter, $link; removed.

/**
* customise Add to Cart link/button for product loop
* @param string $button
* @param object $product
* @return string
*/
function custom_woo_loop_add_to_cart_link($button, $product) {
    // not for variable, grouped or external products
    if (!in_array($product->product_type, array('variable', 'grouped', 'external'))) {
        // only if can be purchased
        if ($product->is_purchasable()) {
            // show qty +/- with button
            ob_start();
            woocommerce_simple_add_to_cart();
            $button = ob_get_clean();

            // modify button so that AJAX add-to-cart script finds it
            $replacement = sprintf('data-product_id="%d" data-quantity="1" $1 ajax_add_to_cart add_to_cart_button product_type_simple ', $product->id);
            $button = preg_replace('/(class="single_add_to_cart_button)/', $replacement, $button);
        }
    }

    return $button;
}

It still needs that little bit of JavaScript to keep the button’s quantity in sync with the quantity field, but it’s also easy to add that directly to the page using the action hook ‘woocommerce_after_shop_loop’. Download this Gist and add the code to your theme’s functions.php file.

And job is done by the half dozen or singly, with AJAX.