Hi, I sell an olive oil with 2 variants. My product page shows the price of 1 bottle of each variant. I want to increase the price on the product page when I increase the quantity that I want to buy. Say I click on +1 I want the price to be increased by 1 bottle and show the total amount. Is that possible before I add it to the shopping cart?
Topic summary
A Shopify store owner selling olive oil with two variants wants to dynamically update the product price on the page as customers adjust the quantity selector, showing the total cost before adding items to the cart.
Solution Approach:
- Modify the
price.liquidfile to add adata-priceattribute storing the base price - Implement JavaScript to listen for quantity changes and recalculate the displayed price in real-time
- Include variant price data as JSON in a
data-variant-pricesattribute to handle multiple product variants
Key Challenge:
The initial implementation only multiplied the price of one variant (small bottle) regardless of which variant was selected. This required updating the code to track variant selection.
Technical Details:
- The store uses radio buttons (not dropdowns) for variant selection
- Prices use European formatting (comma for decimals, EUR currency)
- Solution involves parsing variant data from JSON and updating price based on both selected variant and quantity
- Event listeners monitor both quantity input changes and variant radio button selections
Current Status:
The developer provided updated code specifically for radio button variant selectors. Implementation involves modifying price.liquid and adding JavaScript to handle dynamic price calculations. The conversation remains ongoing as the store owner works through implementation details.
Hi @felufit ,
Yes, it’s absolutely possible to update the price dynamically on the product page when the quantity is adjusted, even before adding the product to the cart. You can achieve this with a small customization to your theme using Liquid and JavaScript. Here’s how you can do it:
Steps to Implement:1. Locate Your Product Template:
Go to your Shopify admin, navigate to Online Store > Themes > Actions > Edit Code, and find the file where the product details are rendered (product.liquid or product-template.liquid).
- Update the Price Display:
Wrap the price section in a div or span for easier dynamic updates:
{{ product.price | money }}
- Ensure There’s a Quantity Selector:
Make sure there’s a quantity input field on the product page:
- Add JavaScript for Dynamic Updates:
In your theme.js file or directly on the product page, add the following script:
document.addEventListener("DOMContentLoaded", function () {
const quantityInput = document.getElementById("quantity");
const priceElement = document.getElementById("product-price");
const basePrice = parseFloat(priceElement.getAttribute("data-price")); // Base price of 1 bottle
if (quantityInput && priceElement) {
quantityInput.addEventListener("input", function () {
const quantity = parseInt(quantityInput.value) || 1; // Default to 1 if empty
const newPrice = (basePrice * quantity).toFixed(2); // Calculate new price
priceElement.textContent = `$${newPrice}`; // Update price display
});
}
});
- Save and Test:
Save your changes and test the functionality. The price should now dynamically adjust based on the quantity selected.
This approach ensures your product page reflects the total cost as the customer adjusts the quantity. It’s user-friendly and helps customers make quicker purchase decisions.
If you’re comfortable, we can do this for you! Please share your collaborator code in a DM, and we’ll set it up for you free of charge.
Let me know if you have any questions!
Best regards,
Shubham | Untechnickle
Hi Shubham, I tried to do what you wrote but I can’t find the area where to change things. I only have a main-product.liquid and I can’t find product-prices nor money_without_currency in my code. Is there maybe another liquid where I need to search? I’m using the DAWN 15.2 if that helps
Hey @felufit ,
That’d work. You can do these price related changes in the price.liquid file. Please create a copy of theme and add it there. Once everything works fine, then you can publish the theme.
Update price.liquid to Include a Dynamic Price Attribute
Locate the section of the code where the price-item class is used to display the price. Add a data-price attribute to store the base price.
For example:
{{ money_price }}
Also, as for the Javascript please use this updated code:
document.addEventListener("DOMContentLoaded", function() {
const productForm = document.querySelector('.product-form');
if (!productForm) return;
productForm.delegate('change', '#quantity', function(event) {
const quantity = Math.max(1, parseInt(event.target.value) || 1);
const basePrice = window.Shopify.currency.rate * parseFloat(
document.getElementById("product-price").dataset.price
);
const newPrice = basePrice * quantity;
const formattedPrice = window.Shopify.formatMoney(
newPrice,
window.Shopify.money_format
);
document.getElementById("product-price").innerHTML = formattedPrice;
});
});
I hope this helps.
Thanks,
Shubham
Ok so I just added this code and it kind of works. However, I have 2 variants of the olive oil and the script always multiplies the price of the small bottle even if I choose the big bottle. This is my current javascript. Do I have to adjust something in my liquid?
Got it! Let’s add variant information to the price template and then update the JS.
{{ money_price }}
Updated JS:
document.addEventListener('DOMContentLoaded', function() {
const quantityInput = document.getElementById('Quantity-{{ section.id }}');
const priceElement = document.getElementById('price-{{ section.id }}');
const variantSelect = document.querySelector('select[name="id"], input[name="id"]');
// Parse variant data from the data attribute
const variantPrices = JSON.parse(priceElement.getAttribute('data-variant-prices'));
function updatePrice() {
// Get current variant
const currentVariantId = variantSelect.value;
const currentVariant = variantPrices.find(v => v.id.toString() === currentVariantId.toString());
if (!currentVariant) {
console.error('Variant not found:', currentVariantId);
return;
}
// Get quantity
const quantity = parseInt(quantityInput.value) || 1;
// Calculate total price using the current variant's price
const variantPrice = currentVariant.price / 100; // Convert cents to euros
const totalPrice = variantPrice * quantity;
// Update price display with European formatting
priceElement.textContent = `€${totalPrice.toFixed(2).replace('.', ',')} EUR`;
}
// Add event listeners for both quantity changes and variant changes
quantityInput.addEventListener('change', updatePrice);
variantSelect.addEventListener('change', updatePrice);
// Initial price update
updatePrice();
});
If you’re using radio buttons or other variant selectors instead of a dropdown, you might need to adjust the selector. Let me know if you need help with that or if you’re using a different variant selection method.
This should work, feel free to reach out if you come across any hiccup.
Thanks,
Shubham |. Untechnickle
P.S Do checkout Revize below, sometime later. We’re looking for feedbacks, honest and brutal. Thank you!
Thank you. Indeed Im using buttons and not dropdowns for the variant. also, where do I have to implement the HTML code? In the main-product.liquid or price liquid?
Ps: I will check out revize!
This needs to be updated in price.liquid; just like we did before as this is an updated version of previous code given. Overwrite the previous code.
{{ money_price }}
Here’s the improved JS for radio buttons:
document.addEventListener('DOMContentLoaded', function() {
const quantityInput = document.getElementById('Quantity-{{ section.id }}');
const priceElement = document.getElementById('price-{{ section.id }}');
// Select all radio inputs for variants
const variantRadios = document.querySelectorAll('input[type="radio"][name="id"]');
// Parse variant data from the price element
const variantPrices = JSON.parse(priceElement.getAttribute('data-variant-prices'));
function updatePrice() {
// Find the selected radio button
const selectedVariant = document.querySelector('input[type="radio"][name="id"]:checked');
if (!selectedVariant) return;
const currentVariantId = selectedVariant.value;
const currentVariant = variantPrices.find(v => v.id.toString() === currentVariantId.toString());
if (!currentVariant) {
console.error('Variant not found:', currentVariantId);
return;
}
// Get quantity
const quantity = parseInt(quantityInput.value) || 1;
// Calculate total price using the current variant's price
const variantPrice = currentVariant.price / 100; // Convert cents to euros
const totalPrice = variantPrice * quantity;
// Update price display with European formatting
priceElement.textContent = `€${totalPrice.toFixed(2).replace('.', ',')} EUR`;
}
// Add event listeners for quantity changes
quantityInput.addEventListener('change', updatePrice);
// Add event listeners for all radio buttons
variantRadios.forEach(radio => {
radio.addEventListener('change', updatePrice);
});
// Initial price update
updatePrice();
});
This should do that magic ![]()
~ SV