Filtering doing something weird

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 :thinking: - 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>

I have the same problem it looks like if you have multiple checkboxes with different filters family it does that.

Did you find a solution ?

Well I just found out, each family of checkboxes need to have the same “Name”

Not sure if same ID aswell.

It worked for me and I had the same issue as yours

Hi @juanpablo, thanks for answering. In fact, I have all my checkboxes called “Checkbox” … so I don’t understand why the issue persists…

Hi @Simon_De_Ridder!

@juanpablo is right!

Make sure that all the radio buttons in the same group, or all the checkboxes in the same group, have the same name .
For radios, it is displayed in the Webflow settings panel as Group Name , for checkboxes, it is displayed as Name .And no other form element should have that same name if it’s not part of the radios/checkbox group.

For example, on your page, only the checkboxes under the Ownership category should have the name “Ownership”, while those under the Type of property category should be named “Type of property”, and so on for each respective category.

Hi Pedro,

I see, I misunderstood. I thought I had to name all the checkboxes the same. It’s a bit confusing in the doc… So now this issue is solved :slight_smile:

And regarding the “hidden” listings that were adding up after clicking on the “clear” buttons. It’s because some listings had a higher maximum than the price slider or land size slider.

Should be good now!
Thank you!

Thanks for the feedback, we will update the docs! :flexed_biceps: