1
votes

Using the Debut theme in Shopify, I have a product with variants that are not compatible. At present they show as unavailable but I want to hide them totally so that only valid options show with each other. So as example if I have Red, Blue, Green shoes and have sizes 9,10,11. But can only get Red shoes in Size 10. I don't want to see options for 9 or 11 ever.

Online someone pointed to theme.js and the code below, but I'm not sure what to change.

Thanks

$(this.singleOptionSelector, this.$container).on(
  'change',
  this._onSelectChange.bind(this)
);

}

1
I think this is a liquid code more than a js problem, you might want to change liquid code in product-template. But change like that will be quite complicate since if Blue had size 9, 11 I believe you will still see option 9, 11 with Redsomeoneuseless

1 Answers

0
votes

I've just spend most of the day on this, and have come up with the following, which seems to work nicely on the site I'm developing.

The answer I came up with involves editing the assets/theme.js file. At present, the code below disables the select options which are not relevant by checking them against the available variant combinations, but you could easily adapt the below to hide them and then show them instead with CSS.

assets/theme.js

  1. The _hideUnavailableOptions method below needs to be added to the Variants.prototype object.
  2. You then need to call the method from two different places, see below.

    _hideUnavailableOptions: function() {
      const option1 = document.getElementById("SingleOptionSelector-0");
      const option2 = document.getElementById("SingleOptionSelector-1");
    if (option2) {
      const secondOptions = option2.options;      
      const variants = this.product.variants;
      let possibles = [];
      variants.forEach((variant) => {
        if (variant.options.includes(option1.value)) {
        possibles.push(variant.options)
      }
     })
     for (let option of secondOptions) {
        const value = option.value;
        let flag = false;
        possibles.forEach((possible) => {
         if (possible.includes(value)) {
         flag = true;
        }
      })
      if (flag === false) {
        option.removeAttribute('selected');
        option.setAttribute('disabled', 'disabled');
      } else {
       option.removeAttribute('disabled');
      }
     } option2.querySelector(':not([disabled="disabled"])').setAttribute('selected', 'selected');
     }
    },
    

Call the method as follows:

function Variants(options) {

  //stuff before this, then...

  this.enableHistoryState = options.enableHistoryState;
  this._hideUnavailableOptions();  //N.B. this MUST be before the next line
  this.currentVariant = this._getVariantFromOptions(); 
}

...and again, call the method from Variants.prototype._onSelectChange() - make sure it's the first line in there...

_onSelectChange: function() {
    let hideUnavailable = this._hideUnavailableOptions(); //N.B. this MUST be before the next line
    var variant = this._getVariantFromOptions();

    //lots more stuff follows...
}