Remove specific products from cart on change

Topic summary

Issue: A developer is trying to implement a cart feature that removes all products with a data-collection attribute of “tier-1” through “tier-5” whenever a customer decreases quantity or removes any product from the cart.

Problem: The initial script either removes all products from the cart or only removes one tier product when multiple tier products exist. When testing with 5 products (3 with tier attributes, 2 without), removing a non-tier product only removes one tier product instead of all three.

Attempted Solutions:

  • Keshan97 provided two code iterations focusing on:
    • Collecting tier products into an array
    • Using AJAX requests to set quantity to 0 for each tier product
    • Refreshing the cart after all removals complete
    • Using jQuery promises to track multiple AJAX requests

Current Status: The issue persists after implementing the suggested solutions. The script still fails to remove all tier products simultaneously, indicating a potential problem with the AJAX request handling, cart update mechanism, or product identification logic. The discussion remains unresolved with the developer reporting “still the same bug.”

Summarized with AI on November 10. AI used: claude-sonnet-4-5-20250929.

Hello, Im trying to make a specific feature. the concept of this feature is to check in the cart whether there is a product holding a data-collection attribute = tier-1 … tier-5

Only in this scenario, the script will fire.

So for example, if i have 100 product in the cart, no product has this data attribute == tier-1 … tier-5 , then nothing will happen.

once i have 1 product at least having this attribute, the script will fire.

what i want to do is:

  1. check if data attribute exist.

  2. if exist, then i want to make that everytime a customer lower the quantity (using the input or button - ), or remove any product from the cart, to remove all the product that have the data-attribute = tier-1, tier-2 … tier-5.

  3. refresh and update the cart.

in my code i added clear.js. the script worked fine to me and fires when the product with data-collection exists, but this removes all the product from the whole cart.

the code i wrote:

$(document).ready(function() { 
    // Flag to check if tier-1 to tier-5 product exists
    var hasTierProduct = false;

    // Iterate over the cart items
    $('.media-link').each(function() {
      var collection = $(this).attr('data-collection').trim().toLowerCase();
      
      // Check if the data-collection attribute contains 'tier-'
      if (collection.includes('tier-')) {
        var tier = parseInt(collection.split('tier-')[1]);
        
        // Check if the tier is within the range of 1 to 5
        if (tier >= 1 && tier <= 5) {
          hasTierProduct = true; // Set flag to true if tier product found
        }
      }
    });
  $(document).on("click change", ".sd_mini_removeproduct, .quantity-button.quantity-down, .ajaxcart__qty-num", function (evt) {
  if (hasTierProduct) {
    $.ajax({
      url: "/cart/clear.js",
      method: "POST",
      success: function() {
        console.log('Cart cleared');
        // Reload the page or update cart contents as needed
        location.reload();
      }
    });
  }
});

});

Your concept and initial implementation are on the right track, but it seems like the script’s logic is not fully aligned with your requirements, especially in differentiating between removing all products and only those with a specific data-collection attribute. Here’s how you can refine your approach to achieve the desired functionality:

  1. Refine Attribute Check: Initially, ensure that your script correctly identifies cart items with the specified data-collection attribute (tier-1 to tier-5). It’s essential to verify that this part works as intended.

  2. Adjust Action on Quantity Decrease or Removal: Instead of clearing the entire cart, you’ll want to specifically target and remove items that match the tier-1 to tier-5 criteria when a product quantity is decreased or a product is removed.

  3. Update the Cart Accordingly: After removing the specified items, you’ll need to refresh or update the cart to reflect these changes.

Given your description, let’s adjust your script to focus on removing only the products with the tier- data attribute upon a quantity decrease or product removal, rather than clearing the entire cart.

$(document).ready(function() {
    // Function to check and remove tier products
    function checkAndRemoveTierProducts() {
        // Variable to hold products to be removed
        let productsToRemove = [];

        // Iterate over cart items to find tier products
        $('.media-link').each(function() {
            var collection = $(this).attr('data-collection').trim().toLowerCase();
            if (collection.includes('tier-')) {
                var tier = parseInt(collection.split('tier-')[1]);
                if (tier >= 1 && tier <= 5) {
                    // Assuming there's a way to identify each product uniquely, e.g., by a data attribute like data-line-item-key
                    productsToRemove.push($(this).attr('data-line-item-key'));
                }
            }
        });

        // Remove identified tier products from the cart
        if (productsToRemove.length > 0) {
            productsToRemove.forEach(function(lineItemKey) {
                $.ajax({
                    url: `/cart/change.js`,
                    method: "POST",
                    data: { quantity: 0, line: lineItemKey }, // Set quantity to 0 to remove the item
                    success: function(cart) {
                        console.log('Tier product removed from cart');
                        // Optionally, refresh the cart display here without a full page reload
                    }
                });
            });
        }
    }

    // Bind the function to events that indicate a potential change in cart item quantities or removals
    $(document).on("click change", ".sd_mini_removeproduct, .quantity-button.quantity-down, .ajaxcart__qty-num", function(evt) {
        checkAndRemoveTierProducts();
        // Consider debouncing this function if it gets triggered too frequently
    });
});

Key Changes and Considerations- Targeted Removal: This script specifically targets and removes products identified by the tier-1 to tier-5 attributes. Ensure each cart item can be uniquely identified for removal, such as by using a data-line-item-key attribute or similar.

  • Ajax Requests: For each tier- product found, an AJAX request is made to update the cart by setting the item’s quantity to 0, effectively removing it. Adjust the url and data parameters as necessary to match your cart system’s API requirements.
  • Cart Update: This approach may result in multiple AJAX requests if several tier- products are found. Consider how to efficiently refresh the cart display to reflect these changes, potentially aggregating changes to minimize the number of requests.
1 Like

REPLIED IN THE REPLY ABOVE

In Fact, it worked for only 1 product in the cart with data-collection tier1… tier5.

assume now i have 5 products, 3 products has data-collection tier-2, tier-3 and tier-4 respectively, and the 2 other products has any data-collection attribute,

when i removed any of the 2 other products, it only removed 1 product from the tier- … products.

here is the 2 screenshots to explain:

1, BEFORE I REMOVE A PRODUCT:

AFTER I REMOVED THE PRODUCT:

Can you try this code:

$(document).ready(function() {
    // Function to identify and remove all tier products from the cart
    function removeTierProducts() {
        // Collect all tier products' data-line values
        let tierProductLines = $('.media-link[data-collection^="tier-"]').map(function() {
            return $(this).data('line');
        }).get();
        
        // If there are tier products, remove them
        if (tierProductLines.length) {
            let ajaxRequests = [];
            
            $.each(tierProductLines, function(index, line) {
                // Store AJAX promises in an array to track when all requests are completed
                ajaxRequests.push(
                    $.ajax({
                        url: '/cart/change.js',
                        method: 'POST',
                        data: {
                            line: line,
                            quantity: 0
                        },
                        dataType: 'json'
                    })
                );
            });
            
            // When all AJAX requests are done, refresh the cart
            $.when.apply($, ajaxRequests).done(function() {
                // All tier products have been removed, now refresh the cart
                console.log('All tier products removed');
                location.reload(); // or use your cart's update mechanism
            });
        }
    }
    
    // Bind to cart change/remove events
    $(document).on('click change', '.sd_mini_removeproduct, .quantity-button.quantity-down, .ajaxcart__qty-num', function() {
        removeTierProducts();
    });
});

still the same bug @Keshan97