Skip to content

Instantly share code, notes, and snippets.

@webaware
Forked from mikejolley/functions.php
Last active October 22, 2023 05:55
Show Gist options
  • Save webaware/6260326 to your computer and use it in GitHub Desktop.
Save webaware/6260326 to your computer and use it in GitHub Desktop.
WooCommerce purchase page add-to-cart with quantity and AJAX, by customising the add-to-cart template in the WooCommerce loop. See blog post for details: http://snippets.webaware.com.au/snippets/woocommerce-add-to-cart-with-quantity-and-ajax/
<?php
/**
* Loop Add to Cart -- with quantity and AJAX
* requires associated JavaScript file qty-add-to-cart.js
*
* @link http://snippets.webaware.com.au/snippets/woocommerce-add-to-cart-with-quantity-and-ajax/
* @link https://gist.github.com/mikejolley/2793710/
*/
// add this file to folder "woocommerce/loop" inside theme
global $product;
if( $product->get_price() === '' && $product->product_type != 'external' ) return;
// script for add-to-cart with qty
wp_enqueue_script('qty-add-to-cart', get_stylesheet_directory_uri() . '/js/qty-add-to-cart.js', array('jquery'), '1.0.1', true);
?>
<?php if ( ! $product->is_in_stock() ) : ?>
<a href="<?php echo get_permalink($product->id); ?>" class="button"><?php echo apply_filters('out_of_stock_add_to_cart_text', __('Read More', 'woocommerce')); ?></a>
<?php else : ?>
<?php
switch ( $product->product_type ) {
case "variable" :
$link = get_permalink($product->id);
$label = apply_filters('variable_add_to_cart_text', __('Select options', 'woocommerce'));
break;
case "grouped" :
$link = get_permalink($product->id);
$label = apply_filters('grouped_add_to_cart_text', __('View options', 'woocommerce'));
break;
case "external" :
$link = get_permalink($product->id);
$label = apply_filters('external_add_to_cart_text', __('Read More', 'woocommerce'));
break;
default :
$link = esc_url( $product->add_to_cart_url() );
$label = apply_filters('add_to_cart_text', __('Add to cart', 'woocommerce'));
break;
}
//printf('<a href="%s" rel="nofollow" data-product_id="%s" class="button add_to_cart_button product_type_%s">%s</a>', $link, $product->id, $product->product_type, $label);
if ( $product->product_type == 'simple' ) {
?>
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" method="post" enctype='multipart/form-data'>
<?php woocommerce_quantity_input(); ?>
<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>
</form>
<?php
} else {
printf('<a href="%s" rel="nofollow" data-product_id="%s" class="button add_to_cart_button product_type_%s">%s</a>', $link, $product->id, $product->product_type, $label);
}
?>
<?php endif; ?>
/*!
script for WooCommerce add to cart with quantity, via AJAX
Author: support@webaware.com.au
Author URI: http://snippets.webaware.com.au/
License: GPLv2 or later
Version: 1.0.1
*/
// @link http://snippets.webaware.com.au/snippets/woocommerce-add-to-cart-with-quantity-and-ajax/
// @link https://gist.github.com/mikejolley/2793710/
// add this file to folder "js" inside theme
jQuery(function ($) {
/* 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);
});
/* remove old "view cart" text, only need latest one thanks! */
$(document.body).on("adding_to_cart", function() {
$("a.added_to_cart").remove();
});
});
@makdas
Copy link

makdas commented Feb 18, 2016

For anyone using the https://docs.woothemes.com/document/minmax-quantities/ plugin. Here's an update to the minimum quantity rule.
on add-to-cart.php line 53:
<form action="<?php echo esc_url( $product->add_to_cart_url() ); ?>" class="cart" method="post" enctype='multipart/form-data'> <?php woocommerce_quantity_input(); ?> <?php $minimumamount = get_post_meta( $product->id, 'minimum_allowed_quantity',true ); if(empty($minimumamount)) $minimumamount = 1; ?> <button type="submit" data-quantity="<?php echo $minimumamount ?>" data-product_id="<?php echo $product->id; ?>" class="button alt add_to_cart_button ajax_add_to_cart product_type_simple"><?php echo $label; ?></button> </form>

@coltonbuchanan
Copy link

I'm able to get AJAX to work with the Add to Cart button, but for some reason changing the product quantity from the archive page loads the single-product template. Anyone know why that would be happening?

Edit: Fixed it. My anchor tag was wrapped around the form. I just added </a> before the form.

@webaware
Copy link
Author

@graemebryson thanks, was just updating a site for this and you saved me some time :)

@webaware
Copy link
Author

@graemebryson re: slow first time, should not be related to this script, probably more related to WooCommerce itself. Do you have a persistent object cache? (e.g. memcached)

@dej888
Copy link

dej888 commented Apr 7, 2016

Hello! I just updated to 2.5.5 woocommerce and this is broken now! (it worked fine for 2.5.4)

The problem - It is not adding the items to the cart. You need to refresh the page to get it to show the cart items... Please help, i have been looking for solutions, but am having no luck :(

@priambodokurniawan
Copy link

Thanks man!! perfect!

@SukcesStrony
Copy link

Thanks, it worked after a few JS tweaks for the theme I'm using. Acutally, my theme's so FUBAR that I'm using the main code inside mythemedirectory/woocommerce/single-product/add-to-cart/simple.php, at which point it seems that wp_enqueueing isn't possible. So, I had to throw in these lines into functions.php instead of the main code:

// script for add-to-cart with qty
wp_enqueue_script('qty-add-to-cart', get_stylesheet_directory_uri() . '/js/qty-add-to-cart.js', array('jquery'), '1.0.1', true);

@kienhubt
Copy link

please help me how to
2nd click , it can remove products from cart

@xnnx
Copy link

xnnx commented Jun 7, 2016

Help!
Everything looks fine, but it disregards the quantity input. Only one item is added to the cart. Your help will be greatly appreciated as I'm stuck with this feature for months.
Thank you.

@zavod008
Copy link

zavod008 commented Aug 7, 2016

Thanks, its working!

@ibby89
Copy link

ibby89 commented Feb 9, 2017

Is there a way to make this work on pages using woocommerce single product shortcodes? It works fine on shop/archive pages but unfortunately I cannot get it to show on a custom page I have...

@0ljik
Copy link

0ljik commented Mar 30, 2017

Thanks, it's working but not like I want. First one is that quantity input goes into - numbers. And the second one is I want to have control over it. Like placing it wherever I want: center or in line with button and remove Price tag. I want something like in site plov.com or plov.kz. Please help me do that. I use Widgetkit grid to show products on homepage and I have add to cart button in that grid. Quantity input shows left aligned and button is Centered.

@antoinehenrich
Copy link

When WP_Debug enabled I get 10000 of errors, because get $product->product_type should not be requested in the file.

@braciawrite
Copy link

It's work but does not send value from input. I have + and - buttons. When I enter the number of works, but that's not the point

@braciawrite
Copy link

braciawrite commented Mar 15, 2018

I've rewritten the andrewmclagan code and it works!

$(".add_to_cart_button.product_type_simple").on('click', function() { var $button = $(this); $button.data('quantity', $button.parent().find('input.qty').val()); });

Thanks Bro!

@MoritzSchreiner
Copy link

Hi,
Since I updated my page, the function doesn't work anymore.
It always only adds one product to the cart.

Thanks for the help.

@MoritzSchreiner
Copy link

@xnnx were you able to fix the issue?

@projecthires
Copy link

Hi, I would like the quantity selector button only to show on the loop if the product is a certain category. I tried adding this code to replace line 50 in the add-to-cart.php file, but I can't get it to work. Is this the wrong code or am I inserting into the wrong place (or does this just not work)?

if ( $product->product_type == 'simple' && $product->get_category_ids == '19' ) {

@khmubashar
Copy link

khmubashar commented Jul 28, 2019

This code is working fine to add the item in mini ajax cart, but a one issue is when i choose multiple qty it update only one qty. Simply to say the qty is not updating. can anyone help to resolve this qty update issue. As well as it is not removing view cart link. When performing the add to cart action.

@tcblaize
Copy link

Worked perfect for me. THANKS!

(does anyone know how to implement the loader on the button like the default woocommerce one?)

@tcblaize
Copy link

Worked perfect for me. THANKS!

(does anyone know how to implement the loader on the button like the default woocommerce one?)

NVM, used the "adding_to_cart" and "added_to_cart" hooks in the JS

@ablears
Copy link

ablears commented Apr 2, 2020

Unfortunately, this no longer works with Woo 4.0.1 - the quantity sent is always 1.

@danmeade
Copy link

danmeade commented Apr 27, 2020

Can confirm that this is no longer working with Woo 4.*

@JamboMedia
Copy link

Yes, not working anymore after upgrade. Hope there will be a fix soon.

@mr-biggleswirth
Copy link

mr-biggleswirth commented May 11, 2020

After Woo 4.0+, I've found that adjusting the JS to the following does the trick:

$(".button.product_type_simple.add_to_cart_button.ajax_add_to_cart").on('click', function() { var $button = $(this); $button.attr('data-quantity', $button.parent().find('input.qty').val()); });

Using .data() is apparently the wrong thing to use in this case, according to the docs.

Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr.

So instead, we are explicitly updating the data-quantity attribute to the input value using .attr().

@JamboMedia
Copy link

Many thanks! It works :)

@mnb546
Copy link

mnb546 commented Sep 29, 2020

After Woo 4.0+, I've found that adjusting the JS to the following does the trick:

$(".button.product_type_simple.add_to_cart_button.ajax_add_to_cart").on('click', function() { var $button = $(this); $button.attr('data-quantity', $button.parent().find('input.qty').val()); });

Using .data() is apparently the wrong thing to use in this case, according to the docs.

Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr.

So instead, we are explicitly updating the data-quantity attribute to the input value using .attr().

Not sure why, but this worked until I updated Woo in September 2020. Now the quantity I set doesn't reflect on cart. Instead only 1 product is added.

EDIT: For me it was necessary to add another parent() function.

$(".button.product_type_simple.add_to_cart_button.ajax_add_to_cart").on('click', function() { var $button = $(this); $button.attr('data-quantity', $button.parent().parent().find('input.qty').val()); });

@inspiredearth
Copy link

After Woo 4.0+, I've found that adjusting the JS to the following does the trick:

$(".button.product_type_simple.add_to_cart_button.ajax_add_to_cart").on('click', function() { var $button = $(this); $button.attr('data-quantity', $button.parent().find('input.qty').val()); });

Using .data() is apparently the wrong thing to use in this case, according to the docs.

Using the data() method to update data does not affect attributes in the DOM. To set a data-* attribute value, use attr.

So instead, we are explicitly updating the data-quantity attribute to the input value using .attr().

Are you saying you replaced the following from the js file, with the code you've provided?

   $("form.cart").on("change", "input.qty", function() {
        if (this.value === "0")
            this.value = "1";

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

@arenonana
Copy link

i'm using Woocommerce 4.8 and i got this:
" Fatal error: Uncaught Error: Call to a member function get_price() on null "

@Oliviercreativ
Copy link

Oliviercreativ commented Apr 20, 2021

Hello,
I was wondering if it was possible when you click on the "-" button (in my archive page) that removes the quantity of the product in the cart (in ajax)?

I want to reproduce the same system as in the basket, add or delete the ajax quantities with the minus and the plus.

Do you have an idea please?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment