Syncing Range Slider Handles Across Multiple Sliders

Hi Finsweet friends,

I’m working with range sliders and need to sync their handles and values. The sliders represent the same data (KW and BHP), so when I adjust one slider, the other should update accordingly.

I’ve already managed to update the input fields dynamically using custom script (thanks to ChatGPT), as you can see on this page: Marine Engines (I’ve temporarily unhidden the input fields for clarity).

Now, I need to make sure that when I drag one of the slider handles, the other slider’s handle also updates to match the correct position.

Does anyone have a solution or advice on how to achieve this? Any help would be greatly appreciated!

Thanks a lot,
Dorus

Hello @spreek! I could not see any script on the site, I managed to get this working reliably with the following code

<script>
  window.fsAttributes = window.fsAttributes || [];
  window.fsAttributes.push([
    'cmsfilter',
    (filterInstances) => {
      const slider1 = document.getElementById('kw-slider');
      const slider2 = document.getElementById('bhp-slider');

      function updateSlider(slider, valueFrom, valueTo) {
        const inputs = slider.querySelectorAll('input[fs-cmsfilter-range]');
        const handles = slider.querySelectorAll('[fs-rangeslider-element="handle"]');
        const fill = slider.querySelector('[fs-rangeslider-element="fill"]');

        const min = parseFloat(slider.getAttribute('fs-rangeslider-min'));
        const max = parseFloat(slider.getAttribute('fs-rangeslider-max'));

        inputs[0].value = valueFrom;
        inputs[1].value = valueTo;

        const fromPercentage = ((valueFrom - min) / (max - min)) * 100;
        const toPercentage = ((valueTo - min) / (max - min)) * 100;

        handles[0].style.left = `${fromPercentage}%`;
        handles[1].style.left = `${toPercentage}%`;

        if (fill) {
          fill.style.left = `${fromPercentage}%`;
          fill.style.width = `${toPercentage - fromPercentage}%`;
        }

        const displayValues = slider.querySelectorAll('[fs-rangeslider-element="display-value"]');
        if (displayValues.length > 0) {
          displayValues[0].textContent = valueFrom.toLocaleString();
          displayValues[1].textContent = valueTo.toLocaleString();
        }
      }

      function syncSliderChanges(sliderA, sliderB) {
        const inputsA = sliderA.querySelectorAll('input[fs-cmsfilter-range]');
        const inputsB = sliderB.querySelectorAll('input[fs-cmsfilter-range]');

        inputsA.forEach((input) =>
          input.addEventListener('input', () => {
            const valueFrom = parseFloat(inputsA[0].value);
            const valueTo = parseFloat(inputsA[1].value);
            updateSlider(sliderB, valueFrom, valueTo);
          })
        );

        inputsB.forEach((input) =>
          input.addEventListener('input', () => {
            const valueFrom = parseFloat(inputsB[0].value);
            const valueTo = parseFloat(inputsB[1].value);
          })
        );
      }

      syncSliderChanges(slider1, slider2);
      syncSliderChanges(slider2, slider1);

      window.fsAttributes.rangeslider.init();
    },
  ]);
</script>

There are some changes needed for this to work:

  1. Add the kw-slider and bhp-slider IDs to the sliders, do this to the element with fs-rangeslider-element="wrapper".
  2. Use this Range Slider script
<script
  defer
  fs-attributes-preventload="true"
  src="https://cdn.jsdelivr.net/npm/@finsweet/attributes-rangeslider@1/rangeslider.js"
></script>
  1. Ensure that the max and min values are the same for both sliders

Could you please test this and let me know how it works on your end?

Awesome!! This works thanks so much Luis!

I noticed that the maximum and minimum values need to be the same. Is there any way to make them different?

old site example: Marine engines

Hey, @spreek! I’ve been trying to replicate the behavior but I am afraid I have not been able to have the sliders behave as the example.

After digging for a bit I found that the example you’ve shown me is using this library → noUiSlider - JavaScript Range Slider | Refreshless.com

We could look into incorporating this with CMS Filter, let me know what you think!

Hi Luis, best whishes for 2025! Thanks for digging in and your support! It would be great if that could be incoporated. If it integrates well with CMS Filter, it’s definitely worth a try. Let me know if you foresee any challenges or if you need any input from my side.

Sure @spreek! If you could help me integrating the slider into your design, I can work on the code that will interact with CMS Filter.

Just let me know when the slider has been added and I will work on the code! :muscle:

Best wishes for 2025!

Hi @Support-Luis!

Apologies for my late response. A few projects and other matters came up on the client’s side, which put things on hold for a while. The NOUI slider has now been implemented. Could you please review the code to link them?

Lowest and highest KW value: 221 / 3580
Lowest and highest KW value: 296 / 4801

The values are currently set the same; otherwise, the sliders wouldn’t work. If you adjust them for this one, I should be able to apply the changes to the other pages as well. Many thanks for your help!

KW vs. BHP – Key Difference & Conversion Ratio:
Kilowatts (kW) and brake horsepower (BHP) are both units of power measurement for engines. kW is the standard metric unit, while BHP is a traditional imperial unit. The conversion ratio is:

1 kW ≈ 1.341 BHP

Since the values must stay in sync, any adjustment in one unit should be proportionally applied to the other to ensure consistent slider behavior.

Hey @Support-Luis any chance so look into the NoUI sliders? I would like to pay for the solution. Let me know your thougts on this.