d
Topic
jony Member
Posts:
4
8 months ago
g
2
upvotes

Debut Theme – Product Swatches

Hi there,

Does anyone know how to use this Product Swatch tutorial with the Debut theme?
https://help.shopify.com/themes/customization/showcase-products/add-color-swatches

I can't find the selectCallback function anywhere.

Thanks

i
Replies
Posts:
4
6 months ago

Having the same issue. Is the color swatch customization maybe not possible on this theme?

The Web Elite | Shopify Experts
Posts:
6
4 months ago

Hi,

Did you actually find where the selectCallback function is? I am also looking for it and not able to find it. Thanks

Posts:
4
4 months ago

Hi Daniela,

No, it appears that with the update to Sectioned themes, Shopify has changed the way the selectCallback function works and it no longer goes by that name.

All the js now lives in a seperate file, usually called theme.js or something similar.

We have asked other theme developers about this and apparently, while swatches are still possible, the documentation from Shopify needs to be updated to reflect a new (apparently easier) method for setting these up in Sectioned themes.

So, basically we have been told to keep our eye on that customization and watch for an update.

So, if anyone on this thread notices an update there I think we would all appreciate a comment dropped here as a heads up.

Thanks everyone!

The Web Elite | Shopify Experts
Posts:
6
Last edited 4 months ago
g
1
upvotes

Hey,

Thanks for the info. I checked the theme.js and managed to modify it so i see the color swatch! :) I dont think it's the nicest way to modify that js file but it will do till they publish the nice way :P So in theme.js at line 2482 you will find the variable variant declared and after i added the swatched code. Of course there are still some style changes that you should add by yourself as in the doc is css and now they are using scss, which i didnt do yet. But it seems to be working, adding it in the cart and everything.. Oh and you also have to add jquery to the theme so the other color select will dissappear. 

Posts:
4
4 months ago

Hi Daniela,

That is fantastic news, well done for playing around and finding a solution! We are so excited to hear that this could be the answer we have all been waiting for.

May I ask you to please clarify just this point: "Oh and you also have to add jquery to the theme so the other color select will dissappear. " What JQuery did you add and where?

And just to also confirm, are you using the Debut theme for this?

The Web Elite | Shopify Experts
Posts:
6
4 months ago

Yes, i use Debut :) JQuery, a js framework responsible for some magic :D In theme.liquid after this line '<!--[if lte IE 9]><script src="{{ 'vendor.js' | asset_url }}"></script><![endif]--> add this:


  <script
  src="https://code.jquery.com/jquery-2.2.4.min.js"
  integrity="sha256-BbhdlvQf/xTY9gja0Dq3HiwQF8LaCRTXxZKRutelT44="
  crossorigin="anonymous"></script>

tim Member trezoro.co
Posts:
1666
4 months ago
g
1
upvotes

It actually is not the best idea -- most probably you will end up with extra copy of jQuery loaded.

For many Sectioned themes jQuery is included as a part of vendor.js.  Your inlined scripts do not see it because it is not available until the page is fully loaded, because vendor.js is included with defer="defer" attribute (probably a Shopify's attempt to reduce the number of render-blocking scripts). 

So you have two options: a) remove the defer attribute and allow vendor.js to load as soon as it is included (which I recommend to all non-programmer type shopify users, since it is easy) or b) modify the code and include it in the theme.js (what I do myself).

Or, you should remove jQuery from the vendor.js file if you include it separately.

 

Want to hire me to tweak a theme? Mail me at tairli@yahoo.com! My post solved your problem? This is my Paypal too :)
Amber Hazel Member
Posts:
8
Last edited 4 months ago

I can't make this to work. Both drop-down and radio options are displayed on my product page. What am I doing wrong?

I added this below second </select> in product-template.liquid

{% if product.available and product.variants.size > 1 %}
  {% for option in product.options %}
    {% include 'swatch' with option %}
  {% endfor %}
{% endif %}  

I don't think my theme.js is same as your Daniela. This is my code arround line 2482.

          // The variant doesn't exist, disable submit button and change the text.
          // This may be an error or notice that a specific variant is not available.
          $(this.selectors.addToCart).prop('disabled', true);
          $(this.selectors.addToCartText).text(theme.strings.soldOut);
        }
      } else {
        $(this.selectors.addToCart).prop('disabled', true);
        $(this.selectors.addToCartText).text(theme.strings.unavailable);
        $(this.selectors.productPrices)
          .addClass('visibility-hidden')
          .attr('aria-hidden', 'false');
      }
    },

I'm not sure where to add code related to callback?

Scr thumb
Posts:
4
3 months ago

Would love an answer to this as well. Since selectCallback is gone, what needs to be changed in the code and where in theme.js does it go?

Posts:
6
3 months ago

You have the Color 2 times because of the jquery issue i was talking about. Remove the defer="defer" attribute, like Tim specified. It's in the theme.liquid line 62 and 63 for vendor.js. And in theme.js you need to add, at line 2484, so inside if(variant){

for (var i=0,length=variant.options.length; i<length; i++) {
          $('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');
        }

 

DreKay Member
Posts:
10
3 months ago

I'm having this same exact issue as the others in this thread. Everything appears fine on the product page, and the variants are listed correctly, but the variant selected by the swatches does not reflect what is added to cart (so it always just adds the default color and size in my case). I'm using Debut as the theme.

Please see the attached screenshot for where I added the code from the tutorial (that is otherwise supposed to go into selectCallback). I'm putting it exactly where Daniela suggests, although my line numbers are slightly different from other small modifications. Would it be possible for anyone with a working solution to upload the full relevant portion of their theme.js?

I see no errors in my JS console, any errors that I've seen I've squashed already. I'm not sure where to proceed from here.

 

Screen shot 2017 04 25 at 5.35.42 pm thumb
DreKay Member
Posts:
10
3 months ago

Nevermind! Got it to work. I had originally commented out the dropdowns for the original size and color variants as they weren't disappearing fast enough - but seemingly this gave me my issue.

Make sure in theme.js your code looks exactly like this. Do a control-f for if (variant) { and add these lines immediately underneath:

for (var i=0,length=variant.options.length; i<length; i++) {
          $('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');

}

That's what I've done and it works great here! 

Cameron Member
Posts:
1
Last edited 3 months ago

Hello, I've been having issues with implementing this on Debut.  I added the code in theme.js to where it said in this topic.  I ran into the first problem that "selector" is not defined.  Specifically in this code line:

 var form = jQuery('#' + selector.domIdPrefix).closest('form');

I changed "selector" to "this.selectors" since I saw that was what the rest of the theme was using, and it worked!  However, the swatches don't seem to work with direct linking of variants.  For example, if I had a product with two colors, black and blue, and I visited the blue url, it would show the black swatch as selected.  I suspect that it has something to do with putting "this.selectors" but I'm not sure.  Has anyone had the same issue?

EDIT: Wait, I just realized that the code the tutorial says to copy and the code it has in the images are different, and the reason selector was undefined was because it was defined with selectCallback, which no longer exists.  Does anyone have any updated instructions on how to implement this properly?

Posts:
7
2 months ago

HI Everyone :).

First off thank you all who have contributed to this solution I've been able to follow it through and implement it on my site really easily, even for a coding newbie like me!

I only have one issue, when I pick a swatch and click 'add to cart' it doesn't change the product that's added. It just adds the default color option. 

I think it has something to do with this bit of code from theme.js:

    var variant = evt.variant;
	// BEGIN SWATCHES
	if (variant) {
      for (var i=0,length=variant.options.length; i<length; i++) {
          $('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');

  		var form = jQuery('#' + selector.domIdPrefix).closest('form');
   		var radioButton = form.find('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');
    if (radioButton.size()) {
      radioButton.get(0).checked = true;
   		 }
  		}
	}
	// END SWATCHES

 

Can anyone help me fix it?

 

Thank you!

dbdb Member
Posts:
7
about 2 months ago

Has anyone figured this out yet? I have all the same problems as above. The buttons exist, they add product to the cart but all default to the same primary product. I cannot get them to add the correct product to the cart. Additionally, I also only get grey/gray colored buttons. How to fix the colors (currently less important than the cart issues)?

 

Thank you,

 

David

dbdb Member
Posts:
7
about 2 months ago

Did you figure this out Cameron?

dbdb Member
Posts:
7
about 2 months ago

Hi Daniella,

I'm struggling with this. Please can you tell us how you implemented it with the code and locations?

Thanks,

David

Posts:
6
about 2 months ago

 

Hey,

So first i modified the product-template.liquid , i added the swatch. I added my own css, didnt take the one from the documentation but you can check it and take what you think it's useful. And dont forget to create swatch.liquid.

Then in theme.js you need to add, at line 2484, so inside if(variant){

for (var i=0,length=variant.options.length; i<length; i++) {
          $('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');
        }

Then in theme.liquid lines 62 and 63 i think, i removed the defer='defer' for the javascript files that are added there, like from vendor.js and there's another one as well. 

Dont forget to add the code at the end of theme.liquid

<script>
jQuery(function() {
  jQuery('.swatch :radio').change(function() {
    var optionIndex = jQuery(this).closest('.swatch').attr('data-option-index');
    var optionValue = jQuery(this).val();
    jQuery(this)
      .closest('form')
      .find('.single-option-selector')
      .eq(optionIndex)
      .val(optionValue)
      .trigger('change');
  });
});
</script>

That's it..hope it works.. 

dbdb Member
Posts:
7
about 2 months ago

Thank you Daniela. I'm afraid I have meticulously followed your instructions and cannot get this to work. The only problems is that the cart does not update properly. The cart only shows the default item, regardless of what is selected. Please can you copy and paste your entire section for updating the cart from theme.js. This is my code at present (thank you for your help!):

 

    _updateAddToCart: function(evt) {
      var variant = evt.variant;
		// BEGIN SWATCHES
        if (variant) {
          for (var i=0,length=variant.options.length; i<length; i++) {
          	$('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');
          }
        }
        // END SWATCHES
      
        $(this.selectors.productPrices)
          .removeClass('visibility-hidden')
          .attr('aria-hidden', 'true');

        if (variant.available) {
          $(this.selectors.addToCart).prop('disabled', false);
          $(this.selectors.addToCartText).text(theme.strings.addToCart);
          
        } else {
          // The variant doesn't exist, disable submit button and change the text.
          // This may be an error or notice that a specific variant is not available.
          $(this.selectors.addToCart).prop('disabled', true);
          $(this.selectors.addToCartText).text(theme.strings.soldOut);
        }
      } else {
        $(this.selectors.addToCart).prop('disabled', true);
        $(this.selectors.addToCartText).text(theme.strings.unavailable);
        $(this.selectors.productPrices)
          .addClass('visibility-hidden')
          .attr('aria-hidden', 'false');
      }
      	

 

Posts:
4
about 2 months ago

dbdb, I believe the above instructions regarding what to do with the defer="defer" attribute will resolve your issue. 

Posts:
6
about 2 months ago

Hey, this is my code for the cart section:

_updateAddToCart: function(evt) {
      var variant = evt.variant;
      

      if (variant) {
        for (var i=0,length=variant.options.length; i<length; i++) {
          $('.swatch[data-option-index="' + i + '"] :radio[value="' + variant.options[i] +'"]');
        }
        
        $(this.selectors.productPrices)
          .removeClass('visibility-hidden')
          .attr('aria-hidden', 'true');            

        if (variant.available) {
          $(this.selectors.addToCart).prop('disabled', false);
          $(this.selectors.addToCartText).text(theme.strings.addToCart);
        } else {
          // The variant doesn't exist, disable submit button and change the text.
          // This may be an error or notice that a specific variant is not available.
          $(this.selectors.addToCart).prop('disabled', true);
          $(this.selectors.addToCartText).text(theme.strings.soldOut);
        }
      } else {
        $(this.selectors.addToCart).prop('disabled', true);
        $(this.selectors.addToCartText).text(theme.strings.unavailable);
        $(this.selectors.productPrices)
          .addClass('visibility-hidden')
          .attr('aria-hidden', 'false');
      }
    },
 

Check if you removed the defer="defer" like Robert also suggested. These are my modified lines in theme.liquid, in the header:

 <!--[if (gt IE 9)|!(IE)]><!--><script src="{{ 'vendor.js' | asset_url }}"></script><!--<![endif]-->
  <!--[if lte IE 9]><script src="{{ 'vendor.js' | asset_url }}"></script><![endif]-->
  
  
  <!--[if (gt IE 9)|!(IE)]><!--><script src="{{ 'theme.js' | asset_url }}"></script><!--<![endif]-->
  <!--[if lte IE 9]><script src="{{ 'theme.js' | asset_url }}"></script><![endif]-->
 

dbdb Member
Posts:
7
about 2 months ago

Still not working for me. Here's my entire theme.liquid code (also, thanks for the suggestion about the defer code Robert, sadly that was already deleted and it's still not working):

 

<!doctype html>
<!--[if IE 9]> <html class="ie9 no-js" lang="{{ shop.locale }}"> <![endif]-->
<!--[if (gt IE 9)|!(IE)]><!--> <html class="no-js" lang="{{ shop.locale }}"> <!--<![endif]-->
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <meta name="viewport" content="width=device-width,initial-scale=1">
  <meta name="theme-color" content="{{ settings.color_button }}">
  <link rel="canonical" href="{{ canonical_url }}">

  {% if settings.favicon != blank %}
    <link rel="shortcut icon" href="{{ settings.favicon | img_url: '32x32' }}" type="image/png">
  {% endif %}

  {% capture seo_title %}
    {{ page_title }}
    {% if current_tags %}
      {%- assign meta_tags = current_tags | join: ', ' %} &ndash; {{ 'general.meta.tags' | t: tags: meta_tags -}}
    {% endif %}
    {% if current_page != 1 %}
      &ndash; {{ 'general.meta.page' | t: page: current_page }}
    {% endif %}
    {% unless page_title contains shop.name %}
      &ndash; {{ shop.name }}
    {% endunless %}
  {% endcapture %}
  <title>{{ seo_title }}</title>

  {% if page_description %}
    <meta name="description" content="{{ page_description | escape }}">
  {% endif %}

  {% include 'social-meta-tags' %}

  {{ 'theme.scss.css' | asset_url | stylesheet_tag }}
  {% include 'google-fonts' %}

  <script>
    var theme = {
      strings: {
        addToCart: {{ 'products.product.add_to_cart' | t | json }},
        soldOut: {{ 'products.product.sold_out' | t | json }},
        unavailable: {{ 'products.product.unavailable' | t | json }},
        showMore: {{ 'general.filters.show_more' | t | json }},
        showLess: {{ 'general.filters.show_less' | t | json }}
      },
      moneyFormat: {{ shop.money_format | json }}
    }

    document.documentElement.className = document.documentElement.className.replace('no-js', 'js');
  </script>

  <!--[if (lte IE 9) ]>{{ 'match-media.min.js' | asset_url | script_tag }}<![endif]-->

  {% if template.directory == 'customers' %}
    <!--[if (gt IE 9)|!(IE)]><!--><script src="{{ 'shopify_common.js' | shopify_asset_url }}" defer="defer"></script><!--<![endif]-->
    <!--[if lte IE 9]><script src="{{ 'shopify_common.js' | shopify_asset_url }}"></script><![endif]-->
  {% endif %}

  <!--[if (gt IE 9)|!(IE)]><!--><script src="{{ 'vendor.js' | asset_url }}"></script><!--<![endif]-->
  <!--[if lte IE 9]><script src="{{ 'vendor.js' | asset_url }}"></script><![endif]-->

  <!--[if (gt IE 9)|!(IE)]><!--><script src="{{ 'theme.js' | asset_url }}"></script><!--<![endif]-->
  <!--[if lte IE 9]><script src="{{ 'theme.js' | asset_url }}"></script><![endif]-->

  {{ content_for_header }}
</head>

<body class="template-{{ template | split: '.' | first }}">

  <a class="in-page-link visually-hidden skip-link" href="#MainContent">{{ 'general.accessibility.skip_to_content' | t }}</a>

  <div id="SearchDrawer" class="search-bar drawer drawer--top">
    <div class="search-bar__table">
      <div class="search-bar__table-cell search-bar__form-wrapper">
        <form class="search search-bar__form" action="/search" method="get" role="search">
          <button class="search-bar__submit search__submit btn--link" type="submit">
            {% include 'icon-search' %}
            <span class="icon__fallback-text">{{ 'general.search.submit' | t }}</span>
          </button>
          <input class="search__input search-bar__input" type="search" name="q" value="{{ search.terms | escape }}" placeholder="{{ 'general.search.placeholder' | t }}" aria-label="{{ 'general.search.placeholder' | t }}">
        </form>
      </div>
      <div class="search-bar__table-cell text-right">
        <button type="button" class="btn--link search-bar__close js-drawer-close">
          {% include 'icon-close' %}
          <span class="icon__fallback-text">{{ 'general.search.close' | t }}</span>
        </button>
      </div>
    </div>
  </div>

  {% section 'header' %}

  <div class="page-container" id="PageContainer">

    <main class="main-content" id="MainContent" role="main">
      {{ content_for_layout }}
    </main>

    {% section 'footer' %}

  </div>
  
  <script>
  jQuery(function() {
    jQuery('.swatch :radio').change(function() {
      var optionIndex = jQuery(this).closest('.swatch').attr('data-option-index');
      var optionValue = jQuery(this).val();
      jQuery(this)
        .closest('form')
        .find('.single-option-selector')
        .eq(optionIndex)
        .val(optionValue)
        .trigger('change');
    });
  });
  </script>
 
</body>
</html>

Daniela, if I give you my login credentials, could you take a look at all my code and see what's the matter?

Thank you EVERYONE!

Posts:
1
15 days ago

 

Just figured this out, thanks for the help!

If you are using the debut theme for creating a homepage with a featured product and need the swatches to appear there, you need to do this seperately in the featured-product.liquid file (under Sections). Add the same code you used for product-template.liquid like the following,

<select name="id" id="ProductSelect-{{ section.id }}" data-section="{{ section.id }}" class="product-form__variants no-js">
                {% for variant in product.variants %}
                  {% if variant.available %}
                    <option {% if variant == product.selected_or_first_available_variant %} selected="selected" {% endif %} value="{{ variant.id }}">
                      {{ variant.title }}
                    </option>
                  {% else %}
                    <option disabled="disabled">{{ variant.title }} - {{ 'products.product.sold_out' | t }}</option>
                  {% endif %}
                {% endfor %}
              </select>
              {% if product.available and product.variants.size > 1 %}
                {% for option in product.options %}
                  {% include 'swatch' with option %}
                {% endfor %}
              {% endif %}

I also found the formatting looked weird with the "Buy Now" button, so I added a bit of CSS to make that on the next line. I added to the theme.scss.liquid file, 

.swatch { 
  margin:1em 0; 
  margin-left: 8px;
  margin-right: 10vw;
}

I hope that can help someone with a similar problem!