I am new to Woocommerce. I was trying to show the quantity box in the shop page. I have used the below code and it's working as expected:
add_action( 'woocommerce_before_shop_loop', 'handsome_bearded_guy_select_variations' );
function handsome_bearded_guy_select_variations() {
remove_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_loop_add_to_cart', 10 );
add_action( 'woocommerce_after_shop_loop_item', 'woocommerce_template_single_add_to_cart', 30 );
}
But the problem is that ajax add to cart button got replaced with default one.
How can I enable back the ajax functionality on add to cart button with quantity field for Woocommerce archives pages?
Updated (2019) - Removed the quantity bug
This can be done with the following code, that is very similar to the original one, using a custom hooked function in dedicated woocommerce_loop_add_to_cart_link
filter hook and a bit of jQuery.
Now as it's ajax powered like before, once adding to cart, you will get the additional button "View cart" on right side (that you can hide: see at the end how).
You will have to make some CSS styling on this...
The code:
add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) {
if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
// Get the necessary classes
$class = implode( ' ', array_filter( array(
'button',
'product_type_' . $product->get_type(),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
) ) );
// Adding embeding <form> tag and the quantity field
$html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>%s',
'<form class="cart">',
woocommerce_quantity_input( array(), $product, false ),
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->get_id() ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() ),
'</form>'
);
}
return $html;
}
add_action( 'wp_footer' , 'archives_quantity_fields_script' );
function archives_quantity_fields_script(){
<script type='text/javascript'>
?>
jQuery(function($){
// Update quantity
$(".add_to_cart_button.product_type_simple").on('click input', function() {
$(this).data('quantity', $(this).parent().find('input.qty').val() );
});
// On "adding_to_cart" delegated event, removes others "view cart" buttons
$(document.body).on("adding_to_cart", function() {
$(".added_to_cart").remove();
});
});
</script>
<?php //endif;
}
Code goes in function.php file of your active child theme (active theme). Tested and works.
Hiding additional "View cart" button button (when using ajax add to cart):
Then you can first remove this from the jQuery code:
// On "adding_to_cart" delegated event, removes others "view cart" buttons
$(document.body).on("adding_to_cart", function() {
$(".added_to_cart").remove();
});
1) You can add this CSS rule to your styles.css file located in your active theme:
a.added_to_cart.wc-forward {
display:none;
}
2) You can use the following hoocked function (first option is the best way):
add_action( 'wp_head' , 'hide_ajax_view_cart_button' );
function hide_ajax_view_cart_button(){
if( is_shop() || is_product_category() || is_product_tag() ): ?>
<style>
a.added_to_cart.wc-forward {
display:none;
}
</style>
<?php endif;
}
Code goes in function.php file of your active child theme (active theme).
tested and works.
Does everything as above, without the "quantity bug".
The code:
add_filter( 'woocommerce_loop_add_to_cart_link', 'quantity_inputs_for_loop_ajax_add_to_cart', 10, 2 );
function quantity_inputs_for_loop_ajax_add_to_cart( $html, $product ) {
if ( $product && $product->is_type( 'simple' ) && $product->is_purchasable() && $product->is_in_stock() && ! $product->is_sold_individually() ) {
// Get the necessary classes
$class = implode( ' ', array_filter( array(
'button',
'product_type_' . $product->get_type(),
$product->is_purchasable() && $product->is_in_stock() ? 'add_to_cart_button' : '',
$product->supports( 'ajax_add_to_cart' ) ? 'ajax_add_to_cart' : '',
) ) );
// Adding embeding <form> tag and the quantity field
$html = sprintf( '%s%s<a rel="nofollow" href="%s" data-quantity="%s" data-product_id="%s" data-product_sku="%s" class="%s">%s</a>%s',
'<form class="cart">',
woocommerce_quantity_input( array(), $product, false ),
esc_url( $product->add_to_cart_url() ),
esc_attr( isset( $quantity ) ? $quantity : 1 ),
esc_attr( $product->get_id() ),
esc_attr( $product->get_sku() ),
esc_attr( isset( $class ) ? $class : 'button' ),
esc_html( $product->add_to_cart_text() ),
'</form>'
);
}
return $html;
}
add_action( 'wp_footer' , 'archives_quantity_fields_script' );
function archives_quantity_fields_script(){
//if( is_shop() || is_product_category() || is_product_tag() ): ?>
<script type='text/javascript'>
jQuery(function($){
// Update quantity on 'a.button' in 'data-quantity' attribute (for ajax)
$(".add_to_cart_button.product_type_simple").on('click', function() { var $button = $(this); $button.data('quantity', $button.parent().find('input.qty').val()); });
// remove old "view cart" text, only need latest one thanks!
$(document.body).on("adding_to_cart", function() {
$("a.added_to_cart").remove();
});
});
</script>
<?php //endif;
}
References:
@LoicTheAztec's entry above 11 Feb 2018.
@braciawrite's and @andrewmclagan's GitHub entries on 11 Dec 2015 and 15 Mar 2018 respectively.
https://gist.github.com/webaware/6260326
Note:
Code should perform the check when "add_to_cart" button is pressed, not on quantity change.
I've commented out the if and endif statements under function "archives_quantity_fields_script" as I am running this code on a custom page with WooCommerce products.
Hope this helps!