Hi all,
I’ve setup the attributes v2 on my client’s website but we noticed some weird stuff happening.
First of all, here’s the view only Webflow link:
You’ll need to go on the “all listings” page.
Here’s a quick video showing the different problems that we encounter:
Issues with Thinsuite Attribute Filtering and CMS Results - Watch Video
Lastly,
my friend created a script to handle the price conversion between Monto and the price slider:
<script>
window.addEventListener("load", async () => {
let isResettingPrice = false
function getCookieValue(name) {
const regex = new RegExp(`(^| )${name}=([^;]+)`);
const match = document.cookie.match(regex);
if (match) {
return match[2];
}
}
// window.currentSelectedMoney
const montoCookie = getCookieValue("MONTO_CURRENT_CURRENCY") || "IDR";
let currentCurrency = montoCookie;
let currencyRate = 1;
// Define min and max slider values
const MIN_SLIDER_VALUE = 0;
const MAX_SLIDER_VALUE = 118950000000; // IDR
const currenciesWithSymbol = [
{
currency: "IDR",
symbol: "Rp"
},
{
currency: "EUR",
symbol: "€"
},
{
currency: "USD",
symbol: "$"
},
{
currency: "AUD",
symbol: "A$"
}
];
const priceWrapper = document.querySelector("#price-slider-wrapper");
const currencySpan = priceWrapper.querySelector("#currency");
const sliderWrapper = priceWrapper.querySelector(".rangeslider_wrap");
const leftHandle = sliderWrapper.querySelector("#left-handle");
const rightHandle = sliderWrapper.querySelector("#right-handle");
const sliderTextsWrapper = sliderWrapper.querySelector(".values_wrap");
const clearPricings = document.querySelectorAll(".clear-pricing_wrap");
const leftHandleText = sliderTextsWrapper.children[0];
const rightHandleText = sliderTextsWrapper.children[1];
function hideTextHandleIfOn() {
if (leftHandle.style.display !== "none") {
leftHandleText.style.display = "none";
}
if (rightHandleText.style.display !== "none") {
rightHandleText.style.display = "none";
}
}
let newLeftMoneyLabelDiv = null;
let newRightMoneyLabelDiv = null;
function insertTextNodeIfNeeded() {
newLeftMoneyLabelDiv = sliderTextsWrapper.querySelector("#newLeftMoneyLabelDiv");
if (!newLeftMoneyLabelDiv) {
newLeftMoneyLabelDiv = document.createElement("div");
newLeftMoneyLabelDiv.setAttribute("id", "newLeftMoneyLabelDiv");
sliderTextsWrapper.append(newLeftMoneyLabelDiv);
}
newRightMoneyLabelDiv = sliderTextsWrapper.querySelector("#newRightMoneyLabelDiv");
if (!newRightMoneyLabelDiv) {
newRightMoneyLabelDiv = document.createElement("div");
newRightMoneyLabelDiv.setAttribute("id", "newRightMoneyLabelDiv");
sliderTextsWrapper.append(newRightMoneyLabelDiv);
}
}
function insertMoneyText(target, value) {
const roundedValue = Math.round(value * currencyRate);
if (currentCurrency === "IDR") {
const idrFormatter = new Intl.NumberFormat("id-ID", {
notation: "compact",
compactDisplay: "short",
currency: "IDR",
style: "currency"
});
target.innerHTML = idrFormatter.format(roundedValue);
} else {
const normalFormatter = new Intl.NumberFormat("en-US", {
currency: currentCurrency,
style: "currency",
minimumFractionDigits: 0,
maximumFractionDigits: 0
});
target.innerHTML = normalFormatter.format(roundedValue);
}
}
function getAriaValueNow() {
return {
left: leftHandle.getAttribute("aria-valuenow"),
right: rightHandle.getAttribute("aria-valuenow")
};
}
// Updated renderMoneyTextNode function with min/max parameters
function renderMoneyTextNode(min, max) {
console.log('max', max)
const { left, right } = getAriaValueNow();
const _min = Number(min || left);
const _max = Number(max || right);
insertMoneyText(newLeftMoneyLabelDiv, _min);
insertMoneyText(newRightMoneyLabelDiv, _max);
}
function updateCurrencySymbol(element) {
const selectedSymbol = currenciesWithSymbol.find(
(currency) => currency.currency === currentCurrency
).symbol;
element.innerHTML = `(${selectedSymbol})` || "";
}
// ✅ Initialize UI first
hideTextHandleIfOn();
insertTextNodeIfNeeded();
updateCurrencySymbol(currencySpan);
// ✅ Fetch exchange rate on page load if currency is not IDR, then update DOM
if (currentCurrency !== "IDR") {
try {
const { rate } = await fetch(
`https://api.monto.io/shops/AGr6Wab0l8QK9LxNv1RqOYKg/curconv/rate?currency=${currentCurrency}`
).then((res) => res.json());
currencyRate = rate;
// ✅ Update DOM after fetching the rate
renderMoneyTextNode();
} catch (error) {
console.error("Failed to fetch currency rate:", error);
// Fallback to IDR if rate fetch fails
currentCurrency = "IDR";
currencyRate = 1;
updateCurrencySymbol(currencySpan);
renderMoneyTextNode();
}
} else {
// ✅ For IDR, render immediately since rate is already 1
renderMoneyTextNode();
}
// ✅ Add click event listeners to all clear-pricing_wrap elements
clearPricings.forEach((clearPricing) => {
clearPricing.addEventListener("click", async () => {
console.log('debugger ??')
if(isResettingPrice)return
try {
isResettingPrice = true
// Fetch current exchange rate if needed
const { rate } = await fetch(
`https://api.monto.io/shops/AGr6Wab0l8QK9LxNv1RqOYKg/curconv/rate?currency=${currentCurrency}`
).then((res) => res.json());
currencyRate = rate;
renderMoneyTextNode(MIN_SLIDER_VALUE, MAX_SLIDER_VALUE);
console.log(`Slider reset to range: ${convertedMin} - ${convertedMax} ${currentCurrency}`);
} catch (error) {
console.error("Failed to reset pricing:", error);
}finally{
isResettingPrice = false
}
});
});
const currencyButtons = document.querySelectorAll("[data-monto-set-currency]");
currencyButtons.forEach((button) => {
button.addEventListener("click", async () => {
console.log('currencyButtons')
const selectedCurrency = button.getAttribute("data-monto-set-currency");
currentCurrency = selectedCurrency;
const { rate } = await fetch(
`https://api.monto.io/shops/AGr6Wab0l8QK9LxNv1RqOYKg/curconv/rate?currency=${selectedCurrency}`
).then((res) => res.json());
currencyRate = rate;
hideTextHandleIfOn();
insertTextNodeIfNeeded();
updateCurrencySymbol(currencySpan);
renderMoneyTextNode();
});
});
let isDragging = false;
function startDragging() {
isDragging = true;
hideTextHandleIfOn();
insertTextNodeIfNeeded();
updateCurrencySymbol(currencySpan);
renderMoneyTextNode();
}
function duringDragging() {
if (isDragging) {
hideTextHandleIfOn();
insertTextNodeIfNeeded();
renderMoneyTextNode();
}
}
function stopDragging() {
isDragging = false;
}
sliderWrapper.addEventListener("mousedown", startDragging);
sliderWrapper.addEventListener("mousemove", duringDragging);
sliderWrapper.addEventListener("mouseup", stopDragging);
// ✅ Add touch support
sliderWrapper.addEventListener("touchstart", startDragging, { passive: true });
sliderWrapper.addEventListener("touchmove", duringDragging, { passive: true });
sliderWrapper.addEventListener("touchend", stopDragging);
});
</script>