Skip to content

Instantly share code, notes, and snippets.

@isaacmejia
Created December 7, 2020 17:59
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save isaacmejia/dc932e46bf48fbc9ce7bd0a1b9f22c8e to your computer and use it in GitHub Desktop.
Save isaacmejia/dc932e46bf48fbc9ce7bd0a1b9f22c8e to your computer and use it in GitHub Desktop.
Sectioned Themes Linked Options
<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
*/
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 = document.querySelectorAll('.single-option-selector')[0];
break;
case 1:
var key = document.querySelectorAll('.single-option-selector')[0].value;
var selector = document.querySelectorAll('.single-option-selector')[1];
break;
case 2:
var key = document.querySelectorAll('.single-option-selector')[0].value;
key += ' / ' + document.querySelectorAll('.single-option-selector')[1].value;
var selector = document.querySelectorAll('.single-option-selector')[2];
}
var initialValue = selector.value;
selector.innerHTML = '';
var availableOptions = Shopify.optionsMap[key];
for (var i=0; i<availableOptions.length; i++) {
var option = availableOptions[i];
var newOption = document.createElement('option');
newOption.setAttribute('value', option);
newOption.innerHTML = option;
selector.appendChild(newOption);
}
if (Shopify.arrayIncludes(availableOptions, initialValue)) {
selector.value = initialValue;
}
selector.dispatchEvent(new Event('change'));
};
Shopify.linkOptionSelectors = function(product) {
// Building our mapping object.
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]);
}
}
}
// 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.
document.querySelectorAll('.single-option-selector')[0].addEventListener('change', function (event) {
Shopify.updateOptionsInSelector(1);
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
});
// When there is an update in the second dropdown.
document.querySelectorAll('.single-option-selector')[1].addEventListener('change', function (event) {
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
});
};
{% if product.available and product.options.size > 1 %}
var $addToCartForm = document.querySelector('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, config);
}
{% endif %}
var selector = document.querySelectorAll('.single-option-selector')[0];
selector.dispatchEvent(new Event('change'));
{% if product.options.size == 1 %}
{% for variant in product.variants %}
{% unless variant.available %}
Array.from(document.querySelectorAll('.single-option-selector')).filter(function(el) { return el.value.trim() === {{ variant.title | json }}; }).map(function (el) { el.parentNode.removeChild(el); });
{% endunless %}
{% endfor %}
document.querySelectorAll('.single-option-selector').map(function(selector) { selector.dispatchEvent(new Event('change')); });
{% endif %}
});
</script>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment