I'm creating a custom WooCommerce cart and updating the quantity of a cart item works correctly. The only problem is that it doesn't automatically refresh, only works after page load.
My current code, which uses the woocommerce_add_to_cart_fragments hook and uses the passed in $fragments object. According to what I've seen around this is the correct way to go, but this doesn't work and I've debugged and to me the problem seems to be that the $fragments I get in the hook doesn't have my original html but instead a html that looks like this:
<div class="widget_shopping_cart_content">
<ul class="woocommerce-mini-cart cart_list product_list_widget ">
<li class="woocommerce-mini-cart-item mini_cart_item">
<a href="http://velosity-dev-wordpress.local/cart/?remove_item=92cc227532d17e56e07902b254dfad10&_wpnonce=8ead5f2c51"
class="remove remove_from_cart_button" aria-label="Remove this item" data-product_id="92"
data-cart_item_key="92cc227532d17e56e07902b254dfad10" data-product_sku="">×</a> <a
href="http://velosity-dev-wordpress.local/product/subber-one/">
<img width="300" height="300"
src="http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-300x300.jpg"
class="attachment-woocommerce_thumbnail size-woocommerce_thumbnail" alt="" loading="lazy"
srcset="http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-300x300.jpg 300w, http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-150x150.jpg 150w, http://velosity-dev-wordpress.local/wp-content/uploads/2021/09/mathilde-langevin-WxHJEMUnlIM-unsplash-100x100.jpg 100w"
sizes="(max-width: 300px) 100vw, 300px" />Subber One </a>
<span class="quantity">2 × <span class="woocommerce-Price-amount amount"><bdi><span
class="woocommerce-Price-currencySymbol">$</span>349.00</bdi></span></span>
</li>
</ul>
<p class="woocommerce-mini-cart__total total">
<strong>Subtotal:</strong> <span class="woocommerce-Price-amount amount"><bdi><span
class="woocommerce-Price-currencySymbol">$</span>698.00</bdi></span>
</p>
<p class="woocommerce-mini-cart__buttons buttons"><a href="http://velosity-dev-wordpress.local/cart/"
class="button wc-forward">View cart</a><a href="http://velosity-dev-wordpress.local/checkout/"
class="button checkout wc-forward">Checkout</a></p>
I don't really know how to pass in the correct 'active' html in to this hook, so any pointer would be greatly appreciated! Big thanks in advance!
My custom cart html/php (inside a file called header-shopping-cart.php)
<div class="cart-items" id="cart-items">
<?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
<div class="cart-item">
<?php echo $cart_item['data']->get_image(); ?>
<div>
<h3><?php echo $cart_item['data']->get_title() ?></h3>
<div class="quantity">
<input type="number" id="quantity_614459a588590" class="input-text qty text" step="1" min="0" max=""
name="cart[<?php echo $cart_item_key ?>][qty]" value="<?php echo $cart_item['quantity'] ?>"
title="Qty" size="4" placeholder="" inputmode="numeric">
</div>
<div class="price"><?php echo $cart_item['data']->get_price_html() ?></div>
</div>
</div>
<div class="divider"></div>
<? endforeach; ?>
</div>
My JS function (inside custom.js)
jQuery(function ($) {
$(document).on("change", "input.qty", function () {
var $thisbutton = $(this);
var cart_item_key = $(this)
.attr("name")
.replace(/cart\[([\w]+)\]\[qty\]/g, "$1");
var item_quantity = $(this).val();
var currentVal = parseFloat(item_quantity);
$.ajax({
type: "POST",
url: cart_qty_ajax.ajax_url,
data: {
action: "my_cart_qty",
cart_item_key: cart_item_key,
quantity: currentVal,
},
success: function (response) {
jQuery(document.body).trigger("added_to_cart", [response.fragments, response.cart_hash, $thisbutton]);
},
});
});
});
My php-functions (inside functions.php)
<?php
function enqueue_cart_qty_ajax() {
wp_register_script( 'my_cart_qty-ajax-js', get_template_directory_uri() . '/js/custom.js', array( 'jquery' ), '', true );
wp_localize_script( 'my_cart_qty-ajax-js', 'cart_qty_ajax', array( 'ajax_url' => admin_url( 'admin-ajax.php' ) ) );
wp_enqueue_script( 'my_cart_qty-ajax-js' );
}
add_action('wp_enqueue_scripts', 'enqueue_cart_qty_ajax');
function ajax_my_cart_qty() {
// Set item key as the hash found in input.qty's name
$cart_item_key = $_POST['cart_item_key'];
$quantity = $_POST['quantity'];
// Get the array of values owned by the product we're updating
$threeball_product_values = WC()->cart->get_cart_item( $cart_item_key );
// Get the quantity of the item in the cart
$threeball_product_quantity = apply_filters( 'woocommerce_stock_amount_cart_item', apply_filters( 'woocommerce_stock_amount', preg_replace( "/[^0-9\.]/", '', filter_var($_POST['quantity'], FILTER_SANITIZE_NUMBER_INT)) ), $cart_item_key );
// Update cart validation
$passed_validation = apply_filters( 'woocommerce_update_cart_validation', true, $cart_item_key, $threeball_product_values, $threeball_product_quantity );
// Update the quantity of the item in the cart
if ( $passed_validation ) {
WC()->cart->set_quantity( $cart_item_key, $threeball_product_quantity, true );
}
// Refresh the page
echo do_shortcode( '[woocommerce_cart]' );
die();
}
add_action('wp_ajax_my_cart_qty', 'ajax_my_cart_qty');
add_action('wp_ajax_nopriv_my_cart_qty', 'ajax_my_cart_qty');
//Responsive cart
add_filter( 'woocommerce_add_to_cart_fragments', 'ajaxify_components', 10, 1 );
function ajaxify_components( $fragments ) {
ob_start();
?>
<div class="cart-items" id="cart-items">
<?php foreach(WC()->cart->get_cart() as $cart_item_key => $cart_item) : ?>
<div class="cart-item">
<?php echo $cart_item['data']->get_image(); ?>
<div>
<h3><?php echo $cart_item['data']->get_title() ?></h3>
<div class="quantity">
<input type="number" id="quantity_614459a588590" class="input-text qty text" step="1" min="0" max=""
name="cart[<?php echo $cart_item_key ?>][qty]" value="<?php echo $cart_item['quantity'] ?>"
title="Qty" size="4" placeholder="" inputmode="numeric">
</div>
<div class="price"><?php echo $cart_item['data']->get_price_html() ?></div>
</div>
</div>
<div class="divider"></div>
<? endforeach; ?>
</div>
<?php
$fragments['#cart-items'] = ob_get_clean();
return $fragments;
}
Hope someone can give me a pointer in the right direction. Thanks!
from Woocommerce wrong fragments passed back from woocommerce_add_to_cart_fragments
No comments:
Post a Comment