wpmenucart-ajax-assist.js script broken
-
Hello,
I took a look at the following script because my mobile menu cart menu item does not disappear when the cart is emptied through ajax:
assets/js/wpmenucart-ajax-assist.js
There is no way it is going to work when an item is removed from the cart and the cart becomes empty. Only the adding_to_cart action is bound.
- This topic was modified 7 years ago by therealgilles.
-
Additionally the code below needs to be inside the bind call so that the state of the cart is re-evaluated properly:
if ( typeof window.Cookies !== 'undefined' ) { // WC3.0 items_in_cart = Cookies.get( 'woocommerce_items_in_cart' ); } else if ( typeof $.cookie !== 'undefined' && $.isFunction($.cookie) ){ // WC2.X items_in_cart = $.cookie( 'woocommerce_items_in_cart' ); } else { return; // no business here } if ( items_in_cart > 0 ) { $('.empty-wpmenucart').removeClass('empty-wpmenucart'); } else if ( !(wpmenucart_ajax_assist.always_display) ) { $('.wpmenucartli').addClass('empty-wpmenucart'); $('.wpmenucart-shortcode').addClass('empty-wpmenucart'); }
- This reply was modified 7 years ago by therealgilles.
- This reply was modified 7 years ago by therealgilles.
I believe the correct action to bind to is ‘updated_wc_div’.
Mentioning that:
$( document.body ).bind( <action>, function() {
is deprecated, and should instead be written as:
$( document.body ).on( <action>, function() {
- This reply was modified 7 years ago by therealgilles.
- This reply was modified 7 years ago by therealgilles.
- This reply was modified 7 years ago by therealgilles.
Hi @chamois_blanc!
Thank you so much for contributing. The ajax assist script is actually specifically for assistence with server side caching, on non-cached sites it should work without this script too. That’s why this function is not bound to any trigger besides the add-to-cart, it’s only intended to be run once on page load to override cached CSS classes in the menu item. That’s also why there is no specific binding to the AJAX remove from cart action, as this would already trigger an update of the fragments.I think the issue you’re describing is resolved with the following script:
jQuery( function( $ ) { /* Cart Hiding */ if (wpmenucart_ajax_assist.shop_plugin == 'WooCommerce' ) { // update on page load wpmenucart_update_menu_classes(); // update when cart is updated $( document.body ).on( 'adding_to_cart updated_wc_div', wpmenucart_update_menu_classes ); } function wpmenucart_update_menu_classes() { if ( typeof window.Cookies !== 'undefined' ) { // WC3.0 items_in_cart = Cookies.get( 'woocommerce_items_in_cart' ); } else if ( typeof $.cookie !== 'undefined' && $.isFunction($.cookie) ){ // WC2.X items_in_cart = $.cookie( 'woocommerce_items_in_cart' ); } else { return; // no business here } if ( items_in_cart > 0 ) { $('.empty-wpmenucart').removeClass('empty-wpmenucart'); } else if ( !(wpmenucart_ajax_assist.always_display) ) { $('.wpmenucartli').addClass('empty-wpmenucart'); $('.wpmenucart-shortcode').addClass('empty-wpmenucart'); } } });
Can you confirm this?
Thanks!
EwoutWill do. Wouldn’t added_to_cart be better than adding_to_cart? adding_to_cart is used prior to modifying the cart content, while added_to_cart is used once the cart content is done. The latter is a better time to update the menu item.
A few other notes:
The ajax assist script is actually specifically for assistence with server side caching, on non-cached sites it should work without this script too.
What do you mean by ‘server-side caching’? Woocommerce uses ajax requests to update the cart content without having to reload the page. This is not server-side caching in my mind.
That’s why this function is not bound to any trigger besides the add-to-cart, it’s only intended to be run once on page load to override cached CSS classes in the menu item.
Not sure what you mean by ‘cached CSS classes’. The code updates the DOM to remove some of the classes and add other ones. I guess you could say the browser caches the CSS classes, but that’s not usually how people use the word.
That’s also why there is no specific binding to the AJAX remove from cart action, as this would already trigger an update of the fragments.
I am a bit confused by this statement. Updating the fragments does not necessarily reload the page and it won’t automatically update the menu item content either. That’s why you have assets/js/wpmenucart.js which triggers on listed button clicks.
In my opinion, the file should have triggers on added_to_cart and updated_wc_div instead, and the code above should be integrated with it with the CSS classes updated appropriately. The button click specific code should then not be necessary anymore. This is for Woocommerce only obviously.
Using added_to_cart ought to allow you to replace:
setTimeout(function () { WPMenucart_Load_JS(); }, 1000);
by just this:
WPMenucart_Load_JS();
as everything should be up-to-date when the event triggers.
Caveats: not sure how it would fair with older versions of Woocommerce.
What do you mean by ‘server-side caching’? Woocommerce uses ajax requests to update the cart content without having to reload the page. This is not server-side caching in my mind.
By server side caching I mean varnish cache, W3 Total Cache, WP Rocket – anything that prerenders pages and serves that instead of dynamically generating them all the time. Indeed, WooCommerce uses AJAX to update the cart contents, and this works fine and does not suffer from server side caching. However, this only updates the actual cart contents and not it’s wrappers. WooCommerce faces a similar issue with their own mini-cart and have a similar solution.
Not sure what you mean by ‘cached CSS classes’. The code updates the DOM to remove some of the classes and add other ones. I guess you could say the browser caches the CSS classes, but that’s not usually how people use the word.
I am referring to the CSS classes in the li menu element (specifically, the class that defines whether it’s empty:
empty-wpmenucart
). Normally WP Menu Cart dynamically sets these, based on the content of the cart. But server side caching makes this static, which would produce unreliable results. Hence this ajax-assist script ??I am a bit confused by this statement. Updating the fragments does not necessarily reload the page and it won’t automatically update the menu item content either. That’s why you have assets/js/wpmenucart.js which triggers on listed button clicks.
In my opinion, the file should have triggers on added_to_cart and updated_wc_div instead, and the code above should be integrated with it with the CSS classes updated appropriately. The button click specific code should then not be necessary anymore. This is for Woocommerce only obviously.
Using added_to_cart ought to allow you to replace:
setTimeout(function () { WPMenucart_Load_JS(); }, 1000);
by just this:
WPMenucart_Load_JS();
as everything should be up-to-date when the event triggers.
Actually, updating fragments does update the menucart automatically, as it has been added to the fragments data using
woocommerce_add_to_cart_fragments
: source.
The additional script you are referring to is not used on default installations and only there for fallback purposes (primarily outside WooCommerce anyway (the plugin works with multiple shop plugins), since WooCommerce fragments work excellent most of the time also since most caching plugins have taken this into account).
There is no need to reload the page after something has been added to the cart, we have AJAX to account for just the menu cart bit. Thewpmenucart-ajax-assist.js
script was only ran at the initial page load to prevent any cachedempty-wpmenucart
class from overriding the actual cart state.added_to_cart
oradding_to_cart
does not make a big difference anyway, it’s only to set or unset theempty-wpmenucart
class in the item (the actual contents are updated by WooCommerce fragments when WC receives the ajax response). When something is added to the cart it can start removing the class regardless of the result. Semantically I agree, but I have decided to stick with the behavior WC has for the mini-cart to keep everything consistent.This is unrelated to the
WPMenucart_Load_JS
function that you are referring to which is only there for fallback/backup purposes and not used in WC unless there are issues with WooCommerce fragments (mostly a thing of the past). A delay like this wouldn’t be necessary for WooCommerce because it triggers events when it’s done, but some of the other shop plugins do not have such triggers so we rely on more basic solutions.Hope that clarifies things ??
Should you have any follow up questions, do not hesitate to send an email to [email protected] (also since you appear to be using the pro version, you are entitled to priority support). Also, do note that some of what you may seeing could be both WooCommerce & Pro specific. Pro is a bit more advanced in this aspect!
Have a fantastic weekend!
EwoutA quick PS to avoid some confusion:
The initial issue you posted here was an actual bug, but only in Pro, not in the free version (which does not have theempty-wpmenucart
class at the top-level li item). Removing from cart via AJAX has only recently been introduced to WC and this hadn’t been taken into account yet.
The cart would still update on the next page load, except if you had server side caching which is what the ajax-assist script would then fix when the page loaded – cart hidden again (if configured as such in the settings).Since the free version did not have that
empty-wpmenucart
class at the top-level li item, WC AJAX fragments would take care of the cart changes, including removal. (free only has the<a>
element which would be updated by the fragments and include the class that would hide it, pro has a submenu<ul>
next to it so we hide the entire top level item).Updates for both Pro and the free version were released today that address this issue. Thank you for contributing!
Ewout
Thank you for the updates. I will try them out at some point, although I have already implemented my own workarounds.
WooCommerce uses AJAX to update the cart contents, and this works fine and does not suffer from server side caching.
It depends on how the server-side caching is done. Varnish, for instance, can cache everything, including ajax requests/responses.
Semantically I agree, but I have decided to stick with the behavior WC has for the mini-cart to keep everything consistent.
I am afraid adding_to_cart won’t work well when the cart is being emptied as the cart content hasn’t been updated yet at this point. The setTimeout delay may be masking / working around this “bug”.
I am afraid adding_to_cart won’t work well when the cart is being emptied as the cart content hasn’t been updated yet at this point. The setTimeout delay may be masking / working around this “bug”.
WooCommerce triggers the
updated_wc_div
(whats in a name) event when the cart is emptied (or updated otherwise) – this is also what I have bound for the ajax-assist script.Happy holidays!
Ewout
- The topic ‘wpmenucart-ajax-assist.js script broken’ is closed to new replies.