Created
December 22, 2021 19:36
-
-
Save kyleboehlen/fd4ce2f4d24a16b74b1e4a30c914f32d to your computer and use it in GitHub Desktop.
Shopify Hide Unavailable Variants
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<script> | |
// (c) Copyright 2016 Caroline Schnapp. All Rights Reserved. Contact: mllegeorgesand@gmail.com | |
// See https://docs.shopify.com/themes/customization/navigation/link-product-options-in-menus | |
// Modified by Jonathan Moore (Style Hatch) https://github.com/jonathanmoore | |
/* | |
Updated to work with sectioned themes | |
- Added required methods from the deprecated options_selection.js | |
- Triggers an initial variant change | |
- Hides sold out variants with only one option | |
*/ | |
/* Modified by Mark and Kyle Boehlen Dec 2021 https://www.kyleboehlen.com | |
- Added variables, moved call to product.liquid. | |
- Added switch (variable) to show sold out | |
- Added secound for loop to add in sold out variants into the selectors at the end | |
- Added reference to jquery in product.liquid | |
*/ | |
// Set up some variables that identify the selection, in this theme it is located in product-form.liquid line 98 | |
var selectionobject = '.form__input--select' // '.single-option-selector' | |
var select0 = selectionobject + ':eq(0)' | |
var select1 = selectionobject + ':eq(1)' | |
var select2 = selectionobject + ':eq(2)' | |
// Set up a variable as a switch for showing sold out items | |
var showsoldout = true | |
window.addEventListener('DOMContentLoaded', function() { | |
var Shopify = Shopify || {}; | |
// Required functionality from depricated options_selection.js | |
Shopify.arrayIncludes = function(e, t) { | |
for (var n = 0; n < e.length; n++) | |
if (e[n] == t) return !0; | |
return !1 | |
}, Shopify.uniq = function(e) { | |
for (var t = [], n = 0; n < e.length; n++) Shopify.arrayIncludes(t, e[n]) || t.push(e[n]); | |
return t | |
} | |
Shopify.optionsMap = {}; | |
Shopify.updateOptionsInSelector = function(selectorIndex) { | |
switch (selectorIndex) { | |
case 0: | |
var key = 'root'; | |
var selector = jQuery(select0); | |
break; | |
case 1: | |
var key = jQuery(select0).val(); | |
var selector = jQuery(select1); | |
break; | |
case 2: | |
var key = jQuery(select0).val(); | |
key += ' / ' + jQuery(select1).val(); | |
var selector = jQuery(select2); | |
} | |
var initialValue = selector.val(); | |
selector.empty(); | |
var availableOptions = Shopify.optionsMap[key]; | |
for (var i=0; i<availableOptions.length; i++) { | |
var option = availableOptions[i]; | |
var newOption = jQuery('<option></option>').val(option).html(option); | |
selector.append(newOption); | |
} | |
jQuery('.swatch[data-option-index="' + selectorIndex + '"] .swatch-element').each(function() { | |
if (jQuery.inArray($(this).attr('data-value'), availableOptions) !== -1) { | |
$(this).removeClass('soldout').show().find(':radio').removeAttr('disabled','disabled').removeAttr('checked'); | |
} | |
else { | |
$(this).addClass('soldout').hide().find(':radio').removeAttr('checked').attr('disabled','disabled'); | |
} | |
}); | |
if (jQuery.inArray(initialValue, availableOptions) !== -1) { | |
selector.val(initialValue); | |
} | |
selector.trigger('change'); | |
}; | |
Shopify.linkOptionSelectors = function(product) { | |
// Building our mapping object. | |
// Start with available variants | |
for (var i=0; i<product.variants.length; i++) { | |
var variant = product.variants[i]; | |
if (variant.available) { | |
// Gathering values for the 1st drop-down. | |
Shopify.optionsMap['root'] = Shopify.optionsMap['root'] || []; | |
Shopify.optionsMap['root'].push(variant.option1); | |
Shopify.optionsMap['root'] = Shopify.uniq(Shopify.optionsMap['root']); | |
// Gathering values for the 2nd drop-down. | |
if (product.options.length > 1) { | |
var key = variant.option1; | |
Shopify.optionsMap[key] = Shopify.optionsMap[key] || []; | |
Shopify.optionsMap[key].push(variant.option2); | |
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]); | |
} | |
// Gathering values for the 3rd drop-down. | |
if (product.options.length === 3) { | |
var key = variant.option1 + ' / ' + variant.option2; | |
Shopify.optionsMap[key] = Shopify.optionsMap[key] || []; | |
Shopify.optionsMap[key].push(variant.option3); | |
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]); | |
} | |
} | |
} | |
// If we are showing the sold out items - then we will add them in a second loop so that the selectors get instock options first | |
if (showsoldout) { | |
for (var s=0; s<product.variants.length; s++) { | |
var variant = product.variants[s]; | |
if (!variant.available) { | |
// Gathering values for the 1st drop-down. | |
Shopify.optionsMap['root'] = Shopify.optionsMap['root'] || []; | |
Shopify.optionsMap['root'].push(variant.option1); | |
Shopify.optionsMap['root'] = Shopify.uniq(Shopify.optionsMap['root']); | |
// Gathering values for the 2nd drop-down. | |
if (product.options.length > 1) { | |
var key = variant.option1; | |
Shopify.optionsMap[key] = Shopify.optionsMap[key] || []; | |
Shopify.optionsMap[key].push(variant.option2); | |
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]); | |
} | |
// Gathering values for the 3rd drop-down. | |
if (product.options.length === 3) { | |
var key = variant.option1 + ' / ' + variant.option2; | |
Shopify.optionsMap[key] = Shopify.optionsMap[key] || []; | |
Shopify.optionsMap[key].push(variant.option3); | |
Shopify.optionsMap[key] = Shopify.uniq(Shopify.optionsMap[key]); | |
} | |
} | |
} | |
} // End if soldout | |
// Update options right away. | |
Shopify.updateOptionsInSelector(0); | |
if (product.options.length > 1) Shopify.updateOptionsInSelector(1); | |
if (product.options.length === 3) Shopify.updateOptionsInSelector(2); | |
// When there is an update in the first dropdown. | |
jQuery(select0).change(function() { | |
Shopify.updateOptionsInSelector(1); | |
if (product.options.length === 3) Shopify.updateOptionsInSelector(2); | |
return true; | |
}); | |
// When there is an update in the second dropdown. | |
jQuery(select1).change(function() { | |
if (product.options.length === 3) Shopify.updateOptionsInSelector(2); | |
return true; | |
}); | |
}; | |
// added - making the script fire on page load | |
Shopify.linkOptionSelectors({{ product | json}}); | |
{% if product.available and product.options.size > 1 %} | |
var $addToCartForm = $('form[action="/cart/add"]'); | |
if (window.MutationObserver && $addToCartForm.length) { | |
if (typeof observer === 'object' && typeof observer.disconnect === 'function') { | |
observer.disconnect(); | |
} | |
var config = { childList: true, subtree: true }; | |
var observer = new MutationObserver(function() { | |
Shopify.linkOptionSelectors({{ product | json }}); | |
observer.disconnect(); | |
}); | |
observer.observe($addToCartForm[0], config); | |
} | |
{% endif %} | |
var selector = jQuery(select0); | |
selector.trigger('change'); | |
{% if product.options.size == 1 %} | |
{% for variant in product.variants %} | |
{% unless variant.available %} | |
jQuery(select0).filter(function() { return jQuery(this).text().trim() === {{ variant.title | json }}; }).remove(); | |
{% endunless %} | |
{% endfor %} | |
jQuery(select0).trigger('change'); | |
{% endif %} | |
}); | |
</script> |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Any way for this work on 'Ride' 2.0 theme? This theme doesn't have a product.liquid section which is the only reason as to why this isn't working.