Have your say in Community Polls: What was/is your greatest motivation to start your own business?

Showing Variant Metafield on the Product Page Dynamically

Showing Variant Metafield on the Product Page Dynamically

Sensei_Ryan
Shopify Partner
30 0 15

Hello, I am trying to display variant metafield on the product page under the product title for the Testament theme. I added this code in the main-product.liquid file under the product title but it is static and does not change dynamically when different variants are selected.

 

Code I used:

{% for variant in product.variants %}
{% if product.selected_or_first_available_variant.id == variant.id %}
<strong>{{ variant.metafields.custom.description }}</strong>
{% endif %}
{% endfor %}

 

I know there is something missing but I can't figure it out. I feel like I am half way there. If someone can please assist me then I would greatly appreciate it!

Replies 4 (4)

BSS-Commerce
Shopify Partner
3477 463 547

Hi @Sensei_Ryan 

We would like to give you a suggestion. It may be different cause I used the dawn theme to test this

- Solution 1:

Step 1: Go to Online store -> edit code -> global.js

Step 2: Find the onVariantChange() function and replace it with this code 

 

onVariantChange() {
    this.updateOptions();
    this.updateMasterId();
    this.toggleAddButton(true, '', false);
    this.updatePickupAvailability();
    this.removeErrorMessage();

    if (!this.currentVariant) {
      this.toggleAddButton(true, '', true);
      this.setUnavailable();
    } else {
      this.updateMedia();
      this.updateURL();
      this.updateVariantInput();
      this.renderProductInfo();
      this.updateShareUrl();


      // Below is the newly added line as shown in the video
      this.updateVariantDetails(this.currentVariant);
    }
  }


 updateVariantDetails(currentVariant){
    const variants = document.querySelectorAll('[data-variant-id]')
  
    variants.forEach( function(variant) {
        variant.style.display = 'none';
        if(variant.dataset.variantId == currentVariant.id){
          variant.style.display = 'block'
        }
      });
   }

 

Step 3: Find the CSS file (with dawn theme is base.css/ collage.css/theme.css...) and paste this code 

 

.variant__description {
  display: none
}

 

Step 4:  Enjoy the result

This is our tested video https://www.loom.com/share/ac2c265554c54d6b9f96c759d669bfd1

A note that it's working with the Dawn theme, so I'm not sure if it works with your theme or not. So can you kindly give me permission to your store to try the code?

 

- Solution 2: You can try this app to show the variant.  When you click 1 variant and it will show all your variants chosen and will display on the cart page and have a lot of types of variants like: (button, swatch, textfile, numberfield, .datepicker, file upload...). 

 

Your theme will become like this: 

+ Product page: 

view (84).png

+ Cart page:

view (85).png

I hope that it will work for you.

 

If our suggestions are useful, please let us know by giving it a like, marking it as a solution, or donating here .


B2B Solution & Custom Pricing | Product Labels by BSS


Need help from our expert? Kindly share your request with us via community@bsscommerce.com


BSS Commerce - Full-service eCommerce Agency
Sensei_Ryan
Shopify Partner
30 0 15

Thanks for the info! I couldn't get it to work myself though. What email should I send the permission to?

sharpie9701
Tourist
14 0 3

I have a question for you.  I have used that code and it works great!  All my variant metadata does exactly what I want it to.

 

My problem is, that when I add this part of the code:

updateVariantDetails(currentVariant){
const variants = document.querySelectorAll('[data-variant-id]')

variants.forEach( function(variant) {
variant.style.display = 'none';
if(variant.dataset.variantId == currentVariant.id){
variant.style.display = 'block'
}
});
}

my local pickup availability no longer refreshes with the variant change.  It disappears when you choose a different variant, but will reappear when you select the variant that the page loaded to.  I have tried everything I can think of and I can't seem to get the pickup availability to show right.  Otherwise, amazing coding!!

PradeepE
Shopify Partner
1 0 0

Hi,

Dawn theme 14 version , I am create a metafield for variants. Display the metafield on the each product page. It should dynamically change based on variant selection without reloading the page.
step 1: I am adding the metafields for varients like goto shopify admin page create the variant metafied afteer to add the metafield in product page. this process is like  settings->custom data->variants

step 2: To add custom liquid code like online store->customize->click to the product(Template->product information)->Add block->custom liquid->to enter the below code
code:

<div id="variant-metafield">
{% assign current_variant = product.selected_or_first_available_variant %}
{% if current_variant.metafields.custom.varient_data %}
<p id="variant-data">{{ current_variant.metafields.custom.varient_data }}</p>
{% endif %}
</div>

 

step 3: Now goto global.js file in Edit code to  add the below code  inside the

renderProductInfo(){}

code:
        const metafieldSource = html.getElementById(`variant-data`);
        const metafieldDestination = document.getElementById('variant-data');
        if (metafieldSource && metafieldDestination) {
          metafieldDestination.innerText = metafieldSource.innerText;
        }

conclusion:

this is i am adding the code on global.js
  renderProductInfo() {
    const requestedVariantId = this.currentVariant.id;
    const sectionId = this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section;

    fetch(
      `${this.dataset.url}?variant=${requestedVariantId}&section_id=${
        this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section
      }`
    )
      .then((response) => response.text())
      .then((responseText) => {
        // prevent unnecessary ui changes from abandoned selections
        if (this.currentVariant.id !== requestedVariantId) return;

        const html = new DOMParser().parseFromString(responseText, 'text/html');

        // Update metafield data dynamically
        const metafieldSource = html.getElementById(`variant-data`);
        const metafieldDestination = document.getElementById('variant-data');
        if (metafieldSource && metafieldDestination) {
          metafieldDestination.innerText = metafieldSource.innerText;
        }

        const destination = document.getElementById(`price-${this.dataset.section}`);
        const source = html.getElementById(
          `price-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`
        );
        const skuSource = html.getElementById(
          `Sku-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`
        );
        const skuDestination = document.getElementById(`Sku-${this.dataset.section}`);
        const inventorySource = html.getElementById(
          `Inventory-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`
        );
        const inventoryDestination = document.getElementById(`Inventory-${this.dataset.section}`);

        const volumePricingSource = html.getElementById(
          `Volume-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`
        );

        this.updateMedia(html);

        const pricePerItemDestination = document.getElementById(`Price-Per-Item-${this.dataset.section}`);
        const pricePerItemSource = html.getElementById(
          `Price-Per-Item-${this.dataset.originalSection ? this.dataset.originalSection : this.dataset.section}`
        );

        const volumePricingDestination = document.getElementById(`Volume-${this.dataset.section}`);
        const qtyRules = document.getElementById(`Quantity-Rules-${this.dataset.section}`);
        const volumeNote = document.getElementById(`Volume-Note-${this.dataset.section}`);

        if (volumeNote) volumeNote.classList.remove('hidden');
        if (volumePricingDestination) volumePricingDestination.classList.remove('hidden');
        if (qtyRules) qtyRules.classList.remove('hidden');

        if (source && destination) destination.innerHTML = source.innerHTML;
        if (inventorySource && inventoryDestination) inventoryDestination.innerHTML = inventorySource.innerHTML;
        if (skuSource && skuDestination) {
          skuDestination.innerHTML = skuSource.innerHTML;
          skuDestination.classList.toggle('hidden', skuSource.classList.contains('hidden'));
        }

        if (volumePricingSource && volumePricingDestination) {
          volumePricingDestination.innerHTML = volumePricingSource.innerHTML;
        }

        if (pricePerItemSource && pricePerItemDestination) {
          pricePerItemDestination.innerHTML = pricePerItemSource.innerHTML;
          pricePerItemDestination.classList.toggle('hidden', pricePerItemSource.classList.contains('hidden'));
        }

        const price = document.getElementById(`price-${this.dataset.section}`);

        if (price) price.classList.remove('hidden');

        if (inventoryDestination) inventoryDestination.classList.toggle('hidden', inventorySource.innerText === '');

        const addButtonUpdated = html.getElementById(`ProductSubmitButton-${sectionId}`);
        this.toggleAddButton(
          addButtonUpdated ? addButtonUpdated.hasAttribute('disabled') : true,
          window.variantStrings.soldOut
        );

        publish(PUB_SUB_EVENTS.variantChange, {
          data: {
            sectionId,
            html,
            variant: this.currentVariant,
          },
        });
      });
  }
dynamic-variant.pngdynamic-varient.png