woocommerce / woocommerce-google-analytics-integration

WordPress plugin: Provides the integration between WooCommerce and Google Analytics.
http://wordpress.org/plugins/woocommerce-google-analytics-integration/
172 stars 69 forks source link

Handle AJAX add to cart for simple products #386

Closed mikkamp closed 7 months ago

mikkamp commented 7 months ago

Changes proposed in this Pull Request:

This PR resolves the issue that an add to cart AJAX request from a single product page was throwing an error. WC core doesn't handle AJAX from single product pages, however it can be replicated with a plugin. It's also quite common for themes to include this kind of behaviour.

Reported in the forum: https://wordpress.org/support/topic/js-error-on-product-page-2/

The PR resolved two issues:

  1. If the product data attribute is not available on the add to cart button, then extract it from the value (WC sets it on the value in this template).
  2. The handlers / formatter is given the result of searching for a product. However in some cases a product is not found by the function getProductFromID, in such cases we need to prevent from formatting the data.

We also need to be careful with the handler document.body.onadded_to_cart as we always hook into this regardless if we disable add_to_cart tracking, should we conditionally hook into that event?

Closes #382

Detailed test instructions:

  1. Setup tracking including add_to_cart tracking
  2. Install a plugin to do AJAX add to cart: https://wordpress.org/plugins/woo-ajax-add-to-cart/
  3. Create a simple product
  4. Add simple product on a single product page
  5. Confirm that the product is tracked
  6. Create a page with the shortcode [products] and ensure AJAX add to cart on archives is enabled in WC > Settings
  7. Add a simple product from the archive page
  8. Confirm that the product is tracked

Additional details:

This PR points out a separate issue that we search for products in the cart items first and then the list of products, see here.

That's a problem when it comes to the quantity number, which we can see in the following scenario:

  1. Add single product 3x to cart
  2. Refresh archive page
  3. Add same single product to cart
  4. View tracking data and the quantity is set to 3

Ideally we should be setting the quantity back to 1. Also is it really relevant to search through cart data, even though the product ID matches, we might have added one with a discount / addon which could make the price different. We'll need to log this in a separate issue.

Another issue is that it still won't work for variable products added to AJAX as we'll need to access the form data to find out which variation was selected.

Changelog entry

puntope commented 7 months ago

Thanks @mikkamp ✅ LGTM

Create a page with the shortcode [products] and ensure AJAX add to cart on archives is enabled in WC > Settings Add a simple product from the archive page Confirm that the product is tracked

These 3 steps are also fixed in https://github.com/woocommerce/woocommerce-google-analytics-integration/pull/378 (or at least I cannot reproduce them when using that branch) So I tested everything with that branch merged as well to be sure is not a conflict and is handled twice.

mikkamp commented 7 months ago

These 3 steps are also fixed in https://github.com/woocommerce/woocommerce-google-analytics-integration/pull/378 (or at least I cannot reproduce them when using that branch) So I tested everything with that branch merged as well to be sure is not a conflict and is handled twice.

Thanks for double checking. The adjusted logic makes it hard to reproduce after #378, but the important part of this PR is that it also falls back to getting the product ID from the value of a button (which is where WC places it for simple products).

Since this is approved I'm going to go ahead and merge it.

lith-imad commented 7 months ago

Another issue is that it still won't work for variable products added to AJAX as we'll need to access the form data to find out which variation was selected.

I think this is a critical bug and should be fixed in its own issue. For anyone who is looking for a quick fix, here's what I've done as workaround:

var addToCartButton = document.querySelector('.single_add_to_cart_button');
if (addToCartButton) {
    addToCartButton.dataset.product_id =  addToCartButton.parentElement.querySelector('input[name="product_id"]')?.value;
}