Palo Alto Theme – Variant-Specific Images Not Updating on Color Change

Palo Alto Theme – Variant-Specific Images Not Updating on Color Change

MK7861
Shopify Partner
5 0 0

Hi everyone,

I'm using the Palo Alto Shopify Theme (Vibrant Style) and facing an issue with variant-specific images.

When I select a color (e.g., red or black), all product images are still shown instead of filtering to show only the images related to the selected variant. I’ve added alt text to match the variant media and tried some custom JS, but it’s still not working.

https://txl918zpmaxmm73h-72155496758.shopifypreview.com/products/testing-product


Has anyone successfully implemented variant-based image filtering in this theme?
Any help would be greatly appreciated!


Thanks!

Replies 6 (6)

StevenT_A7
Explorer
156 13 17

Hi @MK7861 , 

 

Go to Online Store > Themes > Edit Code

Open product.js or theme.js (depending on the Palo Alto version) or include this code at the bottom of your main-product.liquid or product-template.liquid inside <script> tags.

Please use the  code below for rectifying the  problem :-

 

<script>
document.addEventListener("DOMContentLoaded", function () {
const productForm = document.querySelector("form[action^='/cart/add']");
if (!productForm) return;

const variantSelector = productForm.querySelector('[name="options[Color]"]');
const allImages = document.querySelectorAll('[data-media-id]');
const productGallery = document.querySelector('.product__media-list');

function filterImagesByVariant(variantValue) {
if (!productGallery) return;

allImages.forEach(img => {
const altText = img.querySelector('img')?.alt || '';
if (altText.toLowerCase() === variantValue.toLowerCase()) {
img.style.display = '';
} else {
img.style.display = 'none';
}
});
}

// Initial load
if (variantSelector) {
filterImagesByVariant(variantSelector.value);

variantSelector.addEventListener("change", function () {
filterImagesByVariant(this.value);
});
}
});
</script>

 

Please use this code and let me know if you need any further clarifications.

Thanks ! 

 

Steven Taylor
302-260-8345
MK7861
Shopify Partner
5 0 0

Hi @StevenT_A7 ,

Thanks for your suggestion!

I added the code below the product.js file as recommended, but unfortunately, it didn’t have any effect. I also tried placing it at the bottom of theme.js, but still no change.

Is there anything else I might be missing, or should I try placing it somewhere else?

Appreciate your help!

This is the media.liquid code, and I can only confirm that the product detail thumbnails loop is coming from the media.liquid file:


{%- comment -%}
Renders a media element for the product gallery.
Media types include: image, video, external_video and model.
Accepts:
- media: {Object} Media Liquid object (required)
- featured_media: {Object} Media Liquid object (required) - featured media of a given product or variant
- img_sizes: {String} - A set of media conditions for `img` sizes attribute (Optional)
- image_width: {Number} - Image width on desktop based on section settings
- unique: {String} Section id
- hide_controls: {Boolean} True or false - Hide video controls

Usage:
{%- for media in product.media -%}
{% render 'media', media: media, featured_media: featured_media, unique: unique, hide_controls: hide_controls %}
{%- endfor -%}
{%- endcomment -%}

{%- liquid
assign img_sizes = img_sizes | default: ''
assign image_widths = image_widths | default: '245, 320, 365, 410, 490, 640, 753, 848, 980, 1024, 1280, 1506, 1696, 1960'
assign image_size = '1024x1024'
assign image_zoom_size = '2048x2048'
assign view_string = 'general.accessibility.view' | t
capture media_wrapper_id
echo 'FeaturedMedia-' | append: unique | append: '-' | append: media.id
endcapture

assign media_aspect_ratio = media.aspect_ratio
unless media_aspect_ratio
assign media_aspect_ratio = 1
endunless
assign media_padding_top = 1 | divided_by: media_aspect_ratio | times: 100 | round: 1

if section.settings.image_aspect_ratio
assign media_padding_top = section.settings.image_aspect_ratio | times: 100 | round: 1
endif

assign controls = true
if hide_controls
assign controls = false
endif

capture image
assign loading = loading | default: 'lazy'
assign preload = nil
assign fetchpriority = nil
assign image_alt = media.alt | strip_html | escape

if template.name == 'product' and media == featured_media
assign loading = 'eager'
assign fetchpriority = 'high'
assign preload = true
endif

assign sizes = '(min-width: 1400px) ' | append: image_width | append: ', (min-width: 768px) calc((100vw - 40px) * 0.6 - 30px), calc(100vw - 40px)'

if section_type == 'quickview'
case settings.quick_buy_image_layout
when 'large'
assign sizes = '(min-width: 768px) 315px, calc((100vw - 50px) / 2 - 17px)'
when 'small'
assign sizes = '(min-width: 768px) 163px, calc((100vw - 50px) / 2 - 17px)'
endcase
assign image_widths = '150, 300, 315, 330, 360, 480, 540, 630, 720'
assign loading = 'eager'
assign fetchpriority = 'high'
endif

if img_sizes != ''
assign sizes = img_sizes
endif

assign image_id = media.id
assign is_simple_img = false
if media.media_type != 'image'
assign image_id = nil
assign is_simple_img = true
endif

render 'image', image: media.preview_image, simple: is_simple_img, widths: image_widths, sizes: sizes, loading: loading, fetchpriority: fetchpriority, preload: preload, id: image_id, alt: image_alt
endcapture

capture media_display
case media.media_type
when 'external_video'
if media.host == 'youtube'
echo media | external_video_url: autoplay: true, mute: true, playsinline: true, controls: controls, loop: enable_video_looping, playlist: media.external_id | external_video_tag: loading: 'lazy'
else
echo media | external_video_url: autoplay: true, muted: true, playsinline: true, controls: controls, loop: enable_video_looping | external_video_tag: loading: 'lazy'
endif
when 'video'
echo media | media_tag: image_size: image_size, class: 'media-video', autoplay: true, muted: true, loop: enable_video_looping, controls: controls
when 'model'
echo media | model_viewer_tag: image_size: image_size, toggleable: true, data-model-id: media.id
else
echo media | media_tag: class: 'media-item', image_size: image_size
endcase
endcapture

capture deferred_media_classes
echo 'product-gallery__media deferred-media'
echo ' product-gallery__media--' | append: media.id
if media.media_type == 'external_video' or media.media_type == 'video'
echo ' product-gallery__media--video'
endif
if media.media_type == 'model'
echo ' product-gallery__media--model'
endif
endcapture
-%}

{%- capture interaction_markup -%}
<button type="button"
class="deferred-media__poster"
aria-label="{{ view_string }} {{ image_alt }}"
data-deferred-media-button
>
<span class="deferred-media__poster-button">
{%- if media.media_type == 'model' -%}
{%- render 'icon-media-model' -%}
{%- else -%}
{%- render 'icon-media-video' -%}
{%- endif -%}
</span>

{{ image }}
</button>
{%- endcapture -%}

 

{% assign media_variant_ids = '' %}
{% for variant in product.variants %}
{% if variant.featured_media != null and variant.featured_media.id == media.id %}
{% assign media_variant_ids = media_variant_ids | append: variant.id | append: ' ' %}
{% endif %}
{% endfor %}

 

 


<div id="{{ media_wrapper_id }}"
class="product-gallery__media-slide{% unless featured_media == media %} media--hidden{% endunless %}"
data-product-slide
data-id="{{ media.id }}"
data-variant-ids="{{ media_variant_ids | strip }}"
data-aspectratio="{{ media_aspect_ratio }}"
data-media-id="{{ unique }}-{{ media.id }}"
data-type="{{ media.media_type }}"


{% if media.media_type == 'video' or media.media_type == 'external_video' %}
data-video
data-video-id="{{ media.id }}"
data-enable-video-looping="{{ enable_video_looping }}"
{% endif %}
{% if media.media_type == 'model' %}
data-model
data-model-id="{{ media.id }}"
{% endif %}
{% if media.media_type == 'external_video' %}
data-youtube-id="{{ media.external_id }}"
{% endif %}
data-product-single-media-wrapper
>

 



{%- if media.media_type == 'image' -%}

<div class="product-gallery__media product-gallery__media--image">
<div class="product-gallery__media-space" style="--media-padding-top: {{ media_padding_top }}%;"></div>

{{ image }}

{%- if enable_zoom and section_type != 'quickview' -%}
<a href="{{ media | product_img_url: image_zoom_size }}"
class="product-gallery__media-link"
rel="lightbox"
data-zoom-wrapper
data-image-width="{{ media.width }}"
data-image-height="{{ media.height }}">
<span class="visually-hidden">{{ 'general.accessibility.product_image_lightbox' | t }}</span>
</a>
{%- endif -%}
</div>
{%- else -%}

 



{%- case media.media_type -%}
{%- when 'external_video' or 'video' or 'model' -%}
<deferred-media class="{{ deferred_media_classes }}"
data-deferred-media
style="padding-top: {{ media_padding_top }}%;"
{% if media.media_type != 'external_video' %} data-loop="{{ enable_video_looping }}"{% endif %}
>
{{ interaction_markup }}

<template>
{{ media_display }}
</template>
</deferred-media>

{%- else -%}
<div class="product-gallery__media" style="padding-top: {{ media_padding_top }}%;">
{{ media_display }}
</div>
{%- endcase -%}
{%- endif -%}
</div>



Best regards,

MK7861
Shopify Partner
5 0 0

When I used this code in the media.liquid product thumbnails loop, it worked fine
{% if product.selected_or_first_available_variant.featured_media.alt != media.alt and product.selected_or_first_available_variant.featured_media.alt != blank %}
style="display: none;"
{% endif %}
thumbnail-alt="{{ media.alt }}"

But when I click on the variant color, it doesn't change. Maybe I need some JavaScript code or CSS.

tim
Shopify Partner
4727 578 1706

Have you seen/implemented/verified this -- https://palo-alto.presidiocreative.com/products/palo-alto-product-pages/variant-images ?

If my post is helpful, hit the thumb up button -- it will help others with similar problem to find a solution.
I can be reached via e-mail tairli@yahoo.com
MK7861
Shopify Partner
5 0 0

Yes, I checked, but it's not what I'm looking for. I want the thumbnails to display only when I click on a particular variant color—only the related thumbnails, not all of them. It's basically simple in the free theme, but in this theme, it's not working. I don’t know why.

I want exactly like this example: Without Shopify APP
https://variant-image-wizard.myshopify.com/products/open-front-poncho-cape?variant=39437642203249


MK7861
Shopify Partner
5 0 0

When I used this code in the media.liquid product thumbnails loop, it worked fine
{% if product.selected_or_first_available_variant.featured_media.alt != media.alt and product.selected_or_first_available_variant.featured_media.alt != blank %}
style="display: none;"
{% endif %}
thumbnail-alt="{{ media.alt }}"

But when I click on the variant color, it doesn't change. Maybe I need some JavaScript code or CSS.