<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 | |
var Shopify = Shopify || {}; | |
Shopify.optionsMap = {}; | |
Shopify.updateOptionsInSelector = function(selectorIndex) { | |
switch (selectorIndex) { | |
case 0: | |
var key = 'root'; | |
var selector = jQuery('.single-option-selector:eq(0)'); | |
break; | |
case 1: | |
var key = jQuery('.single-option-selector:eq(0)').val(); | |
var selector = jQuery('.single-option-selector:eq(1)'); | |
break; | |
case 2: | |
var key = jQuery('.single-option-selector:eq(0)').val(); | |
key += ' / ' + jQuery('.single-option-selector:eq(1)').val(); | |
var selector = jQuery('.single-option-selector:eq(2)'); | |
} | |
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. | |
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. | |
jQuery(".single-option-selector:eq(0)").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(".single-option-selector:eq(1)").change(function() { | |
if (product.options.length === 3) Shopify.updateOptionsInSelector(2); | |
return true; | |
}); | |
}; | |
{% 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 %} | |
</script> | |
This comment has been minimized.
This comment has been minimized.
There's an issue in some themes that the elements won't have loaded in by the time this code runs (even when it's added at the very bottom of theme.liquid). In that case adding a |
This comment has been minimized.
This comment has been minimized.
To have the options greyed out & disabled, just remove this piece of code:
|
This comment has been minimized.
This comment has been minimized.
I love this code and it worked for a couple of months. Now all of a sudden the options are not updating to only show what is available after the initial load of the page. When selecting a variant after the first option it says UNAVAILABLE rather than the normal ADD TO CART. Any suggestions? Thanks so much in advance, Aaron |
This comment has been minimized.
This comment has been minimized.
Shopify.uniq is no longer available so this is no longer working. |
This comment has been minimized.
This comment has been minimized.
Is there a an update to use in place of Shopify.uniq? |
This comment has been minimized.
This comment has been minimized.
I've found this video- it uses this snippets and it works: https://youtu.be/dNjMDv5kWig |
This comment has been minimized.
This comment has been minimized.
Thanks MichalHoss - the youtube does have slightly different method, and works. |
This comment has been minimized.
This comment has been minimized.
Seems to be working for me. Thanks! Should I be worried it will stop working? |
This comment has been minimized.
This comment has been minimized.
Hi, |
This comment has been minimized.
This comment has been minimized.
There is a conflict when there is ONLY ONE variant option used on product page. Changes to this piece of code, undesired has been commented out:
|
This comment has been minimized.
This comment has been minimized.
Any ideas on how to implement this in the new sectioned themes? I'm at a loss. |
This comment has been minimized.
This comment has been minimized.
I'm having the same issue than xhorntail with the sectioned theme Jumpstart. When I try this tutorial: https://help.shopify.com/themes/customization/navigation/link-product-options-in-menus , it works perfectly on my product page but not on the section featured product of my home page. Did someone has the same issue and found a solution ? |
This comment has been minimized.
This comment has been minimized.
I'm the creator of the premium District theme, and this question comes up extremely often in support. Now that all the themes have updated to sections, this great guide stopped working. I spent some time this afternoon modifying the snippet to work with some of the changes sectioned themes saw.
I have verified that it works with our District theme, and while it should work in theory with other sectioned themes it has not been tested. https://gist.github.com/jonathanmoore/c0e0e503aa732bf1c05b7a7be4230c61 |
This comment has been minimized.
This comment has been minimized.
I read in one of the comments that in order to have the options greyed out & disabled, to remove a piece of code: The problem is that if I remove this piece of code, then the linked-options do not work anymore. Therefore the question is: For example: So in this context, I would like for color Black not be visible for size M, and color white to visible but grayed out for size M What are the changes to be made to the above posted code to make this work? Many thanks. |
This comment has been minimized.
This comment has been minimized.
@simina89 - uncomment that line and instead remove
you can also go ahead and remove
both |
This comment has been minimized.
This comment has been minimized.
How To add please select option with this code. I have added this code and now by default variants are selected. I want please select option in the drop down and main image will show rather than showing first variant with image as default. Thanks |
This comment has been minimized.
This comment has been minimized.
I have the OOTSB Turbo theme. The code works in the editor but when viewing on the Live page the product page needs to be refreshed each time for the code to work. Any ideas how I can fix this? |
This comment has been minimized.
This comment has been minimized.
I have the same problem as you KevinHitchins - page needs to be refreshed to get this to work. Have you had any luck since? |
This comment has been minimized.
This comment has been minimized.
KevinHitchins and babyoriginals, I'm also wanting to use the OOTSB Turbo theme and have not been able to replace my existing theme for the same reason. Reached out to both Shopify support and OOTSB support, but neither were able to resolve the issue or commit to a future fix/update. Unfortunately my store absolutely requires this functionality so am completely out of luck until it is resolved. Shopify "Experts" have also been reluctant to try to fix this. Did either one of you manage to get this working yet? If so, please post an update to these comments, and I will do the same. Thank you. |
This comment has been minimized.
This comment has been minimized.
Is it possible to get an update for Slate? |
This comment has been minimized.
This comment has been minimized.
use "jQuery.unique" in the place of "Shopify.uniq" |
This comment has been minimized.
This comment has been minimized.
This code works great on the product detail page, however it does not get applied within the Quick Shop modal window. I've got |
This comment has been minimized.
This comment has been minimized.
|
This comment has been minimized.
This comment has been minimized.
I'm having the same problem as several others, the page needs to be manually refreshed each time to get this to work. Still wanting to use the OOTSB Turbo Theme. Very frustrating. Please let me know if you figured this out. Cheers! |
This comment has been minimized.
This comment has been minimized.
I get a page jump to the top after completion of selections I am trying to stop. I think it relates to this piece of code. Anyone have any thoughts on what in the code snippet can be causing that? How to stop it? Thanks!! |
This comment has been minimized.
This comment has been minimized.
i'm using Debut Theme and after implement this, nothing is happen. Anyone can help me? |
This comment has been minimized.
This comment has been minimized.
This code works great for us using the Fasionopolism theme but - how do we only hide unavailable variants (such as a color/size that doesn't exist) and leave sold out variants to still show up but say 'sold out'? |
This comment has been minimized.
This comment has been minimized.
Hey Please help me. Everything tried but not working for me. jQuery(function($) {
|
This comment has been minimized.
This comment has been minimized.
Fix 1
Fix 2@codinginfotech says use "jQuery.unique" in the place of "Shopify.uniq" |
This comment has been minimized.
This comment has been minimized.
I have tried this on symmetry theme but its not working can anyone help please? |
This comment has been minimized.
This comment has been minimized.
@eddyparkinson I implemented both these fixes as well as removing defer="defer" from the vendor.js load and still nothing doing. Preview link below, any help would be much appreciated. https://8hk4yjvzez82ip57-1011974210.shopifypreview.com - Navigate to the Hats product in the catalog for the best example.
|
This comment has been minimized.
This comment has been minimized.
I'm getting Cannot read property 'length' of undefined on the loop that goes on |
This comment has been minimized.
This comment has been minimized.
Hello, I get this error "availableOptions is undefined". Do you have any suggestions for that? |
This comment has been minimized.
This comment has been minimized.
In my case, the issue was in the selector calls (lines 14, 18, 22, 23, 82 and 88). It originally was: jQuery(".single-option-selector:eq But when I looked at my code, the actual selector was missing the "single-" part, so the updated code ended up being: jQuery(".option-selector:eq &TLDR; In the linked-options.liquid file, find and replace all instances of ".single-option-selector" with ".option-selector" |
This comment has been minimized.
This comment has been minimized.
I have also applied the same script but its not working. I am using 'FLEX' theme by Out of Sandbox. Actually, I have three option as below:
linked-option script only hide the color option variants its not hiding the size and contrast color variants. Code:`<script> // Modified by Jonathan Moore (Style Hatch) https://github.com/jonathanmoore // Required functionality from depricated options_selection.js
}; {% if product.available and product.options.size > 1 %}
{% endif %} var selector = jQuery('.single-option-selector__radio:eq(0)');
|
This comment has been minimized.
This comment has been minimized.
@muneeb434 Hello dude, your code is working for Brooklyn theme, thanks. But what if i want use "button" type, not "drop-down"? May be you know what to change in this code? |
This comment has been minimized.
This comment has been minimized.
Excellent one.. trying hard for whole day.. and i found it at last |
This comment has been minimized.
This comment has been minimized.
Was anyone able to implement this feature to the quickview cart option? |
This comment has been minimized.
This comment has been minimized.
The code if you want to disable variants instead of hiding them. It also appends 'Sold Out'. Should look like this https://tppr.me/jjhlY <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 var Shopify = Shopify || {}; Shopify.optionsMap = {}; Shopify.updateOptionsInSelector = function(selectorIndex) { switch (selectorIndex) { case 0: var key = 'root'; var selector = jQuery('.single-option-selector:eq(0)'); break; case 1: var key = jQuery('.single-option-selector:eq(0)').val(); var selector = jQuery('.single-option-selector:eq(1)'); break; case 2: var key = jQuery('.single-option-selector:eq(0)').val(); key += ' / ' + jQuery('.single-option-selector:eq(1)').val(); var selector = jQuery('.single-option-selector:eq(2)'); } var initialValue = selector.val(); var availableOptions = Shopify.optionsMap[key]; selector.find('option').each(function () { var $this = jQuery(this); var _value = $this.val(); var html = $this.html(); if (jQuery.inArray(_value, availableOptions) !== -1) { $this.removeAttr('disabled', 'disabled').html(_value); } else { $this.removeAttr('checked').attr('disabled', 'disabled').html( _value + " - Sold Out" ); selector.find('option:not(:disabled)').first().click(); } }); if (selector.find(':checked').length < 1) { selector.find('option:not(:disabled)').first().click(); } 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. for (var i=0; i 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. jQuery(".single-option-selector:eq(0)").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(".single-option-selector:eq(1)").change(function() { if (product.options.length === 3) Shopify.updateOptionsInSelector(2); return true; }); }; {% 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 %} </script> |
This comment has been minimized.
This comment has been minimized.
Is it possible to have this work for select elements instead of radio buttons? |
This comment has been minimized.
This comment has been minimized.
It works for select elements. |
This comment has been minimized.
This comment has been minimized.
@willimagrivera has a good idea but I had to make some corrections to get that code to work. Here's what works for me: First, make sure when you call the product form you add product JSON, here's how I placed that in the {%- assign product_data_json = product | json -%}
{% form 'product', product, novalidate: 'novalidate', data-product-json: product_data_json %} Then in my var Shopify = Shopify || {};
Shopify.optionsMap = {};
Shopify.arrayIncludes = function (t, e) {
for (var o = 0; o < t.length; o++) {
if (t[o] == e) return !0;
}
return !1;
};
Shopify.uniq = function (t) {
for (var e = [], o = 0; o < t.length; o++) {
Shopify.arrayIncludes(e, t[o]) || e.push(t[o]);
}
return e;
};
Shopify.updateOptionsInSelector = function(selectorIndex) {
switch (selectorIndex) {
case 0:
var key = 'root';
var selector = jQuery('.single-option-selector:eq(0)');
break;
case 1:
var key = jQuery('.single-option-selector:eq(0)').val();
var selector = jQuery('.single-option-selector:eq(1)');
break;
case 2:
var key = jQuery('.single-option-selector:eq(0)').val();
key += ' / ' + jQuery('.single-option-selector:eq(1)').val();
var selector = jQuery('.single-option-selector:eq(2)');
}
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);
// }
selector.find('option').each(function () {
var $this = jQuery(this);
var _value = $this.val();
if (jQuery.inArray(_value, availableOptions) !== -1) {
$this.removeAttr('disabled', 'disabled').html(_value);
} else {
$this.removeAttr('checked').attr('disabled', 'disabled');
selector.find('option:not(:disabled)').first().click();
}
});
if (selector.find(':checked').length < 1) {
selector.find('option:not(:disabled)').first().click();
}
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.
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.
jQuery('.single-option-selector:eq(0)').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('.single-option-selector:eq(1)').change(function() {
if (product.options.length === 3) Shopify.updateOptionsInSelector(2);
return true;
});
};
var $addToCartForm = $('form[action="/cart/add"]');
var product = $addToCartForm.length > 0 ? JSON.parse($addToCartForm.attr('data-product-json')) : false;
if (product && product.available && product.options.length > 1) {
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);
observer.disconnect();
});
observer.observe($addToCartForm[0], config);
}
Shopify.linkOptionSelectors(product);
} |
This comment has been minimized.
This comment has been minimized.
I've tried trouble shooting using the comments on here to either grey out or even just show out of stock options while also having the linked options work, but I haven't had any luck. I can get one to work or the other, but never at the same time. I am working with the Out of the Sandbox theme Mobilia. Has anyone been able to make it work with that theme? |
This comment has been minimized.
This comment has been minimized.
I changed also the way to select form from :
to
Because when you are on a locale (/en), it does not match, and it should ! |
This comment has been minimized.
This comment has been minimized.
Which site sir
…On Fri, Dec 4, 2020, 8:56 PM Fieloux ***@***.***> wrote:
***@***.**** commented on this gist.
------------------------------
I changed also the way to select form from :
$('form[action="/cart/add"]')
to
$('form[action*="/cart/add"]')
Because when you are on a locale (/en), it does not match, and it should !
—
You are receiving this because you commented.
Reply to this email directly, view it on GitHub
<https://gist.github.com/1083007#gistcomment-3550344>, or unsubscribe
<https://github.com/notifications/unsubscribe-auth/AEMJXZ6HYAD4XRE5XF5LU6TSTD5STANCNFSM4H53ISUA>
.
|
This comment has been minimized.
Is it possible to have the options greyed out and disabled instead of hidden?