onVariantChange class is not there in Shopify Dawn 15.0.0.

I’m trying to display only images of the selected Variant using the alt text (i.e. variant color name in provided in the alt text place) provided in the backend. this is the code I’m working with

class VariantSelects extends HTMLElement {
  constructor() {
    super();
  }
  
  connectedCallback() {
    this.addEventListener('change', (event) => {
      const target = this.getInputForEventTarget(event.target);
      this.updateSelectionMetadata(event);

      publish(PUB_SUB_EVENTS.optionValueSelectionChange, {
        data: {
          event,
          target,
          selectedOptionValues: this.selectedOptionValues,
        },
      });
    });
  }

  updateSelectionMetadata({ target }) {
    const { value, tagName } = target;

    if (tagName === 'SELECT' && target.selectedOptions.length) {
      Array.from(target.options)
        .find((option) => option.getAttribute('selected'))
        .removeAttribute('selected');
      target.selectedOptions[0].setAttribute('selected', 'selected');

      const swatchValue = target.selectedOptions[0].dataset.optionSwatchValue;
      const selectedDropdownSwatchValue = target
        .closest('.product-form__input')
        .querySelector('[data-selected-value] > .swatch');
      if (!selectedDropdownSwatchValue) return;
      if (swatchValue) {
        selectedDropdownSwatchValue.style.setProperty('--swatch--background', swatchValue);
        selectedDropdownSwatchValue.classList.remove('swatch--unavailable');
      } else {
        selectedDropdownSwatchValue.style.setProperty('--swatch--background', 'unset');
        selectedDropdownSwatchValue.classList.add('swatch--unavailable');
      }

      selectedDropdownSwatchValue.style.setProperty(
        '--swatch-focal-point',
        target.selectedOptions[0].dataset.optionSwatchFocalPoint || 'unset'
      );
    } else if (tagName === 'INPUT' && target.type === 'radio') {
      const selectedSwatchValue = target.closest(`.product-form__input`).querySelector('[data-selected-value]');
      if (selectedSwatchValue) selectedSwatchValue.innerHTML = value;
    }
  }

  getInputForEventTarget(target) {
    return target.tagName === 'SELECT' ? target.selectedOptions[0] : target;
  }

  get selectedOptionValues() {
    return Array.from(this.querySelectorAll('select option[selected], fieldset input:checked')).map(
      ({ dataset }) => dataset.optionValueId
    );
  }
}

I’m trying to add onVariantChange() class option and all the classes that follow this like -

  • updateOptions()

  • updateMasterId()

  • filterImgVariant()

  • toggleAddButton()

  • updatePickupAvailability()

  • removeErrorMessage()

  • updateVariantStatues()

  • updateMedia()

  • updateURL()

  • updateVariantInput()

  • renderProductInfo()

  • updateShareUrl()

all these classes are missing in the above code at the 5th line. Please help with this issue..!

Appreciate any help I can re

@Saradh_Chandra totally get it man. That was so easy to do. But I guess they changed the code base and it will be a bit of research now to get that working.

@KetanKumar

@Zworthkey

@PageFly-Victor

@dmwwebartisan

@ZestardTech

Here’s the link to my site: https://da094b-2d.myshopify.com/products/ua-heatgear-compression-long-sleeve

I changed the code in the files (product-media-gallery.liquid and global.js) and I share the following codes below. After changing the code, only variant images are shown. But, the media is not getting changed without reloading the page. And when we click on the images it will get zoomed, again there it shows all the images.

Here’s the link to the code in the git repo:

@Saradh_Chandra yeah will have to look for onVariant change function and add our code in there to make it work without refreshing the page.

I have been in the global.js folder I don’t think it’s there. The code base has changed drastically.

Did you get anything..?

I tried hardcoding location.reload(), but that doesn’t seem to work. I’m not sure where to add this. Let me know if you get anything. I appreciate any input.

@Saradh_Chandra I haven’t looked at it yet. Will see to it and update you

Thanks

@Saradh_Chandra this took a lot of looking up but I did manage to implement it alhamdulillah.

@Shadab_dev can you send the solution..?

@Saradh_Chandra Sure.

So first of all make add the alt text to your images.

Make sure the text is exactly same as of your variants.

Then on your product-media-gallery.liquid file add this entire code.

{% comment %}
Renders a product media gallery. Should be used with ‘media-gallery.js’
Also see ‘product-media-modal’

Accepts:

  • product: {Object} Product liquid object
  • variant_images: {Array} Product images associated with a variant
  • limit: {Number} (optional) When passed, limits the number of media items to render

Usage:
{% render ‘product-media-gallery’ %}
{% endcomment %}

{%- liquid
if section.settings.hide_variants and variant_images.size == product.media.size
assign single_media_visible = true
endif

if limit == 1
assign single_media_visible = true
endif

assign media_count = product.media.size
if section.settings.hide_variants and media_count > 1 and variant_images.size > 0
assign media_count = media_count | minus: variant_images.size | plus: 1
endif

if media_count == 1 or single_media_visible
assign single_media_visible_mobile = true
endif

if media_count == 0 or single_media_visible_mobile or section.settings.mobile_thumbnails == ‘show’ or section.settings.mobile_thumbnails == ‘columns’ and media_count < 3
assign hide_mobile_slider = true
endif

if section.settings.media_size == ‘large’
assign media_width = 0.65
elsif section.settings.media_size == ‘medium’
assign media_width = 0.55
elsif section.settings.media_size == ‘small’
assign media_width = 0.45
endif
-%}

<media-gallery
id=“MediaGallery-{{ section.id }}”
role=“region”
{% if section.settings.enable_sticky_info %}
class=“product__column-sticky”
{% endif %}
aria-label=“{{ ‘products.product.media.gallery_viewer’ | t }}”
data-desktop-layout=“{{ section.settings.gallery_layout }}”

{{ 'accessibility.skip_to_product_info' | t }}
    {%- if product.selected_or_first_available_variant.featured_media != null -%} {%- assign featured_media = product.selected_or_first_available_variant.featured_media -%}
  • {%- assign media_position = 1 -%} {% render 'product-thumbnail', media: featured_media, media_count: media_count, position: media_position, desktop_layout: section.settings.gallery_layout, mobile_layout: section.settings.mobile_thumbnails, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true, media_width: media_width, media_fit: section.settings.media_fit, constrain_to_viewport: section.settings.constrain_to_viewport, lazy_load: false %}
  • {%- endif -%} {%- for media in product.media -%} {% if media_position >= limit or media_position >= 1 and section.settings.hide_variants and variant_images contains media.src %} {% continue %} {% endif %}

    {%- unless media.id == product.selected_or_first_available_variant.featured_media.id -%}

  • {%- liquid assign media_position = media_position | default: 0 | plus: 1 assign lazy_load = false if media_position > 1 assign lazy_load = true endif -%} {% render 'product-thumbnail', media: media, media_count: media_count, position: media_position, desktop_layout: section.settings.gallery_layout, mobile_layout: section.settings.mobile_thumbnails, loop: section.settings.enable_video_looping, modal_id: section.id, xr_button: true, media_width: media_width, media_fit: section.settings.media_fit, constrain_to_viewport: section.settings.constrain_to_viewport, lazy_load: lazy_load %}
  • {%- endunless -%} {%- endfor -%}
{% render 'icon-caret' %}
1 / {{ 'general.slider.of' | t }} {{ media_count }}
{% render 'icon-caret' %}
{%- if first_3d_model -%} {% render 'icon-3d-model' %} {{ 'products.product.xr_button' | t }} {%- endif -%} {%- liquid assign is_not_limited_to_single_item = false if limit == null or limit > 1 assign is_not_limited_to_single_item = true endif -%} {%- if is_not_limited_to_single_item and media_count > 1 and section.settings.gallery_layout contains 'thumbnail' or section.settings.mobile_thumbnails == 'show' -%} {% render 'icon-caret' %}
    {%- capture sizes -%} (min-width: {{ settings.page_width }}px) calc(({{ settings.page_width | minus: 100 | times: media_width | round }} - 4rem) / 4), (min-width: 990px) calc(({{ media_width | times: 100 }}vw - 4rem) / 4), (min-width: 750px) calc((100vw - 15rem) / 8), calc((100vw - 8rem) / 3) {%- endcapture -%}

    {%- if featured_media != null -%}
    {%- liquid
    capture media_index
    if featured_media.media_type == ‘model’
    increment model_index
    elsif featured_media.media_type == ‘video’ or featured_media.media_type == ‘external_video’
    increment video_index
    elsif featured_media.media_type == ‘image’
    increment image_index
    endif
    endcapture
    assign media_index = media_index | plus: 1
    -%}

  • {%- capture thumbnail_id -%} Thumbnail-{{ section.id }}-0 {%- endcapture -%} {{ featured_media.preview_image | image_url: width: 416 | image_tag: loading: 'lazy', sizes: sizes, widths: '54, 74, 104, 162, 208, 324, 416', id: thumbnail_id, alt: featured_media.alt | escape }}
  • {%- endif -%} {%- for media in product.media -%} {%- unless media.id == product.selected_or_first_available_variant.featured_media.id -%} {%- liquid capture media_index if media.media_type == 'model' increment model_index elsif media.media_type == 'video' or media.media_type == 'external_video' increment video_index elsif media.media_type == 'image' increment image_index endif endcapture assign media_index = media_index | plus: 1 -%}
  • {%- if media.media_type == 'model' -%} {%- render 'icon-3d-model' -%} {%- elsif media.media_type == 'video' or media.media_type == 'external_video' -%} {%- render 'icon-play' -%} {%- endif -%} {%- capture thumbnail_id -%} Thumbnail-{{ section.id }}-{{ forloop.index }} {%- endcapture -%} {{ media.preview_image | image_url: width: 416 | image_tag: loading: 'lazy', sizes: sizes, widths: '54, 74, 104, 162, 208, 324, 416', id: thumbnail_id, alt: media.alt | escape }}
  • {%- endunless -%} {%- endfor -%}
{% render 'icon-caret' %} {%- endif -%}

And then in product-info.js add this code

if (!customElements.get(‘product-info’)) {
customElements.define(
‘product-info’,
class ProductInfo extends HTMLElement {
quantityInput = undefined;
quantityForm = undefined;
onVariantChangeUnsubscriber = undefined;
cartUpdateUnsubscriber = undefined;
abortController = undefined;
pendingRequestUrl = null;
preProcessHtmlCallbacks = ;
postProcessHtmlCallbacks = ;

constructor() {
super();

this.quantityInput = this.querySelector(‘.quantity__input’);
}

connectedCallback() {
this.initializeProductSwapUtility();

this.onVariantChangeUnsubscriber = subscribe(
PUB_SUB_EVENTS.optionValueSelectionChange,
this.handleOptionValueChange.bind(this)
);

this.initQuantityHandlers();
this.dispatchEvent(new CustomEvent(‘product-info:loaded’, { bubbles: true }));
}

addPreProcessCallback(callback) {
this.preProcessHtmlCallbacks.push(callback);
}

initQuantityHandlers() {
if (!this.quantityInput) return;

this.quantityForm = this.querySelector(‘.product-form__quantity’);
if (!this.quantityForm) return;

this.setQuantityBoundries();
if (!this.dataset.originalSection) {
this.cartUpdateUnsubscriber = subscribe(PUB_SUB_EVENTS.cartUpdate, this.fetchQuantityRules.bind(this));
}
}

disconnectedCallback() {
this.onVariantChangeUnsubscriber();
this.cartUpdateUnsubscriber?.();
}

initializeProductSwapUtility() {
this.preProcessHtmlCallbacks.push((html) =>
html.querySelectorAll(‘.scroll-trigger’).forEach((element) => element.classList.add(‘scroll-trigger–cancel’))
);
this.postProcessHtmlCallbacks.push((newNode) => {
window?.Shopify?.PaymentButton?.init();
window?.ProductModel?.loadShopifyXR();
});
}

handleOptionValueChange({ data: { event, target, selectedOptionValues } }) {
if (!this.contains(event.target)) return;
this.resetProductFormState();

const productUrl = target.dataset.productUrl || this.pendingRequestUrl || this.dataset.url;
this.pendingRequestUrl = productUrl;
const shouldSwapProduct = this.dataset.url !== productUrl;
const shouldFetchFullPage = this.dataset.updateUrl === ‘true’ && shouldSwapProduct;

this.renderProductInfo({
requestUrl: this.buildRequestUrlWithParams(productUrl, selectedOptionValues, shouldFetchFullPage),
targetId: target.id,
callback: shouldSwapProduct
? this.handleSwapProduct(productUrl, shouldFetchFullPage)
: this.handleUpdateProductInfo(productUrl),
});
}

resetProductFormState() {
const productForm = this.productForm;
productForm?.toggleSubmitButton(true);
productForm?.handleErrorMessage();
}

handleSwapProduct(productUrl, updateFullPage) {
return (html) => {
this.productModal?.remove();

const selector = updateFullPage ? “product-info[id^=‘MainProduct’]” : ‘product-info’;
const variant = this.getSelectedVariant(html.querySelector(selector));
this.updateURL(productUrl, variant?.id);
if (updateFullPage) {
document.querySelector(‘head title’).innerHTML = html.querySelector(‘head title’).innerHTML;

HTMLUpdateUtility.viewTransition(
document.querySelector(‘main’),
html.querySelector(‘main’),
this.preProcessHtmlCallbacks,
this.postProcessHtmlCallbacks
);
} else {
HTMLUpdateUtility.viewTransition(
this,
html.querySelector(‘product-info’),
this.preProcessHtmlCallbacks,
this.postProcessHtmlCallbacks
);
}
};
}

renderProductInfo({ requestUrl, targetId, callback }) {
this.abortController?.abort();
this.abortController = new AbortController();

fetch(requestUrl, { signal: this.abortController.signal })
.then((response) => response.text())
.then((responseText) => {
this.pendingRequestUrl = null;
const html = new DOMParser().parseFromString(responseText, ‘text/html’);
callback(html);
})
.then(() => {
// set focus to last clicked option value
document.querySelector(#${targetId})?.focus();
})
.catch((error) => {
if (error.name === ‘AbortError’) {
console.log(‘Fetch aborted by user’);
} else {
console.error(error);
}
});
}

getSelectedVariant(productInfoNode) {
const selectedVariant = productInfoNode.querySelector(‘variant-selects [data-selected-variant]’)?.innerHTML;
return !!selectedVariant ? JSON.parse(selectedVariant) : null;
}

buildRequestUrlWithParams(url, optionValues, shouldFetchFullPage = false) {
const params = ;

!shouldFetchFullPage && params.push(section_id=${this.sectionId});

if (optionValues.length) {
params.push(option_values=${optionValues.join(',')});
}

return ${url}?${params.join('&')};
}

updateOptionValues(html) {
const variantSelects = html.querySelector(‘variant-selects’);
if (variantSelects) {
HTMLUpdateUtility.viewTransition(this.variantSelectors, variantSelects, this.preProcessHtmlCallbacks);
}
}

handleUpdateProductInfo(productUrl) {
return (html) => {
const variant = this.getSelectedVariant(html);

this.pickupAvailability?.update(variant);
this.updateOptionValues(html);
this.updateURL(productUrl, variant?.id);
this.updateVariantInputs(variant?.id);

if (!variant) {
this.setUnavailable();
return;
}

this.updateMedia(html, variant?.featured_media?.id);
this.filterVariantImages(variant);
const updateSourceFromDestination = (id, shouldHide = (source) => false) => {
const source = html.getElementById(${id}-${this.sectionId});
const destination = this.querySelector(#${id}-${this.dataset.section});
if (source && destination) {
destination.innerHTML = source.innerHTML;
destination.classList.toggle(‘hidden’, shouldHide(source));
}
};

updateSourceFromDestination(‘price’);
updateSourceFromDestination(‘Sku’, ({ classList }) => classList.contains(‘hidden’));
updateSourceFromDestination(‘Inventory’, ({ innerText }) => innerText === ‘’);
updateSourceFromDestination(‘Volume’);
updateSourceFromDestination(‘Price-Per-Item’, ({ classList }) => classList.contains(‘hidden’));

this.updateQuantityRules(this.sectionId, html);
this.querySelector(#Quantity-Rules-${this.dataset.section})?.classList.remove(‘hidden’);
this.querySelector(#Volume-Note-${this.dataset.section})?.classList.remove(‘hidden’);

this.productForm?.toggleSubmitButton(
html.getElementById(ProductSubmitButton-${this.sectionId})?.hasAttribute(‘disabled’) ?? true,
window.variantStrings.soldOut
);

publish(PUB_SUB_EVENTS.variantChange, {
data: {
sectionId: this.sectionId,
html,
variant,
},
});
};
}

filterVariantImages(varObj){
if(varObj.featured_image && varObj.featured_image.alt){

document.querySelectorAll(‘[thumbnail-alt]’).forEach(img => img.style.display = ‘none’);
const currentImageAlt = varObj.featured_image.alt;
const thumbnailSelector= [thumbnail-alt= '${currentImageAlt}'];
document.querySelectorAll(thumbnailSelector).forEach( (img) => {
img.style.display = ‘block’;
})
} else{
document.querySelectorAll(‘[thumbnail-alt]’).forEach(img => img.style.display = ‘block’);
}

}

updateVariantInputs(variantId) {
this.querySelectorAll(
#product-form-${this.dataset.section}, #product-form-installment-${this.dataset.section}
).forEach((productForm) => {
const input = productForm.querySelector(‘input[name=“id”]’);
input.value = variantId ?? ‘’;
input.dispatchEvent(new Event(‘change’, { bubbles: true }));
});
}

updateURL(url, variantId) {
this.querySelector(‘share-button’)?.updateUrl(
${window.shopUrl}${url}${variantId ? ?variant=${variantId} : ''}
);

if (this.dataset.updateUrl === ‘false’) return;
window.history.replaceState({}, ‘’, ${url}${variantId ? ?variant=${variantId} : ''});
}

setUnavailable() {
this.productForm?.toggleSubmitButton(true, window.variantStrings.unavailable);

const selectors = [‘price’, ‘Inventory’, ‘Sku’, ‘Price-Per-Item’, ‘Volume-Note’, ‘Volume’, ‘Quantity-Rules’]
.map((id) => #${id}-${this.dataset.section})
.join(', ');
document.querySelectorAll(selectors).forEach(({ classList }) => classList.add(‘hidden’));
}

updateMedia(html, variantFeaturedMediaId) {
if (!variantFeaturedMediaId) return;
const mediaGallerySource = this.querySelector(‘media-gallery ul’);
const mediaGalleryDestination = html.querySelector(media-gallery ul);
const refreshSourceData = () => {
if (this.hasAttribute(‘data-zoom-on-hover’)) enableZoomOnHover(2);
const mediaGallerySourceItems = Array.from(mediaGallerySource.querySelectorAll(‘li[data-media-id]’));
const sourceSet = new Set(mediaGallerySourceItems.map((item) => item.dataset.mediaId));
const sourceMap = new Map(
mediaGallerySourceItems.map((item, index) => [item.dataset.mediaId, { item, index }])
);
return [mediaGallerySourceItems, sourceSet, sourceMap];
};

if (mediaGallerySource && mediaGalleryDestination) {
let [mediaGallerySourceItems, sourceSet, sourceMap] = refreshSourceData();
const mediaGalleryDestinationItems = Array.from(
mediaGalleryDestination.querySelectorAll(‘li[data-media-id]’)
);
const destinationSet = new Set(mediaGalleryDestinationItems.map(({ dataset }) => dataset.mediaId));
let shouldRefresh = false;

// add items from new data not present in DOM
for (let i = mediaGalleryDestinationItems.length - 1; i >= 0; i–) {
if (!sourceSet.has(mediaGalleryDestinationItems[i].dataset.mediaId)) {
mediaGallerySource.prepend(mediaGalleryDestinationItems[i]);
shouldRefresh = true;
}
}

// remove items from DOM not present in new data
for (let i = 0; i < mediaGallerySourceItems.length; i++) {
if (!destinationSet.has(mediaGallerySourceItems[i].dataset.mediaId)) {
mediaGallerySourceItems[i].remove();
shouldRefresh = true;
}
}

// refresh
if (shouldRefresh) [mediaGallerySourceItems, sourceSet, sourceMap] = refreshSourceData();

// if media galleries don’t match, sort to match new data order
mediaGalleryDestinationItems.forEach((destinationItem, destinationIndex) => {
const sourceData = sourceMap.get(destinationItem.dataset.mediaId);

if (sourceData && sourceData.index !== destinationIndex) {
mediaGallerySource.insertBefore(
sourceData.item,
mediaGallerySource.querySelector(li:nth-of-type(${destinationIndex + 1}))
);

// refresh source now that it has been modified
[mediaGallerySourceItems, sourceSet, sourceMap] = refreshSourceData();
}
});
}

// set featured media as active in the media gallery
this.querySelector(media-gallery)?.setActiveMedia?.(
${this.dataset.section}-${variantFeaturedMediaId},
true
);

// update media modal
const modalContent = this.productModal?.querySelector(.product-media-modal__content);
const newModalContent = html.querySelector(product-modal .product-media-modal__content);
if (modalContent && newModalContent) modalContent.innerHTML = newModalContent.innerHTML;
}

setQuantityBoundries() {
const data = {
cartQuantity: this.quantityInput.dataset.cartQuantity ? parseInt(this.quantityInput.dataset.cartQuantity) : 0,
min: this.quantityInput.dataset.min ? parseInt(this.quantityInput.dataset.min) : 1,
max: this.quantityInput.dataset.max ? parseInt(this.quantityInput.dataset.max) : null,
step: this.quantityInput.step ? parseInt(this.quantityInput.step) : 1,
};

let min = data.min;
const max = data.max === null ? data.max : data.max - data.cartQuantity;
if (max !== null) min = Math.min(min, max);
if (data.cartQuantity >= data.min) min = Math.min(min, data.step);

this.quantityInput.min = min;

if (max) {
this.quantityInput.max = max;
} else {
this.quantityInput.removeAttribute(‘max’);
}
this.quantityInput.value = min;

publish(PUB_SUB_EVENTS.quantityUpdate, undefined);
}

fetchQuantityRules() {
const currentVariantId = this.productForm?.variantIdInput?.value;
if (!currentVariantId) return;

this.querySelector(‘.quantity__rules-cart .loading__spinner’).classList.remove(‘hidden’);
fetch(${this.dataset.url}?variant=${currentVariantId}&section_id=${this.dataset.section})
.then((response) => response.text())
.then((responseText) => {
const html = new DOMParser().parseFromString(responseText, ‘text/html’);
this.updateQuantityRules(this.dataset.section, html);
})
.catch((e) => console.error(e))
.finally(() => this.querySelector(‘.quantity__rules-cart .loading__spinner’).classList.add(‘hidden’));
}

updateQuantityRules(sectionId, html) {
if (!this.quantityInput) return;
this.setQuantityBoundries();

const quantityFormUpdated = html.getElementById(Quantity-Form-${sectionId});
const selectors = [‘.quantity__input’, ‘.quantity__rules’, ‘.quantity__label’];
for (let selector of selectors) {
const current = this.quantityForm.querySelector(selector);
const updated = quantityFormUpdated.querySelector(selector);
if (!current || !updated) continue;
if (selector === ‘.quantity__input’) {
const attributes = [‘data-cart-quantity’, ‘data-min’, ‘data-max’, ‘step’];
for (let attribute of attributes) {
const valueUpdated = updated.getAttribute(attribute);
if (valueUpdated !== null) {
current.setAttribute(attribute, valueUpdated);
} else {
current.removeAttribute(attribute);
}
}
} else {
current.innerHTML = updated.innerHTML;
}
}
}

get productForm() {
return this.querySelector(product-form);
}

get productModal() {
return document.querySelector(#ProductModal-${this.dataset.section});
}

get pickupAvailability() {
return this.querySelector(pickup-availability);
}

get variantSelectors() {
return this.querySelector(‘variant-selects’);
}

get relatedProducts() {
const relatedProductsSectionId = SectionId.getIdForSection(
SectionId.parseId(this.sectionId),
‘related-products’
);
return document.querySelector(product-recommendations[data-section-id^="${relatedProductsSectionId}"]);
}

get quickOrderList() {
const quickOrderListSectionId = SectionId.getIdForSection(
SectionId.parseId(this.sectionId),
‘quick_order_list’
);
return document.querySelector(quick-order-list[data-id^="${quickOrderListSectionId}"]);
}

get sectionId() {
return this.dataset.originalSection || this.dataset.section;
}
}
);
}

i believe this should do it. Let me know if you encounter any problem. Dont forget to like and mark it if it helps.

Email me if you need any further help related to code, theme customizations for your business.

Buy Me Some Coffee if you feel i was helpful and i deserve it. Does act as a motivation.

Thanks anyways

@Saradh_Chandra there is code for two files here. First is product-media-gallery.liquid and then product-info.js. the js file starts in between so please look for it in between.

Thanks

@Saradh_Chandra @Shadab_dev

The simple solution here is to load your variant images in the product-media-gallery.liquid file in whatever way you prefer (using variant image or a variant metafield to have a variant gallery) and then let the new dawn do it’s work. The new version of dawn (dawn15+) reloads the ALL product content on variant change automatically, including the images, so if the variant page load would have the content displayed, the switch does too.

Hi @jessie_monument , saradh here wanted to show only selected variant images. So if a user selects red t-shirt only red color products are shown and so on i am pretty sure you get the point. Does the newer versions of dawn implement this automatically??

Thanks

@Shadab_dev Not exactly automatically but with very little code knowledge or customization.

A basic outline of the set up would involve:

  • creating a variant metafield for a list of images/videos

  • editing the product-media-gallery.liquid file to include only the images from the currently selected variant (from the new metafield)

  • editing the product-media-modal.liquid file to do the same

Thats it! The trigger to reload the images (and the rest of the page content on the product page) happens automatically when a new variant is selected.

@jessie_monument I have done exactly that and luckily enough I was successful in implementing it.

So i am not trying to load images I guess that is something every theme or atleast every free theme brings with itself, I am just hiding or selecting images based on the selected variant.

And yes I am using alt text on images to select particular variants.