Add to Cart button directly in Products List

Hello to all, My first message here. Well, I’m using Reflow against BSS since some days. I need a product list with an add to cart button for every item in the list. So, not a list that leads to each specific product page, but a list to be able to order directly from it. This requirement since this shop will be used/accessed by my current customers only (a kind of shop for payment about things we already discussed together) and they know the products they want to pay for; so, no need to launch product detail. For now, I worked around the case adding products (one by one) to a page to mimic a list in card mode, but the issue is that it’s limited to 10 products (searching why not all the products were rendered, I saw in the Reflow’s toolkit a function limiting it to 10 items per page). So, the addition of an add-to-cart button directly in the provided “Product List” (as an ON/OFF option in BSS) would be nice (at least for me:)…


EDIT: something like this (fictive products of course):

1 Like

OK, awaiting it exists (or not:) in the regular package, here is my “temporary” solution:

// Add an add-to-cart button to products in Products List
// [elroot - 2022-04-03]

/* key as "ref-name = ref-price" */
var store = {"Test Thing = €1.02": "9052875881",
             "Test Token = €1.00": "9890681372",
              "Chose Test = €1.02": "997366310",
              "Jeton Test = €1.00": "9997328504",
              "Local Option = €250.00": "987864248",
              "Option Locale = €250.00": "902255457"};

$.fn.exists = function () {
   return this.length > 0;
}

function add_to_cart_in_product_list()
{  // Patch product list adding an add-to-cart button to each item
   // ALGO: added add-to-cart buttons are duplicated from an operational (template) one placed in the original DOM,
   //       then (and since jQuery clone(true) failed to copy event handlers) every button relays on this atc_proxy.
   const atc_proxy = $("span[data-reflow-type='add-to-cart']").first();
   if (!$(atc_proxy).exists()) {
      console.log("Missing add-to-cart template in original DOM");
      return;
   }
   
   const products = $(".ref-product");
   for (let i = 0; i < products.length; i++) {
      const product = $(products[i]);
      const name = product.find(".ref-name")[0];
      const price = product.find(".ref-price")[0];
      if (!$(name).exists() || !$(price).exists()) {
         consolde.log("Invalid product at position #" + i + " (missing ref-name and/or ref-price)")
         return;}
      const product_key = $(name).html() + " = " + $(price).html();
      
      let product_num = "";
      for (let key in store) {  
         if (key == product_key) {
            product_num = store[key];
         }
      }
      if (product_num === "") {
         console.log("Unable to find a product matching this key in store: '" + product_key + "'");
         return;
      }
      
      atc_proxy.clone().appendTo(product);   // NB: clone(true) failed to copy event handlers as expected; see ALGO above
      const atc_tree = product.find("span").css("data-reflow-type", "add-to-cart");
      for (let i = 0; i < atc_tree.length; i++) {
         $(atc_tree[i]).attr("data-reflow-product", product_num);
      }
      
      const atc_btn = product.find(".ref-button")[0];
      atc_btn.addEventListener('click', function(e) {
         e.preventDefault();
         atc_proxy.attr("data-reflow-product", product_num);
         atc_proxy.find("span").attr("data-reflow-product", product_num);
         atc_proxy.find("a")[0].click();
         /* DEBUG: 
         alert("Added product #" + product_num + " to cart!"); */
      }, false);      
   }
}

add_to_cart_in_product_list();

So, the main requirement is to place an hidden add-to-cart button that will act as a template (for the design) and a proxy (for the action). The benefit is that it doesn’t overload Reflow with tons of requests on rendering and, theoretically, you’re not limited in terms of quantity of products in the list.

Hoping it may help someone else…
Have a good sunday.

2 Likes

Boilerplate code and hard readable, but Goodjob my friend! Hope others will find it usefull!

1 Like

Thanks dickykreedz! You’re right, it would need some help*, but it’s just a quick workaround awaiting Reflow covers the case later…

  • Quick Help:
  1. You add a regular Product or “Add To Cart” component to the page (a “Add To Cart” should suffice, but I did it with a Product one since I searched another way at the beginning). In both cases, you just enable the button in the BSS options of the component (ie. “Show Add To Cart” or “Show Button”). For convenience, you’ll add “display: none;” in the styles of the component. This component will be handled as “atc_btn” in the Javascript code (“atc” meaning “add to cart”).

  2. You add a BSS “Product List” component in the same page. The products from component will be parsed to the “products” collection variable in the Javascript code. Take care that “Show Name” and “Show Price” should be enabled in BSS options (those will allow to identify the right product in store since there’s no exposed product number/reference in the Product List component).

  3. You edit the “store” key pairs array with your own products that you’ll find in your Reflow account. Another way (smarter or not, don’t know) would be to fetch (then arrange) the list using the Reflow API, but you should certainly cache it to prevent repetitive requests at every page loading.

  4. You copy/paste the full Javascript code in a JS file you create in BSS. Then, you call “add_to_cart_in_product_list();” late at the end of your handler for the onload event. You can add a small delay or wait for an element to be sure Reflow had enough time to render its Product List. To keep things simple, I did:

$(function()
{ 
    ... other stuff
    setTimeout(function(){
          add_to_cart_in_product_list();
    }, 1000);
});

  1. You save, export and load the concerned page in your browser. If something sounds wrong, some basic checking have been made in code, issuing an error message in the console (of the devtools reachable by F12 in Chrome). For example, if a product in the list doesn’t match the ones in your hardcoded array, it will tell you there.

  2. You applause yourself or you take chocolate you deserved (I took the second option).

That’s all folks ^.^
And bravo to the BSS Team, since I tested some and it’s far above anyway… Thanks!

Thank you for the suggestion and sharing a solution! At the moment there isn’t an official way to do this, but we will add the ability to show add to cart buttons in product list items in our next updates.

2 Likes