Ajaxify Header Cart Items Count in Woocommerce

Ajaxify header cart items count in Woocommerce

You should not use any reload to update the cart content count… Instead you should use the dedicated woocommerce_add_to_cart_fragments action hook that is Ajax powered.

1) The HTML to be refreshed: So first in your theme's header.php file you should need to embed the cart count in a specific html tag with a defined unique ID (or a class), for example something like:

$items_count = WC()->cart->get_cart_contents_count(); 
?>
<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>
<?php

or:

$items_count = WC()->cart->get_cart_contents_count();

echo '<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>';

2) The code:

add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_mini_cart_count');
function wc_refresh_mini_cart_count($fragments){
ob_start();
$items_count = WC()->cart->get_cart_contents_count();
?>
<div id="mini-cart-count"><?php echo $items_count ? $items_count : ' '; ?></div>
<?php
$fragments['#mini-cart-count'] = ob_get_clean();
return $fragments;
}

if you use a class in your html Tag, you will replace ['#mini-cart-count'] by ['.mini-cart-count']. This hook is also used to refresh the mini-cart content.

Code goes in function.php file of your active child theme (or theme) or also in any plugin file.

Since few years global $woocommerce; + $woocommerce->cart is outdated and replaced by WC()->cart to access WooCommerce cart object.


If you need jQuery to force refresh that count, you can try wc_fragment_refresh or wc_fragments_refreshed delegated events, like:

$(document.body).trigger('wc_fragment_refresh');

or:

$(document.body).trigger('wc_fragments_refreshed');

Ajax update product count on cart menu in Woocommerce

Updated

It's better to set a tag ID than a tag CLASS to ajaxify a cart count, as this selector reference need to be unique. If it's not the case, and there is a hidden mobile duplicated menu, it can't work.

So this item menu need to be unique on the generated html code of your page… If this menu item is duplicated in a mobile version, you will need to change the tag ID or the tag CLASS for the mobile code version.

I have revisited your code a bit:

add_filter( 'wp_setup_nav_menu_item','my_item_setup' );
function my_item_setup( $item ) {
if ( ! is_admin() && class_exists( 'woocommerce' ) ) {
if ( $item->url == esc_url( wc_get_cart_url() ) && ! WC()->cart->is_empty() ){
$title = get_locale() == 'fr_FR' ? 'PANIER' : 'MY CART';
$item->title = $title . ' (<span id="count-cart-items">' . WC()->cart->get_cart_contents_count() . '</span>)';
}
}
return $item;
}

add_filter( 'woocommerce_add_to_cart_fragments', 'wc_refresh_cart_fragments', 50, 1 );
function wc_refresh_cart_fragments( $fragments ){
$cart_count = WC()->cart->get_cart_contents_count();

// Normal version
$count_normal = '<span id="count-cart-items">' . $cart_count . '</span>';
$fragments['#count-cart-items'] = $count_normal;

// Mobile version
$count_mobile = '<span id="count-cart-itemob">' . $cart_count . '</span>';
$fragments['#count-cart-itemob'] = $count_mobile;

return $fragments;
}

Code goes in function.php file of your active child theme (active theme). It should better work.

WooCommerce quantity for different products only - header mini cart - count(WC()-cart-get_cart())

Resolved with different approach by adding a hook callback. Working perfectly.

 /**
* @snippet WC Mini Cart / Product Quantity Calculation by Unique Products - Excluding the same products
* @author Rkoms
**/

// define the woocommerce_cart_contents_count callback
function filter_woocommerce_cart_contents_count($unique_product_qty) {
// make filter magic happen here...
$unique_product_qty = count(WC()->cart->get_cart());
return $unique_product_qty;
};
// add the filter
add_filter( 'woocommerce_cart_contents_count', 'filter_woocommerce_cart_contents_count', 15, 1 );

Custom cart count is not updating without reloading in Woocommerce

There is some mistakes and missing things in your code. For the cart item count in your header the following will solve the problem.

1) The HTML code in your header.php file:

<ul>
<li>
<a href="/cart" id="cart_icon"></a>
</li>
<li>
<span class="counter" id="cart-count"><?php
$cart_count = WC()->cart->get_cart_contents_count();
echo sprintf ( _n( '%d', '%d', $cart_count ), $cart_count );
?></span>
</li>
<li id="access"><?php wp_nav_menu( array( 'sort_column' => 'menu_order', 'container_class' => 'menu-header' ) ); ?></li>
</ul>

2) Your related hooked function code to enable cart item count Ajax refreshed:

add_filter( 'woocommerce_add_to_cart_fragments', 'refresh_cart_count', 50, 1 );
function refresh_cart_count( $fragments ){
ob_start();
?>
<span class="counter" id="cart-count"><?php
$cart_count = WC()->cart->get_cart_contents_count();
echo sprintf ( _n( '%d', '%d', $cart_count ), $cart_count );
?></span>
<?php
$fragments['#cart-count'] = ob_get_clean();

return $fragments;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.


Related: Ajaxify the cart items count in Woocommerce

Ajax refreshing custom mini-cart count and content in Woocommerce

The following will compact your code and will ajax refresh the mini-cart count + the mini-cart content in the right way:

// Utility function that outputs the mini cart content
function my_wc_mini_cart_content(){
$cart = WC()->cart->get_cart();

foreach ( $cart as $cart_item_key => $cart_item ):
$_product = apply_filters( 'woocommerce_cart_item_product', $cart_item['data'], $cart_item, $cart_item_key );
$product_id = apply_filters( 'woocommerce_cart_item_product_id', $cart_item['product_id'], $cart_item, $cart_item_key );

if ( $_product && $_product->exists() && $cart_item['quantity'] > 0 && apply_filters( 'woocommerce_widget_cart_item_visible', true, $cart_item, $cart_item_key ) ) {
$product_name = apply_filters( 'woocommerce_cart_item_name', $_product->get_name(), $cart_item, $cart_item_key );
$thumbnail = apply_filters( 'woocommerce_cart_item_thumbnail', $_product->get_image(), $cart_item, $cart_item_key );
$product_price = apply_filters( 'woocommerce_cart_item_price', WC()->cart->get_product_price( $_product ), $cart_item, $cart_item_key );
if(isset($cart_item['variation']['attribute_pa_size'])) {
$variation_val = $cart_item['variation']['attribute_pa_size'];
$term_obj = get_term_by('slug', $variation_val, 'pa_size');
$size_name = $term_obj->name;
}
?>

<div class="media mini-cart__item woocommerce-mini-cart-item <?php echo esc_attr( apply_filters( 'woocommerce_mini_cart_item_class', 'mini_cart_item', $cart_item, $cart_item_key ) ); ?>">
<?php echo $thumbnail; ?>

<div class="media-body mini-cart__item_body">
<div class="mini-cart__item__heading mt-0"><?php echo $product_name; ?></div>
<?php
echo apply_filters( 'woocommerce_widget_cart_item_quantity', '<div class="cart__item__price">' .
sprintf( '%s × %s', $cart_item['quantity'], $product_price ) .
'</div>', $cart_item, $cart_item_key );

if( isset($size_name) ) { ?>
<div class="mini-cart__item__size"><?php echo $size_name; ?></div>
<?php } ?>
</div>

<div class="mini-cart__item_remove ">
<?php
echo apply_filters( 'woocommerce_cart_item_remove_link', sprintf(
'<a href="%s" class="remove remove_from_cart_button" aria-label="%s" data-product_id="%s" data-cart_item_key="%s" data-product_sku="%s">×</a>',
esc_url( wc_get_cart_remove_url( $cart_item_key ) ),
__( 'Remove this item', 'woocommerce' ),
esc_attr( $product_id ),
esc_attr( $cart_item_key ),
esc_attr( $_product->get_sku() )
), $cart_item_key );
?>
</div>
</div>
<?php
}
endforeach; ?>

<a href="<?php echo get_permalink( wc_get_page_id( 'checkout' ) ); ?>" class="btn btn-dark btn-block"><span class="btn__text"><?php _e('Checkout', 'frosted'); ?></span></a>
<?php
}

// Hooked: The mini cart count and the cart content
add_action( 'frosted_header_top', 'my_wc_mini_cart' );
function my_wc_mini_cart() {
if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) {
$count = WC()->cart->get_cart_contents_count();
?>
<a href="#"><?php _e('Cart', 'frosted'); ?> <span id="cart_count" class="cart__amount"><?php echo esc_html( $count ); ?></span></a>
<div id="mini-cart-content" class="sub-menu sub-menu--right sub-menu--cart">
<?php my_wc_mini_cart_content(); ?>
</div>
<?php
}
}

// Ajax refreshing mini cart count and content
add_filter( 'woocommerce_add_to_cart_fragments', 'my_header_add_to_cart_fragment' );
function my_header_add_to_cart_fragment( $fragments ) {
$count = WC()->cart->get_cart_contents_count();

$fragments['#cart_count'] = '<span id="cart_count" class="cart__amount">' . esc_attr( $count ) . '</span>';

ob_start();
?>
<div id="mini-cart-content" class="sub-menu sub-menu--right sub-menu--cart">
<?php my_wc_mini_cart_content(); ?>
<div>
<?php

$fragments['#mini-cart-content'] = ob_get_clean();

return $fragments;
}

Code goes in function.php file of your active child theme (or active theme). Tested and works.



Related Topics



Leave a reply



Submit