This script works great as a stock countdown, but I couldn't show it in more than 1 place on the same page.
For example, on the same page there are 4 or 5 products/plans and each product shows a different stock quantity and changing the quantity at different times from each other. Only shows on 1 product.
<span class="qty" id="qty"></span>
<script>
const setQty = (qty) => {
qtySpan.innerHTML = qty;
if (qty == 0) return;
let parts = Math.floor((Math.random() * 3) + 1);
if (parts > qty) parts = qty;
const msec = Math.floor(((Math.random() * 15) + 15) * 1000);
qty -= parts;
// Save the updated quantity in localStorage
localStorage.setItem('saved_countdown', qty);
setTimeout(() => setQty(qty), msec);
}
// Get the saved countdown value from localStorage, or use default value of 57 if not found
const defaultQty = localStorage.getItem('saved_countdown') ?? 57;
const qtySpan = document.getElementById('qty');
// Set the initial value of the quantity
setQty(defaultQty);
</script>
I duplicated the script 4x changing the ID "qty" by qty1, qty2, qty3 and qty4, but it didn't work, it keeps showing only in 1 product... :/
Would anyone here be able to help me out? Thank you!
I've modified your script into a Custom Element. This means that you can now create an element called <stock-counter>
.
This element has 2 attributes, quantity
and storage-key
.
quantity
is the amount to start counting from.storage-key
is the name of the Local Storage key that is used to store the last quantity of this specific counter. If a storage key is set and a stored value has been found, then this value will supersede the quanitity
value, unless the stored value is 0
.So the element would look like this:
<stock-counter quantity="40" storage-key="countdown-one">40</stock-counter>
You can place as many of these elements on your page and modify the quantity
and storage-key
for each one.
customElements.define('stock-counter', class extends HTMLElement {
get quantity() {
// Check if value has been stored.
if (this.storageKey !== null) {
const value = Number(localStorage.getItem(this.storageKey));
// Use that value if it is a valid number and not 0.
if (!Number.isNaN(value) && value !== 0) {
return value;
}
}
// Otherwise get the value from the quantity attribute.
const value = Number(this.getAttribute('quantity'));
if (Number.isNaN(value)) {
return 0;
}
return value;
}
set quantity(value) {
if (!isNaN(value)) {
// Store the new value if it's possible.
if (this.storageKey !== null) {
localStorage.setItem(this.storageKey, value);
}
// Set the new attribute value.
this.setAttribute('quantity', value);
}
}
get storageKey() {
return this.getAttribute('storage-key');
}
connectedCallback() {
this.count();
}
count = () => {
const qty = this.quantity;
this.textContent = qty;
if (qty === 0) {
return;
}
let parts = Math.floor((Math.random() * 3) + 1);
if (parts > qty) {
parts = qty;
}
this.quantity -= parts;
const msec = Math.floor(((Math.random() * 15) + 15) * 1000);
setTimeout(this.count, msec);
};
});
<stock-counter quantity="40" storage-key="countdown-one">40</stock-counter>
<stock-counter quantity="50">50</stock-counter>
<stock-counter quantity="80" storage-key="countdown-three">80</stock-counter>