Accessing variant quantity data with Shopify Buy Button

evenvisionstaff
New Member
7 0 0

I am trying to set up the Shopify Buy Button on my Drupal 7 site.  One feature I need is for variant options that are sold out to say so.  This is important, because we have some other functionality around variants being sold out.  

I know that one the user selects that variant, they can see that it is sold out.  But we need the user to see that before they click on it.

What I am looking for is some way to either add a "sold out" class to the sold our variant buttons, or some other way to communicate that the variant is sold out.

I had tried pulling that data in from the product's JSON, which I was able to do, but then I cannot use that info within the template that is displaying the variant options.

 

I have some ideas in mind for frankensteining this into working via jQuery, but that isn't ideal.  So, I am wondering if there is another, more ideal way of making this work.

 

Here is my current code:

<div id='product-component-1604629781277'></div>
<script type="text/javascript">
/*<![CDATA[*/
(function () {
let url = 'https://store.singtree.com/products/[handle_1].json';
var variants = '';
fetch(url)
.then(res => res.json())
.then((out) => {
  let qty = out["product"]["variants"][0]["inventory_quantity"];
  let name = out["product"]["variants"][0]["title"];
console.log(qty);
console.log(name);
  var scriptURL = 'https://sdks.shopifycdn.com/buy-button/latest/buy-button-storefront.min.js';
  if (window.ShopifyBuy) {
    if (window.ShopifyBuy.UI) {
      ShopifyBuyInit();
    } else {
      loadScript();
    }
  } else {
    loadScript();
  }
  function loadScript() {
    var script = document.createElement('script');
    script.async = true;
    script.src=scriptURL;
    (document.getElementsByTagName('head')[0] || document.getElementsByTagName('body')[0]).appendChild(script);
    script.onload = ShopifyBuyInit;
  }
  function ShopifyBuyInit() {
    var client = ShopifyBuy.buildClient({
      domain: 'singing-tree-gardens-nursery.myshopify.com',
      storefrontAccessToken: '5e60ac0ba199b3bac0b49b0a3065447a',
    });
    ShopifyBuy.UI.onReady(client).then(function (ui) {
      ui.createComponent('product', {
iframe: "false",
        id: [product_id],
        node: document.getElementById('product-component-1604629781277'),
        moneyFormat: '%24%7B%7Bamount%7D%7D',
        options: {
  "product": {
iframe: false,
  DOMEvents: {
        'click .shopify-buy__option-select': function (evt, target) {
          var data = target.dataset;
          var product = ui.components.product[0];
          product.updateVariant(data.option, data.value);
        },
    },
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "calc(25% - 20px)",
          "margin-left": "20px",
          "margin-bottom": "50px"
        }
      },
      "title": {
        "color": "#4a2e1f"
      },
      "button": {
        ":hover": {
          "background-color": "#AD5D72"
        },
        "background-color": "#a44b63",
        ":focus": {
          "background-color": "#AD5D72"
        },
        "border-radius": "0px"
      },
      "price": {
        "color": "#4a2e1f"
      },
      "compareAt": {
        "color": "#4a2e1f"
      },
      "unitPrice": {
        "color": "#4a2e1f"
      }
    },
    "text": {
      "button": "Add Product to Cart"
    },
    "contents": {
      "button": false,
      "buttonWithQuantity": true,
      "quantity": true
    }
  },
  "productSet": {
iframe: false,
    "styles": {
      "products": {
        "@media (min-width: 601px)": {
          "margin-left": "-20px"
        }
      }
    }
  },
  "modalProduct": {
iframe: false,
    "contents": {
      "img": false,
      "imgWithCarousel": true,
      "button": false,
      "buttonWithQuantity": true
    },
    "styles": {
      "product": {
        "@media (min-width: 601px)": {
          "max-width": "100%",
          "margin-left": "0px",
          "margin-bottom": "0px"
        }
      },
      "button": {
        ":hover": {
          "color": "#F2B36F"
        },
        "background-color": "#a44b63",
        ":focus": {
          "color": "#F2B36F"
        },
        "border-radius": "0px"
      }
    },
    "text": {
      "button": "Add to cart"
    }
  },
  "cart": {
    "DOMEvents": {
        'click .shopify-buy__btn': function (event) {
          let cart = this.component,
              items = cart.lineItems.map(x => {
                        let id = atob(x.variant.id);

                        return {
                          id: id.split('/').pop(),
                          quantity: x.quantity
                        }
                      }),
              url = '';

          for (let [i, item] of items.entries()) {
            url += `${i === 0 ? '?' : '&'}updates[${item.id}]=${item.quantity}`;
          }

          window.stop();
          window.open('https://singing-tree-gardens-nursery.myshopify.com/cart/update' + url, '_self');
        }
    },
    "styles": {
      "button": {
        "padding": "17px",
        ":hover": {
          "background-color": "#AD5D72"
        },
        "background-color": "#a44b63",
        ":focus": {
          "background-color": "#AD5D72"
        },
        "border-radius": "0px"
      }
    },
    "text": {
      "total": "Subtotal",
      "button": "Checkout"
    },
  "popup": false
  },
  "toggle": {
    "styles": {
      "toggle": {
        "background-color": "#a44b63",
        ":hover": {
          "background-color": "#AD5D72"
        },
        ":focus": {
          "background-color": "#AD5D72"
        }
      }
    }
  },
  "option" : {
    iframe: false,
    "templates": {
      "option": `<div class={{data.classes.option.option}} data-element="option.option">
              <div class="{{data.classes.option.wrapper}}" data-element="option.wrapper">
              <div>
              {{#data.values}}
              <button {{#data.styleAttr}} {{name}} {{/data.styleAttr}} data-value="{{name}}" data-option={{data.name}} class="{{#disabled}}{{data.classes.option.optionDisabled}}{{/disabled}} {{#selected}}{{data.classes.option.optionSelected}}{{/selected}} {{data.classes.option.option}}  " >{{name}} {{id}}</button>
              {{/data.values}}
            </div>
             </div>
         </div>`,
    },
  },
},
      });
    });
  }
})
.catch(err => { throw err });
})();
/*]]>*/
</script>

 

0 Likes
evenvisionstaff
New Member
7 0 0

Hi Michael, 

I'm not sure that quite addresses my issue.  From what I can tell, that will hide the button if the user selects a sold out variant.  I want it to be displayed as sold out before they select the variant, so that they cannot select it and are visually shown that it is sold out.

0 Likes
michaeltheodore
Explorer
59 6 8

There are several places in the code above where you can access the quantity.

If quantity is zero then show a disabled button with 'SOLD OUT' on it.

0 Likes
evenvisionstaff
New Member
7 0 0

Okay, that makes sense, thanks.  How can I access the quantity data?

0 Likes
michaeltheodore
Explorer
59 6 8

In the above code you have the lines

.then((out) => {

let qty = out["product"]["variants"][0]["inventory_quantity"];
let name = out["product"]["variants"][0]["title"];
console.log(qty);
console.log(name);

Then, if qty === 0 do your thing.

0 Likes
evenvisionstaff
New Member
7 0 0

Hi,

I am still having trouble with this.  The problem I am having with your suggestion is that qty is not available in the template that I need to use it.

I have tried using JSON to pull in the qty data in a .js file, and then jQuery to add a class if a button has 0 quantity.  But, the buttons do not seem to get added to the DOM until late, so I am struggling to find a way to run the JS after the buttons have been added.

 

Do you have any other ideas?

0 Likes