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
- The _hideUnavailableOptions method below needs to be added to the Variants.prototype object.
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...
}