Discuss and resolve questions on Liquid, JavaScript, themes, sales channels, and site speed enhancements.
Hello,
On the Shopify product page, I have different price variants, and I would like to be able to retrieve the price of the variant selected by the user.
How can I do that?
This is my code at the moment in main-product.liquid and I'm using Dawn theme:
The variable 'price' does not update correctly.
Thanks for support.
Alot of themes emit their own change event hunt for that and use it.
Try the code without the DOMContentLoaded in browser devtools console panel.
Ensure the element actually exists some themes do wonky things.
Ensure your selectors are targeting the correct element, either specific tag or that there are not multiples and your getting the wrong one. etc etc etc
Sight unseen the code seems fine but who knows what else is going on in your theme because you did not provide any inspectable urls so it will always be completed guessworkd for other people.
READ: https://community.shopify.com/c/blog/how-to-get-support-from-the-community/ba-p/2254458
Contact paull.newton+shopifyforum@gmail.com for the solutions you need
Save time & money ,Ask Questions The Smart Way
Problem Solved? ✔Accept and Like solutions to help future merchants
Answers powered by coffee Thank Paul with a ☕ Coffee for more answers or donate to eff.org
Thank you for the support. I'm adding more information about my issue.
<script>
document.addEventListener('DOMContentLoaded', function () {
function isIE() {
const ua = window.navigator.userAgent;
const msie = ua.indexOf('MSIE ');
const trident = ua.indexOf('Trident/');
return msie > 0 || trident > 0;
}
if (!isIE()) return;
const hiddenInput = document.querySelector('#{{ product_form_id }} input[name="id"]');
const noScriptInputWrapper = document.createElement('div');
const variantSwitcher =
document.querySelector('variant-radios[data-section="{{ section.id }}"]') ||
document.querySelector('variant-selects[data-section="{{ section.id }}"]');
noScriptInputWrapper.innerHTML = document.querySelector(
'.product-form__noscript-wrapper-{{ section.id }}'
).textContent;
variantSwitcher.outerHTML = noScriptInputWrapper.outerHTML;
document.querySelector('#Variants-{{ section.id }}').addEventListener('change', function (event) {
hiddenInput.value = event.currentTarget.value;
});
});
</script>
<script>
document.addEventListener('DOMContentLoaded', function () {
// Function to update the price dynamically
function updatePriceOnVariantChange() {
const variantSelect =
document.querySelector('variant-radios[data-section="{{ section.id }}"]') ||
document.querySelector('variant-selects[data-section="{{ section.id }}"]');
const dynamicPriceElement = document.querySelector("[data-pp-amount]");
// Listen for the change in variant selection
variantSelect.addEventListener("change", function () {
const price = {{ product.selected_variant.price | divided_by: 100.00 | json }};
console.log(price);
// Update the price in the data-pp-amount element
if (dynamicPriceElement) {
dynamicPriceElement.setAttribute("data-pp-amount", price);
}
});
}
// Call the function to initialize the price update
updatePriceOnVariantChange();
});
</script>
My site: https://www.luisjw.it/en/products/copia-del-cuore-anatomico-xl?variant=47226652590418
check out my solution above
Any luck on this? it looks like
I found the solution to this issue. It's a bit hacky, but since the product.variant is determined by the URL param `variant` we can use this the below method to to check url param changes (which will change on variant change)
<script>
document.addEventListener('DOMContentLoaded', function () {
let variants = {{ product.variants | json }};
let variantPriceDict = {};
variants.forEach(variant => {
variantPriceDict[variant.id] = variant.price;
});
console.log('Variant Price Dictionary:', variantPriceDict);
function getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(param);
}
function checkVariantPrice() {
const variantId = getQueryParam('variant');
if (variantId && variantPriceDict[variantId]) {
const price = variantPriceDict[variantId];
console.log(`Variant ID: ${variantId}, Price: ${price}`);
} else {
console.log('Variant not found or no variant parameter in URL.');
}
}
checkVariantPrice();
window.addEventListener('popstate', function () {
console.log('URL changed:', window.location.href);
checkVariantPrice();
});
const originalPushState = history.pushState;
history.pushState = function () {
originalPushState.apply(history, arguments);
checkVariantPrice();
};
const originalReplaceState = history.replaceState;
history.replaceState = function () {
originalReplaceState.apply(history, arguments);
checkVariantPrice();
};
});
</script>
using popstate to check for url param changes, we know when a user changes variants and can then use simple logic to match the param against the variant price dictionary created on page load. Not super heavy on client compute as well. It's not elegant but it works.
Thank you for your response @btromero
Here is my code, I want to show the selected variation price discount.
How to apply your solution for my code. Can you help please?
<div class="best-price-container">
<p class="best-price">
<span class="best-price-text">BEST PRICE:</span>
<span id="discounted-price-text">Rs.{{
product.price | divided_by: 100 | times: 0.80 | round }}</span>
</p>
</div>
@Chirag_Joshi the line console.log('my discounted price', discountedPrice); will display the discounted price for the selected variant.
add the below script to your code and check the console logs when you change variants
<script>
document.addEventListener('DOMContentLoaded', function () {
let variants = {{ product.variants | json }};
let variantPriceDict = {};
variants.forEach(variant => {
variantPriceDict[variant.id] = variant.price;
});
console.log('Variant Price Dictionary:', variantPriceDict);
function getQueryParam(param) {
const urlParams = new URLSearchParams(window.location.search);
return urlParams.get(param);
}
function updatePriceDisplay(price) {
const discountedPrice = (price / 100 * 0.80).toFixed(2);
console.log('my discounted price', discountedPrice);
const priceElement = document.getElementById('discounted-price-text');
if (priceElement) {
priceElement.innerText = `Rs.${discountedPrice}`;
}
}
function checkVariantPrice() {
const variantId = getQueryParam('variant');
if (variantId && variantPriceDict[variantId]) {
const price = variantPriceDict[variantId];
console.log(`Variant ID: ${variantId}, Price: ${price}`);
updatePriceDisplay(price);
} else {
console.log('Variant not found or no variant parameter in URL.');
}
}
checkVariantPrice();
window.addEventListener('popstate', function () {
console.log('URL changed:', window.location.href);
checkVariantPrice();
});
const originalPushState = history.pushState;
history.pushState = function () {
originalPushState.apply(history, arguments);
checkVariantPrice();
};
const originalReplaceState = history.replaceState;
history.replaceState = function () {
originalReplaceState.apply(history, arguments);
checkVariantPrice();
};
});
</script>
Its working like a charm. @btromero I don't know how to thank you. I really appreciate your help.
@btromero
When going to the product page, It calculates the discounts as per the lowest price first, so if the largest priced variation is selected by default it will show the discounted price of the lowest variation. When we select the other variations then it shows the proper prices. Can we fix it?
Also can we show the store currency here instead of Rs. : <span id="discounted-price-text">Rs.{{
product.price | divided_by: 100 | times: 0.80 | round }}</span>
Thank you,
@Chirag_Joshi I don't know much about currencies, so i don't know how to help there. To get around the issue with the pricing, you can set up 2 sets of logic.
domcontentload logic (when page first loads) use
By investing 30 minutes of your time, you can unlock the potential for increased sales,...
By Jacqui Sep 11, 2024We appreciate the diverse ways you participate in and engage with the Shopify Communi...
By JasonH Sep 9, 2024Thanks to everyone who participated in our AMA with 2H Media: Marketing Your Shopify St...
By Jacqui Sep 6, 2024