Shopify themes, liquid, logos, and UX
Hello Shopify Community,
I hope you're all doing well. I'm currently working on my Shopify store and have encountered a challenge that I could use some assistance with.
I have some code on my product page inside a liquid code block that displays the price of the selected variant. Here's the code for reference:
Code 1 (single liquid, price only):
<div id="variant-test-price1"> {{ product.selected_variant.price | money }} </div>
Code 2 (variant title and price):
<div id="variant-test-price2"> {{ product.selected_variant.title }} - {{ product.selected_variant.price | money }} </div>
The liquid works on page load. What I'm trying to achieve is to make this code update dynamically using Ajax without having to manually refresh the page, similar to how the regular pricing updates when I switch between product variants. This is crucial for me to understand for further development purposes. However, I'm not very familiar with JavaScript, and I'm struggling to create a functional script for this purpose alone.
As far as I understand from the documentation, the pricing is fetched from /product/{{product.handle}}.js.
I wonder if this even works with my code above to be updated when a variant is switched. I'm using the regular variant radio pill element on the product page.
If anyone has experience with implementing dynamic updates for liquid code on Shopify product pages, especially when switching between variants, I would greatly appreciate your guidance and expertise.
Please share a script with me that can be used with the above code to help me understand how Shopify updates liquid with Ajax.
Thanks in advance.
Solved! Go to the solution
This is an accepted solution.
Hi @Constantine00 ,
Hope you are doing well.
Please use the below js code which help you to change the price through the AJAX call.
document.addEventListener('DOMContentLoaded', function() {
var variantSelector = document.getElementById('variant-selector');
var priceDisplay = document.getElementById('product-price');
var initialVariant = variantSelector.options[variantSelector.selectedIndex];
var initialPrice = parseFloat(initialVariant.getAttribute('data-price'));
priceDisplay.textContent = '$' + initialPrice.toFixed(2)
variantSelector.addEventListener('change', function() {
var variantId = variantSelector.value;
var selectedOption = variantSelector.options[variantSelector.selectedIndex];
var newPrice = parseFloat(selectedOption.getAttribute('data-price'));
fetch('/products/' + {{ product.handle }} + '.js')
.then(function(response) {
return response.json();
})
.then(function(productData) {
var selectedVariant = productData.variants.find(function(variant) {
return variant.id == variantId;
});
priceDisplay.textContent = '$' + selectedVariant.price.toFixed(2);
})
.catch(function(error) {
console.error('Error fetching product data: ', error);
});
});
});
Please use your own ID attribute and class as per your HTML structure.
This is an accepted solution.
Hi @Constantine00 ,
Hope you are doing well.
Please use the below js code which help you to change the price through the AJAX call.
document.addEventListener('DOMContentLoaded', function() {
var variantSelector = document.getElementById('variant-selector');
var priceDisplay = document.getElementById('product-price');
var initialVariant = variantSelector.options[variantSelector.selectedIndex];
var initialPrice = parseFloat(initialVariant.getAttribute('data-price'));
priceDisplay.textContent = '$' + initialPrice.toFixed(2)
variantSelector.addEventListener('change', function() {
var variantId = variantSelector.value;
var selectedOption = variantSelector.options[variantSelector.selectedIndex];
var newPrice = parseFloat(selectedOption.getAttribute('data-price'));
fetch('/products/' + {{ product.handle }} + '.js')
.then(function(response) {
return response.json();
})
.then(function(productData) {
var selectedVariant = productData.variants.find(function(variant) {
return variant.id == variantId;
});
priceDisplay.textContent = '$' + selectedVariant.price.toFixed(2);
})
.catch(function(error) {
console.error('Error fetching product data: ', error);
});
});
});
Please use your own ID attribute and class as per your HTML structure.
Thank you for your quick response.
I've implemented the JavaScript code you provided inside the custom liquid, ensuring that I updated the IDs to match my setup. For "Code 1," I used the ID "variant-test-price1" for 'variant-selector' and I selected the picker with the ID "variant-radios-template--15595519115401__main" for 'product-price'.
However, it appears that the script doesn't work in my case. The liquid content within "variant-test-price1" remains static when I select different variants using the variant picker. To clarify my goal, In this case I want, "variant-test-price1" to dynamically update with the correct value and currency using an Ajax script, not the pricing underneath the product title.
Regarding the currency symbol ('$') used in the script, how would it would work if multiple currencies are enabled in the shop. Is there a way to make it currency-agnostic? Right now I use "€" EUR.
As for "Code 2," it contains two liquid values within it. Will this work as is, or do I need to restructure the HTML?
The variant picker has this rendered html on my store:
<variant-radios id="variant-radios-template--15595519115401__main" class="no-js-hidden" data-section="template--15595519115401__main" data-url="/products/soap"><fieldset class="js product-form__input">
To trigger a change event, I'm using the ID "variant-radios-template--15595519115401__main". Is this the correct approach in my case?
I included some images and my test store for reference, the password is: 123
https://teststore-9992.myshopify.com/products/soap?variant=41417412182153
Images:
https://imgur.com/a/z5PxovO
Currently, both Code 1 and Code 2 only display values when a variant is selected and the page is reloaded.
Thank you once again for your assistance.
I meant, for "Code 1," I used the ID "variant-test-price1" for 'product-price' and I selected the picker with the ID "variant-radios-template--15595519115401__main" for 'variant-selector'.
Figured it out, had to make some changes.
cool, That's good
Hello!
I'm trying to adapt this solution, to my problem, but I'm lost when it comes to JS.
I need to update the Add to Cart button label, based on the variant that customers choose on the product page.
Since the page updates every time the variant changes, I thought that this solution might be close to what I need.
In my buy-buttons.liquid file, I've modified the span to output different labels for a button, depending on variant condition:
<span>
{%- if product.selected_or_first_available_variant.available == false or quantity_rule_soldout -%}
{{ 'products.product.sold_out' | t }}
{%- else -%}
{% if product.selected_or_first_available_variant.inventory_policy == 'continue' and product.selected_or_first_available_variant.inventory_quantity < 1 %}
{{ 'products.product.preorder' | t }}
{%- else -%}
{{ 'products.product.add_to_cart' | t }}
{%- endif -%}
{%- endif -%}
</span>
It's working, but only on the page load and it doesn't work when variant is changed.
Could you please help me adapt your solution to this issue?
Thank you!
Nevermind, I figured it out! Thank you.
Hi @Constantine00
I tried the above solutions and Its not working for me. Can you help?
As 2024 wraps up, the dropshipping landscape is already shifting towards 2025's trends....
By JasonH Nov 27, 2024Hey Community! It’s time to share some appreciation and celebrate what we have accomplis...
By JasonH Nov 14, 2024In today’s interview, we sat down with @BSS-Commerce to discuss practical strategies f...
By JasonH Nov 13, 2024