Re: variant change update app block

Solved

variant change update app block

Jatin_Jajra
Shopify Partner
3 0 3

I have created a Shopify app in which using theme app extensions I am adding an app block to the product detail page in which I am showing the quantity of the product. Now I have to update the product quantity on the product detail page if the user changes the variant. I want the user to change the variant as soon as they change it, and an event should be triggered by changing the variant inside my app block so that I can update the app block. 

Accepted Solution (1)

Digiteon
Excursionist
11 2 1

This is an accepted solution.

You can use JavaScript to listen for variant changes and trigger an event to update the app block. Here’s a concise solution:

 

Listen for Variant Changes:

 

Use Shopify's variantChange event to detect when a variant is selected. You can listen for this event using JavaScript.

 

Update the App Block:

 

When the variantChange event is triggered, update the product quantity in your app block accordingly.

Here’s a basic example of how you might achieve this:

 

 

// Function to update the app block with new quantity
function updateAppBlock(quantity) {
    // Assuming you have a method to update the app block
    const appBlockElement = document.getElementById('app-block'); // Replace with your actual app block ID or class
    appBlockElement.textContent = `Quantity: ${quantity}`;
}

// Listen for variant change event
document.addEventListener('DOMContentLoaded', () => {
    const variantSelect = document.querySelector('select[name="id"]'); // Replace with your variant selector
    if (variantSelect) {
        variantSelect.addEventListener('change', (event) => {
            const selectedVariantId = event.target.value;

            // Fetch variant details using Shopify’s AJAX API
            fetch(`/products/${window.productHandle}.js`)
                .then(response => response.json())
                .then(product => {
                    const selectedVariant = product.variants.find(variant => variant.id == selectedVariantId);
                    if (selectedVariant) {
                        updateAppBlock(selectedVariant.inventory_quantity);
                    }
                })
                .catch(error => console.error('Error fetching product data:', error));
        });
    }
});

 

 

View solution in original post

Replies 3 (3)

Digiteon
Excursionist
11 2 1

This is an accepted solution.

You can use JavaScript to listen for variant changes and trigger an event to update the app block. Here’s a concise solution:

 

Listen for Variant Changes:

 

Use Shopify's variantChange event to detect when a variant is selected. You can listen for this event using JavaScript.

 

Update the App Block:

 

When the variantChange event is triggered, update the product quantity in your app block accordingly.

Here’s a basic example of how you might achieve this:

 

 

// Function to update the app block with new quantity
function updateAppBlock(quantity) {
    // Assuming you have a method to update the app block
    const appBlockElement = document.getElementById('app-block'); // Replace with your actual app block ID or class
    appBlockElement.textContent = `Quantity: ${quantity}`;
}

// Listen for variant change event
document.addEventListener('DOMContentLoaded', () => {
    const variantSelect = document.querySelector('select[name="id"]'); // Replace with your variant selector
    if (variantSelect) {
        variantSelect.addEventListener('change', (event) => {
            const selectedVariantId = event.target.value;

            // Fetch variant details using Shopify’s AJAX API
            fetch(`/products/${window.productHandle}.js`)
                .then(response => response.json())
                .then(product => {
                    const selectedVariant = product.variants.find(variant => variant.id == selectedVariantId);
                    if (selectedVariant) {
                        updateAppBlock(selectedVariant.inventory_quantity);
                    }
                })
                .catch(error => console.error('Error fetching product data:', error));
        });
    }
});

 

 

Jatin_Jajra
Shopify Partner
3 0 3

 

<!-- product-template.liquid or a similar file -->
<style>
  .product-sells {
    text-align: center;
    font-size: 18px;
  }
</style>

<!-- Hidden input to store the current variant ID -->
<input type="hidden" id="variantId" value="{{ product.selected_or_first_available_variant.id }}">

<p id="salesCount" class="product-sells" data-product-id="{{ product.id }}" data-variant-id="{{ product.selected_or_first_available_variant.id }}"></p>

<script>
  document.addEventListener('DOMContentLoaded', () => {
    const salesCountDiv = document.getElementById("salesCount");
    const variantIdInput = document.getElementById("variantId");

    function fetchAndUpdateData(productId, variantId) {
      console.log("Fetching API data for app block with variant ID:", variantId);
      fetch(`https://node.webbytroops.net/app_block?shop=webbytroops-test-store.myshopify.com&productId=${productId}&variantId=${variantId}`)
        .then(response => response.json())
        .then(data => {
          if (data.show_widget) {
            salesCountDiv.innerHTML = `<strong>Inventory :</strong> ${data.quantity} <br> <strong class="sold">Sold items :</strong> ${data.sold_quantity}`;
          }
        })
        .catch(error => {
          console.error('Error fetching data:', error);
        });
    }

    function handleVariantChange(variant) {
      console.log("Variant changed", variant);
      if (variant && variant.id) {
        console.log("This is the new variant ID:", variant.id); // Log the new variant ID
        variantIdInput.value = variant.id; // Update the hidden input with the new variant ID
        fetchAndUpdateData(salesCountDiv.dataset.productId, variant.id);
      }
    }

    const initialProductId = salesCountDiv.dataset.productId;
    const initialVariantId = variantIdInput.value;
    fetchAndUpdateData(initialProductId, initialVariantId);

    // Listen for Shopify's variant change event
    document.addEventListener('variant:changed', (event) => {
      console.log("variant:changed event detected");
      const variant = event.detail.variant;
      handleVariantChange(variant);
    });

    // Fallback for older Shopify themes or custom implementations
    const variantSelects = document.querySelectorAll('select[name=
                                                     "id"]');
    variantSelects.forEach(select => {
      select.addEventListener('change', (event) => {
        const variantId = parseInt(event.target.value, 10);
        const variant = window.Shopify.product.variants.find(v => v.id === variantId);
        handleVariantChange(variant);
      });
    });

    // Fallback for older themes using radio buttons for variant selection
    const variantRadios = document.querySelectorAll('input[type="radio"][name="id"]');
    variantRadios.forEach(radio => {
      radio.addEventListener('change', (event) => {
        const variantId = parseInt(event.target.value, 10);
        const variant = window.Shopify.product.variants.find(v => v.id === variantId);
        handleVariantChange(variant);
      });
    });
  });
</script>

{% schema %}
{
  "name": "sales count",
  "target": "section",
  "settings": [
    { "type": "product", "id": "product", "label": "Product", "autofill": true },
    { "type": "color", "id": "colour", "label": "Star Colour", "default": "#ff0000" }
  ]
}
{% endschema %}

 

  I have created an app from node js in which I have created app block using theme app extension. This is my code of node js of app block.I want when the variant changes on the product detail page then this variant:changed code of mine should be run so that I can update the app block.

Joy33
Shopify Partner
5 0 0

Hello @Digiteon, Is that approach going to work no matter the theme?!