WooCommerce add to cart with quantity and AJAX

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.

Facebooktwittergoogle_plusredditlinkedinmailFacebooktwittergoogle_plusredditlinkedinmail
  • Bhavin

    this is tutorial very help for my website.simple product added in ajax via add-to-cart but variable product not added using ajax. page will reload when product add. any solution plz help me.

    • G’day Bhavin,

      I’ve not tried to make the variable products use AJAX add to cart. I notice that WooCommerce v2.1 has rearranged things with the add to cart for variations / variable products, so maybe it’ll be easier to do that soon; v2.1 is due out in January or so they say.

      cheers,
      Ross

  • Bhavin

    Thanks a lot for reply.i tried after January.

  • Daniel

    Hi Bhavin,

    Would you happen to have figured out how to auto reload the page upon adding the items?

    Example (practicing this on one of my sites): http://koreankitchenshop.com/

    1. Upon adding qty, it doesn’t show up in the “cart” until manually refreshing the entire page. The entire script works beautifully after the first page reload.

    Note: I’m using the echo shortcode for the actual cart page instead of woocommerce’s widget.

    Any way to allow the woocommerce_cart to reload and display on the page via ajax?

    2. Woocommerce Cart’s page crashes upon removing of item from cart or updating of qty values.

    The cart can’t update quantity values or removing item after using this script. :(

    Hope this information helps!

    Daniel

    • G’day Daniel,

      1. WooCommerce add to cart using AJAX will replace the contents of the standard cart widget. If you’re displaying the cart widget some other way, you need to either ensure that it has a container that WooCommerce can replace the contents with using the selector “div.widget_shopping_cart_content“, or hook the filter add_to_cart_fragments and add your custom cart widget contents there.

      cheers,
      Ross

  • Bhavin

    Hi Ross McKay,
    Problem solved Variable Product Addtocart Via ajax.
    I customize the Woommerce and find solution of variable product addtocart via ajax. thats works great in my website.

  • G’day Bhavin,

    You should share your solution in a blog post! I’ll link to it from here :)

    cheers,
    Ross

    • Bhavin

      Hi Ross McKay,
      Sure I Share My Solution but one problem.i add product with ajax. My website Header Cart not Upadate in Variable Product.Else All Work Perfectly .Any Suggestion Plz help.

      • As I said to Daniel above, you need to hook the filter add_to_cart_fragments and add your custom cart widget contents there. See the WooCommerce doco.

        cheers,
        Ross

        • Bhavin

          Hi Ross McKay,
          Not Work.Simple product add in header cart . variable not add why? Any Suggestion .

          • I don’t know, Bhavin; I can’t see your code from here. Maybe you should start a support topic with a link to a gist of your code, and someone there can help you.

            cheers,
            Ross

  • Gavin

    Hi,

    I have added qty fields to my category pages. Is there a way using your methods to either add each product X QTY without reloading the page or create 1 button that adds all the products X their QTY’s to the cart?

    Thanks.

    • G’day Gavin,

      These methods use AJAX to add to the cart, so you stay on the page without reloading. That’s the purpose of these methods — to let you use AJAX to add to the cart, and still let you pick a quantity. Take a look at this example to see what I mean (and some nice wines / meads you might like for Xmas!)

      cheers,
      Ross

  • Bhavin

    Hi Ross McKay,
    I share variable product via ajax Solution in my blog post.
    http://hirparabhavin.wordpress.com

    • G’day Bhavin, very interesting. I hope that you realise you’ll need to keep patching those files each time a new version of WooCommerce comes out though — better would be to find a way to make your changes using action and filter hooks.

      cheers,
      Ross

  • Rajnish

    hi there

    i want to add quantity button on shop page so use this link
    https://gist.github.com/webaware/6260326

    i have update both files but by default it add only one product at one time it’s not taking quantity

    Please help me out

    Thanks
    Rajnish

    • Make sure you put the files into the correct folders, as per the comments in each file. Check your browser console for JavaScript errors, and your website error_log for PHP errors. If you can’t spot the problem there, best to start a detailed question on Stack Overflow and ask for help.

  • Thanks this really helped me solve the problem I had with adding the dam quantity box to my clients site.

  • Tim

    This is awesome, but no matter what, if I set the quantity to some number, say 11.. it still only adds 1 to the cart.

    Any ideas?

    • Tim

      Ah! Never mind. Forgot to add that last script.

  • It’s Helped…

    Thanks Dude…

  • Any update on implementing ajax add to cart for variable products ?

  • Dylan

    This is awesome… I’ve been looking for a way to do just this for the last week. It’s so close, but unfortunately I’ve run into two issues and wondering if anyone had a thought why:

    1. Using the hook method in my functions.php file, the cart widget updates perfectly with multiple items on the archives pages, but will only add a single item (regardless of quantity specified) on the single product page. I did a bit of checking and found that it’s because the jquery snippet is not being loaded on that page. If I add the jquery through a separate JS file, it works great. I was just wondering if there was a way to keep the code all together in the functions.php file. I think the issue may be related to the ‘woocommerce_after_shop_loop’ hook only applying on the archives pages, but I’ve tried a few alternative hooks with no luck.

    2. There is no text in the “add to cart” button. The code output for the button is – – not sure why the text would be missing, and wondering if I am supposed to define that text elsewhere?

    Thanks for any assistance, and thanks for posting this code!

    • G’day Dylan,

      Re: 1, change the hook from woocommerce_after_shop_loop to wp_print_footer_scripts and move the add_action outside the custom_woo_before_shop_link() function, it will add that snippet to every page, ensuring that your buttons work. I had the same problem on one site I customised. (most of my sites don’t use the single product pages)

      Re: 2, is that only when using this snippet? If so, sounds like a regular expression problem specific to something customised about your add-to-cart buttons. Look deeper at the HTML for the buttons, you might need to adjust that regular expression.

      cheers,
      Ross

      • Dylan

        Hey Ross,

        Sorry for the delayed response – Just wanted to say thanks! You pointed me in the right direction and I was able to get #1 working easily following your direction.

        #2 Started working after I went back in and tried to fix it. I’m not sure why though… I had a custom cart widget and had modified the text on the cart buttons, so I believe the issue was related to one of those two pieces. I tried so many things without seeing any results, and then just loaded it up the next day and it worked… must have been caching. Problem is I don’t know which change I made caused it to start working. I’ll keep trying to figure out what it was so I can post a solution here in case anyone else has the same problem.

        Thanks again.

  • St0rK

    Is there any way to do this for a custom input so it updates the product meta ?

    I have a website which doesn’t use the single product page, the orders are made via shop page. The effect i want it to have is the exact same thing as Woocommerce Product Add-On does but on the shop page with ajax instead of the single product page

    Thank you

    • You’d probably need to write some custom script for that. I have done a customisation for someone using the measurements add-on, with some script that intercepts the AJAX post and modifies it to send the extra data. As long as the right POST data is there, the add-on can do something with it, but the standard add-to-cart script won’t send that data so you need to add it to the POST. It’s all possible, see my post on jQuery’s ajaxSend event for a starting point.

  • Thomas

    Awesome code, any idea how to get this to work on related products in single-product aswell?

    • Change the hook from woocommerce_after_shop_loop to
      wp_print_footer_scripts and move the add_action outside the
      custom_woo_before_shop_link() function, and it will add that snippet to
      every page, maybe that will work for related products. (most of my sites don’t use the single product
      pages — they get wine tasting note pages instead)

      cheers,
      Ross

  • Thomas

    Well I guess I wont be needing this anymore :-)

    • Ha! Yeah, an order form is often the quickest way to the checkout, but we need all tools at our disposal to keep all the shoppers happy! :)

  • Luc Awater

    It works! I have an additional question though. In my header, I have a number that represents the amount of products that are in the cart. How can I make sure that that number will also change? Thanks!

    • Use the `add_to_cart_fragments` filter to make sure that your minicart is updated whenever WooCommerce updates its minicart: http://docs.woothemes.com/document/show-cart-contents-total/

      • Luc Awater

        Thanks, it works. I had a click function on the a tag as well, which is now broken. Any idea what that might be?

        • Your click function would have broken because you linked the click event directly to the a tag, which would have been removed and replaced when the minicart was refreshed. You can handle that by using a delegate. Let’s say your minicart is in a div with class “container”:

          $(".container").on("click", "a", function() {} );

          Read more on the jQuery website.

  • studioculture

    Hi, the code works great but seem to be getting issues when adding the variable item, the attributes don’t display on the cart page so only the name of the product shows up but not which variable you selected e.g colour/size… Any help is appreciated!

    • Variable products are tricky, which is why the code in the blog post leaves them alone. I’ve done a couple of custom sites with variable products, but it’s more complex than the above. Best to let the customer click through to the single product page and pick their variations before adding to the cart.

      • studioculture

        Thanks Ross, I’ve made a custom layout where they are able to select the variables from the archive page for quick add to carts and works but the page refreshes when it adds to cart which I wanted to avoid…

        • You need to intercept the AJAX post for the `woocommerce_add_to_cart` action, and append the extra field data. The jQuery ajaxSend method lets you do that. It’s beyond the scope of this blog post, however.

          • studioculture

            No problems, I look into that, thanks so much!

  • Luc Awater

    I have a preview of the cart in a sidebar. Is there any way to also update the item data in that sidebar? Thanks!

    • Use the `add_to_cart_fragments` filter, same as I said below. You can stack as many things as you like in that filter’s array.

  • Rocc Rocc

    I am wondering if you all can help me. I am using this script to show my variations on my product page but when I click the add to cart button it refreshes the page with add to cart buttons on all of my products. I just want the page to reset without the add to cart buttons. Here is the code:

    if ( ! function_exists( ‘woocommerce_template_loop_add_to_cart’ ) ) {

    function woocommerce_template_loop_add_to_cart() {
    global $product;

    if ($product->product_type == “variable”) {
    woocommerce_variable_add_to_cart();
    }
    else {
    woocommerce_get_template( ‘loop/add-to-cart.php’ );
    }

    }

    }

    http://fitboxmeals.com/product-category/meals/

    Any assistance would be greatly appreciated. I have been trying to figure this out for the past two days. Thank you.

  • Nice tutorial right there, is there any way I get current added product info? the reason I wanted to get such information is I have a Order Information table below and I want it to update the data too, so e.g. I’ve added Product One, so Product One is also added to the Order Table.

    Thanks

  • gabriele

    Hello. it would be possible to see on a site the result of the tutorial ?
    Thank You.

  • Vytlfa

    I’ve set my minimum quantities to numbers other than 1 (2, 3, 4, 6) via the Woocommerce Advanced Product Quantities plugin, and pick and chose code from the php file linked above (namely the button- I’m using the whole .js file). My problem is that even though my quantity inputs display the minimums, the code thinks the input is ‘1’ and errors. Is there anything I can change with code to fix that, to instead of setting it to 1 it sets to to the default minimum?

    • You can call apply_filters('woocommerce_quantity_input_min', '', $product) to get the minimum quantity for the product, and use that. I imagine that WooCommerce Advanced Product Quantities is hooking that filter to change the minimum. Let me know if that works.

      • Vytlfa

        Hmmm I actually have a bunch of custom functionality all over the place; my archive page is using the add to cart simple.php file from the single-product folder. I’m pretty much only using the from code from the Gist file and the complete .js file; I’m not even using the function above so I’m a little confused on how to go about achieving this.

      • Vytlfa

        Honestly I’m not even sure how to proceed. Do I do something like $args = apply_filters('woocommerce_quantity_input_min', '', $product); then try to add the $args to the data-quantity HTML?

    • NB: you need to change data-quantity=”1″ to reflect the minimum quantity you get back from that filter, of course :)

  • Thanks, this was very useful, I am trying to create a “quick view” kind of plugin, and I find this code can be applied to what I have in mind.
    At first I wanted to go down the reinvent-the-wheel route, but I then found it a bit hard… thanks!

  • jennylu98

    Thanks for the great solution, is there a ajax solution for remove link?

    • Why AJAX, and what link?

      • jennylu98

        Sorry for the confusion, I mean the remove product link on the cart and mini-cart pages.

        I want ajax for better ux, dont want to have the page refresh when user removes an item. Any suggestion on how to approach this?

        Thanks!

  • NB: just found a subtle bug, the JS that updates data-quantity needs to update that as .data() not as .attr() so that it is properly reflected when customer adds to cart twice! See updated code above.

  • Jesper

    Thanks for the greate solution Ross, It’s work perfectly, but I miss to add variations for variable products. If some one has solved it, please share your code. I’m using this code above right know.

  • serega270

    Great script, very helpful. Thanks

  • JS

    Update – for Method A, I also did it properly within the Theme rather than Plugin.

  • Garry

    Where Exactly i have to put all these code

    • I suggest you engage a developer to do that for you. If you don’t understand the code and where to place it in your website, you should not be copying / pasting code from the internet as you could create more trouble for yourself than it is worth.

      cheers,
      Ross

  • Answered off-site through emails; I’ll update the post if it works out for you.

  • Young Techleads

    I am the below linked plugin can help you make you add to cart and update cart button ajaxify.

    http://www.youngtechleads.com/woocommerce-ajax-add-to-cart/ WOOJAX

    If you want to make your whole website ajaxify including WooCommerce use below linked plugin http://www.youngtechleads.com/ajaxify-wordpress-site-pro/

    Ajaxify WordPress Site Pro

  • Jean

    Hello Ross, Thank you so much for this fantastic snippet! It works almost perfectly on my site, with one exception: when the “Add to Cart” button is clicked, it also redirects the user to the single product page. I would like the customers to be able to scan a gallery of product thumbnails and add them in a bunch without having a detour to the individual product pages. Is that possible?

    Also, I realize that creating an Ajax variation link is very complicated, but would it be difficult to create a link that just adds the default variation for each product to the cart? Thank you!

    • Jean

      Oops, I found the problem … the part of my theme which linked the image to the product page accidentally enveloped the after_shop_loop_item as well. However, I’m still trying to find a quick way to set Add to Cart to pick the default variation.

  • Vox Populi

    is it possible to add the quantity in the link? For example: http://www.demo.com/productone/?add-to-cart=21&quantity=14 or something like this

  • michaelmaud

    Hi Ross, I am using method A currently and this adds the items via ajax but doesn’t link the quantity (it only ever adds 1) so I tried the one for beyond woocommerce 2.1 and that white screens when added to the functions php file. I took the code from the gists on github, am I missing something?

    • michaelmaud

      Hi Ross, I managed to eventually get this working by updating the data-quantity attribute rather than using the data.

      e.g. your line was

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

      this line did not work on my site, I replaced after much trial and error with

      $(this.form).find(“button[data-quantity]”).attr(“data-quantity”, this.value);

      which worked

      I thought I’d just leave this here in case anybody comes across the same issue with your otherwise excellent script.

  • Cole Majoor

    Hi Ross, couple of questions when implementing the first method code:

    1. I am now seeing double! two lots of “add to cart” and two lots of “qty” buttons, what should I do?
    2. Also, is there any way to put the quantity button beside the “add to cart”? I noticed it’s placed on top.

    Thanks in advance

    • G’day Cole, I haven’t tried that method for quite a while because I generally try to avoid overriding WooCommerce templates — your version inevitably needs updating with each new major WooCommerce release. I reckon I’ll need to update that gist for the current incarnation of WooCommerce, because the templates have been moved around a bit since I wrote this blog post.

      In the meantime, perhaps you can try the second method. It’s the one I actually use on websites, and I can vouch for it still working OK with the current WooCommerce version.

      cheers,
      Ross

      • Cole Majoor

        Thanks for your reply Ross, much appreciated! Will give this a go.

  • James

    Really awesome, and execitly working without the plugin. I cant remove the view cart, but I want to add some think beside the view cart. How can i do this ? Please can you share with me.

  • JS

    The hooks version had been working perfectly for me, but suddenly isn’t after updating to the latest WordPress/Woocommerce :(

  • Dear Ross, a weird thing happens if we change quantity more than once and keep our eye on mini-cart amount value — after second adding of the same product increment is still equal to the first quantity value:

    — default quantity is 1
    — change it to 2
    — add this product to cart
    — amount in the cart is 2
    — change that quantity to any
    — add same product to cart again
    — amount in the cart increased by.. 2!
    — so now amount is 4

    I will be grateful for any hint!

    • dissaa

      Same here!

  • Edd Hurst

    Hi Ross, Thanks for posting this and explaining everything. I just wanted to let you know that the first method appears to have stopped working whilst updating from Woo 2.4.6 to Woo 2.5.5.

    I swapped to the second method, deleted my custom add-to-cart.php template and it worked perfectly, for anybody else who has the same problem.

    • G’day Edd, I updated the scripts recently to work with Woo 2.5.5 so if you need to return to the first method, just update the code.

      However, I recommend using the second method because it gives you some insurance against template changes with WooCommerce upgrades.

  • Kadar Claudiu

    Thank you so much!! :)

  • Kiên Trần

    Thank you so muck. But i has problem .please help me how to
    2nd click , it can remove products from cart

  • xnnx

    Hello Ross,
    Please help, I’m really struggling here for months and just found your solutions which seems to be a life saver for your audience. Not working for me though. Using the method ‘A’, only one item is added to cart, no matter the quantity input.
    Product listing on my site is located at: http://bit.ly/1PE8wSb
    Thanks so much, I really appreciate it.

    • Make sure that you’re using the latest versions of the code, updated recently for WooCommerce 5.5 — and I very much recommend the second method which is more resilient to changes in WooCommerce templates.

      • xnnx

        Great! Half way there. I switched to method ‘B’, added the code in functions.php and it works well. Another thing happens, though. On the same products page, let’s say, I add a product to cart. Everything’s fine. If I add another product, the ‘Add to Cart’ button for the previously added product disappears. The same happens if I add more different products. The previously added ‘Add to Cart’ buttons are disappearing one by one.
        I don’t know if you’re aware of how much I appreciate your help here. You really saved my life. Thanks so much!

  • xnnx

    Hello again,
    Eventually I made it through with some css tweaks. Looks fine now, but it seems the quantities are not working when I use woocommerce shortcodes in other pages of the site. Is it supposed to act like that or am I doing something wrong. Thanks in advance!

  • Dhruv Narang

    Amazing man, worked like a charm for me. Thank you so much :D

  • Guillermo Tamborero Jimenez

    Awesome! Works perfect on woo 2.6.4 you just need to give some css styling ;)

  • Any tips on how to subtract a item from cart? (not remove, decrease quantity)

    • later edit: a quick ajax with
      WC()->cart->set_quantity($cart_item_key,$quantity);
      did the trick.