Get Stock of Product Variation

I want to show the “Add to Cart” button only, if a product is in stock. Currently I achieve this like so:

[[commerce.get_product:lte=`0`:then=`
   <p>Out of Stock</p>
`:else=`
   <input type="number" name="quantity" min="1" max="[[commerce.get_product? &product=`[[+tv.products]]` &field=`stock`]]" value="1" />
   <input type="submit" name="addcart" value="Add to Cart" />
`? &product=`[[+tv.products]]` &field=`stock`]]

If a product has variations though, I want the stock to be shown for the selected product variation.

I assume I need to link the get_products call from the select option somehow to this, so I can get the stock of the selected product ID, but I don’t know how… Here is my current code:

<select id="choose-variation" name="product">
   [[!commerce.get_products? 
      &products=`[[+tv.products]]`
      &tpl=`product_select`
   ]]
</select>


// product_select
<option value="[[+id]]">[[+name]]</option>

Appreciate any help!

This is typically something you’d accomplish with JavaScript; whenever the <select> value changes, update parts of the page to reflect that (stock, price, etc).

The starter pack (preview) includes that functionality too, tho that one is built for the matrix, not the list TV.

My typical approach includes adding data attributes into the options. For example:

<option value="[[+id]]" 
        data-stock="[[+stock]]" 
        data-price="[[+price_rendered]]">
    [[+name]]
</option>

Then add some JS… untested code:

var select = document.getElementById('choose-variation'),
      addToCartForm = document.getElementById('add-to-cart'),
      outOfStockMessage = document.getElementById('out-of-stock');
select.addEventListener('change', function(e) {
    var opt = select.options[select.selectedIndex],
          stock = Number(opt.getAttribute('data-stock'));
    addToCartForm.style.display = stock > 0 ? 'block' : 'none';
    outOfStockMessage.style.display = stock <= 0 ? 'block' : 'none';
});
1 Like

I’m trying to achieve the same thing - to have an “Out of stock” label and no “add to cart” option if an item’s stock is “0”.
This isn’t working…

 [[!commerce.get_product? &product=`[[*product]]` &toPlaceholders=`product` &field=`[[+stock]]`]] 
 
 [[+product.stock:is=`0`:then=`
 <p>Out of Stock</p>
`:else=`
<form method="post" action="[[~[[++commerce.cart_resource]]]]">
    <input type="hidden" name="add_to_cart" value="1">
    <input type="hidden" name="product" value="[[+product.id]]">
    
    <label for="add-quantity">Quantity:</label>
    <input type="number" name="quantity" value="1">
    
    <input type="submit" value="Add to cart">
</form>
`]]

The “add to cart” option displays whatever I do. I’ve tried various permutations but can’t get it to work exactly as I’d like.
Thanks for any help

You have [[!commerce.get_product but [[+product.stock - use [[!+product.stock instead so they’re both parsed at the same time.

Also don’t combine &toPlaceholders and &field - pick one. In this case, toPlaceholder is more appropriate so remove &field from the snippet call.

1 Like

Thank you:-)