Change product image in collection page to the correct variable swatch selection

Highlighted
New Member
4 0 0

We successfully added variable swatches to our collection page. This allows users to select the variation which auto changes the price for that product in the collection page and allows them to add that variant to their cart. Its working great!

The next step is to get the product images for the selected variable to dynamically load and replace the featured image for that specific product to match the variable image.

We have 2 kinds of "options" Color & Size for each product.

We made this script that is working and pulls in the correct product image depending on the color selected

$('.swatch label i').closest('label').each(function () {
    $(this).click(function () {
        let varImgUrl = $(this).data('img');
        let featuredImgUrl = $(this).data('featuredimg');

        if (!varImgUrl.includes('/shopify/assets/no-image-2048-')) {
            $(this).closest('.product-thumb').find('.product-thumb-inner img').removeAttr('srcset').attr('src', varImgUrl);
        } else if (featuredImgUrl.length > 0 && !featuredImgUrl.includes('/shopify/assets/no-image-2048-')) {
            $(this).closest('.product-thumb').find('.product-thumb-inner img').removeAttr('srcset').attr('src', featuredImgUrl);
        } else {
            $(this).closest('.product-thumb').find('.product-thumb-inner img').removeAttr('srcset').attr('src', '//cdn.shopify.com/s/files/1/0278/6656/2627/t/6/assets/no-image.gif?v=2525960480124172442');
        }
    });
});

However this method is only working for us when we select the color swatches. When we select the size swatches we can not get it to change to the correct image.

Anyone have a solid solution for this? We are using the "Galleria" theme which had built in swatches on product page which we are re-useing on collection page.

Here is the image code from the collection loop

<div class="product-thumb-inner">
      <div class="product-thumb-img-wrap {{bs_class}}">
 
        {% if product.images.size == 0 %}
            <!-- If the product has no image, display custom placeholder -->
            <img src="{{ 'no-image.gif' | asset_url }}">
        {% else %}

        <noscript>
            <img class="product-thumb-img z_index_1" alt="{{product.title | escape }}" srcset="{{ product.featured_media.preview_image.src | img_url: img_url_width }} 1x, {{ product.featured_media.preview_image.src | img_url: img_url_width, scale: 2 }} 2x, {{ product.featured_media.preview_image.src | img_url: img_url_width, scale: 3 }} 3x"/>
        </noscript>

                {%- include 'product-image',
                    img: product.featured_media.preview_image,
                    class_name: 'product-thumb-img',
                    spinner: true
                -%}
        {% endif %}
        </div>
      </div>

Here is the swatch code (although you may not need it)

Thanks for any insight into improving our JS!

{% assign CSS_COLOR_NAMES = '"AliceBlue","AntiqueWhite","Aqua","Aquamarine","Azure","Beige","Bisque","Black","BlanchedAlmond","Blue","BlueViolet","Brown","BurlyWood","CadetBlue","Chartreuse","Chocolate","Coral","CornflowerBlue","Cornsilk","Crimson","Cyan","DarkBlue","DarkCyan","DarkGoldenRod","DarkGray","DarkGrey","DarkGreen","DarkKhaki","DarkMagenta","DarkOliveGreen","Darkorange","DarkOrchid","DarkRed","DarkSalmon","DarkSeaGreen","DarkSlateBlue","DarkSlateGray","DarkSlateGrey","DarkTurquoise","DarkViolet","DeepPink","DeepSkyBlue","DimGray","DimGrey","DodgerBlue","FireBrick","FloralWhite","ForestGreen","Fuchsia","Gainsboro","GhostWhite","Gold","GoldenRod","Gray","Grey","Green","GreenYellow","HoneyDew","HotPink","IndianRed","Indigo","Ivory","Khaki","Lavender","LavenderBlush","LawnGreen","LemonChiffon","LightBlue","LightCoral","LightCyan","LightGoldenRodYellow","LightGray","LightGrey","LightGreen","LightPink","LightSalmon","LightSeaGreen","LightSkyBlue","LightSlateGray","LightSlateGrey","LightSteelBlue","LightYellow","Lime","LimeGreen","Linen","Magenta","Maroon","MediumAquaMarine","MediumBlue","MediumOrchid","MediumPurple","MediumSeaGreen","MediumSlateBlue","MediumSpringGreen","MediumTurquoise","MediumVioletRed","MidnightBlue","MintCream","MistyRose","Moccasin","NavajoWhite","Navy","OldLace","Olive","OliveDrab","Orange","OrangeRed","Orchid","PaleGoldenRod","PaleGreen","PaleTurquoise","PaleVioletRed","PapayaWhip","PeachPuff","Peru","Pink","Plum","PowderBlue","Purple","Red","RosyBrown","RoyalBlue","SaddleBrown","Salmon","SandyBrown","SeaGreen","SeaShell","Sienna","Silver","SkyBlue","SlateBlue","SlateGray","SlateGrey","Snow","SpringGreen","SteelBlue","Tan","Teal","Thistle","Tomato","Turquoise","Violet","Wheat","White","WhiteSmoke","Yellow","YellowGreen"' | downcase | remove:'"'| split:',' %}

{% comment %}
    Set the extension of your color files below. Use 'png', 'jpeg', 'jpg' or 'gif'.
{% endcomment %}
{% assign file_extension = 'png' %}
{% if swatch == blank %}
  <div class="swatch error">
    <p>You must include the snippet swatch.liquid with the name of a product option.</p> 
    <p>Use: <code>{% raw %}{% include 'swatch' with 'name of your product option here' %}{% endraw %}</code></p>
    <p>Example: <code>{% raw %}{% include 'swatch' with 'Color' %}{% endraw %}</code></p>
  </div>
{% else %}
  {% assign found_option = false %}
  {% assign is_color = false %}
  {% assign option_index = 0 %}
  {% for option in product.options %}
    {% if option == swatch %}
      {% assign found_option = true %}
      {% assign option_index = forloop.index0 %}

      <style>
        label[for="product-select-option-{{ option_index }}"] { display: none; }
        #product-select-option-{{ option_index }} { display: none; }
        #product-select-option-{{ option_index }} + .custom-style-select-box { display: none !important; }
      </style>

      {% assign downcased_option = swatch | downcase %}
      {% if downcased_option contains 'color' or downcased_option contains 'colour' %}
         {% assign is_color = true %}
    {% endif %}
   {% endif %}
{% endfor %}
{% unless found_option %}
  <div class="swatch error">
    <p>You included the snippet swatch.liquid with the name of a product option — <code>'{{ swatch }}'</code> — that does not belong to your product.</p>
    <p>Use <code>{% raw %}{% include 'swatch' with 'name of your product option here' %}{% endraw %}</code></p>
    <p>Example: <code>{% raw %}{% include 'swatch' with 'Color' %}{% endraw %}</code></p>
    <p><strong>This is case-sensitive!</strong> Do not put in <code>'color'</code> if your product option name is <code>'Color'</code>.</p>
  </div>
  {% else %}
    <div class="swatch clearfix {% unless is_color %} not_color-swatch-block {% endunless %}" data-option-index="{{ option_index }}">
      <h5 class="product-item-caption-select-title  {% if is_color %} color-swatch-title {% else %} not_color-swatch-title {% endif %}">{{ swatch }}:</h5>
      {% assign values = '' %}
      {% for variant in product.variants %}
        {% assign value = variant.options[option_index] %}
        {% unless values contains value %}
          {% assign values = values | join: ',' %}
          {% assign values = values | append: ',' | append: value %} 
          {% assign values = values | split: ',' %}
          {% assign valueHandle = value | handle %}
          <div data-variant-img="{{ variantImgSrc }}" data-value="{{ value | escape }}" class="swatch-element {% if is_color %}color {% else %} not_color {% endif %}{{ value | handle }} {% if variant.available %}available{% else %}soldout{% endif %}">
            {% if is_color %}
                <div class="tooltip">{{ value }}</div>
            {% endif %}
            <input id="swatch-{{section.id}}-{{product.id}}-{{ option_index }}-{{ value | handle }}-{{forloop.index}}" type="radio" name="option-{{ option_index }}" value="{{ value | escape }}"{% if forloop.first %} checked{% endif %} {% unless variant.available %}disabled{% endunless %} />
            {% if is_color %}
              <label for="swatch-{{section.id}}-{{product.id}}-{{ option_index }}-{{ value | handle }}-{{forloop.index}}" data-img="{{ variant.image | img_url: 'x720' }}" data-featuredImg="{{ product.featured_image | img_url: 'x720' }}">
                <i style="{% if valueHandle == "white"%} border: 1px solid; {% endif %} {% unless CSS_COLOR_NAMES contains valueHandle %} border: 1px solid; {% endunless %} background-color: {{ value | split: ' ' | last | handle }}; background-image: url({{ value | handle | append: '.' | append: file_extension | file_img_url:"60x" }});"></i>
                <img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" alt="Crossed Out" />
              </label>
            {% else %}
            <label for="swatch-{{section.id}}-{{product.id}}-{{ option_index }}-{{ value | handle }}-{{forloop.index}}">
                {{ value }}
                <img class="crossed-out" src="{{ 'soldout.png' | asset_url }}" alt="Crossed Out" />
              </label>
            {% endif %}
          </div>
        {% endunless %}
      {% endfor %}
    </div>
{% endunless %}
{% endif %}

 

0 Likes