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>

 

Replies 6 (6)
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.

michaeltheodore
Explorer
59 6 9

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.

evenvisionstaff
New Member
7 0 0

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

michaeltheodore
Explorer
59 6 9

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.

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?