Skip to main content

Example : Create a slider filter instead of checkboxes

JS Code:

<script>
// Updates the track position based on the thumbs' positions.
function updateTrack(track, thumbMin, thumbMax) {
track.style.left = `${thumbMin.offsetLeft}px`;
track.style.width = `${thumbMax.offsetLeft - thumbMin.offsetLeft}px`;
}


// Moves the thumbs and updates the selected range values.
function moveThumb(event, thumb, slider, thumbMin, thumbMax, outputMin, outputMax, minRange, maxRange, filterElement, filterName) {
const sliderRect = slider.getBoundingClientRect();
const position = Math.max(0, Math.min(event.clientX - sliderRect.left, slider.offsetWidth));

if (thumb === thumbMin && position < thumbMax.offsetLeft) {
thumb.style.left = `${position}px`;
outputMin.textContent = `${(minRange + (position / slider.offsetWidth) * (maxRange - minRange)).toFixed(2)}mm`;
} else if (thumb === thumbMax && position > thumbMin.offsetLeft) {
thumb.style.left = `${position}px`;
outputMax.textContent = `${(minRange + (position / slider.offsetWidth) * (maxRange - minRange)).toFixed(2)}mm`;
}

updateTrack(filterElement.querySelector('.track'), thumbMin, thumbMax);
applyFilter(outputMin, outputMax, filterElement, filterName);
}


// Applies the filter based on slider values.
function applyFilter(outputMin, outputMax, filterElement, filterName) {
const minVal = parseFloat(outputMin.textContent);
const maxVal = parseFloat(outputMax.textContent);
const checkboxes = filterElement.querySelectorAll('.fs-checkbox input');

checkboxes.forEach((checkboxElement) => {
const value = parseFloat(checkboxElement.closest('.fs-checkbox').querySelector('.fs-serp-filter-text').textContent.replace('mm', ''));
checkboxElement.checked = value >= minVal && value <= maxVal;
});

// Dispatches an event to update Fast Simon filtering
document.dispatchEvent(new CustomEvent('send-fast-simon-params', {
detail: { narrow: { [filterName]: new Set([...Array.from(checkboxes)]
.map(checkboxElement => checkboxElement.checked ? checkboxElement.closest('.fs-checkbox').querySelector('.fs-serp-filter-text').textContent.trim() : null)
.filter(filteredValue => filteredValue)) }}}));
}


// Creates the slider filter inside the filter element.
function createSlider(filterElement, minRange, maxRange, filterName) {
if (filterElement.classList.contains("cstm-slider")) return; // Prevent duplicate sliders
filterElement.classList.add("cstm-slider");

const sliderContainer = document.createElement('div');
sliderContainer.classList.add('slider-container');

const slider = document.createElement('div');
slider.classList.add('slider');

const track = document.createElement('div');
track.classList.add('track');
slider.appendChild(track);

const thumbMin = document.createElement('div');
thumbMin.classList.add('thumb');
thumbMin.id = 'thumbMin';

const thumbMax = document.createElement('div');
thumbMax.classList.add('thumb');
thumbMax.id = 'thumbMax';

slider.appendChild(thumbMin);
slider.appendChild(thumbMax);
sliderContainer.appendChild(slider);

const outputContainer = document.createElement('div');
outputContainer.classList.add('output-container');

const outputMin = document.createElement('span');
outputMin.id = 'outputMin';
outputMin.textContent = `${minRange}mm`;

const outputMax = document.createElement('span');
outputMax.id = 'outputMax';
outputMax.textContent = `${maxRange}mm`;

outputContainer.appendChild(outputMin);
outputContainer.appendChild(outputMax);
sliderContainer.appendChild(outputContainer);

if (!filterElement.querySelector('.slider-container')) {
filterElement.appendChild(sliderContainer);
}

const moveThumbHandler = (event) => moveThumb(event, event.target, slider, thumbMin, thumbMax, outputMin, outputMax, minRange, maxRange, filterElement, filterName);

thumbMin.addEventListener('mousedown', () => document.addEventListener('mousemove', moveThumbHandler));
thumbMax.addEventListener('mousedown', () => document.addEventListener('mousemove', moveThumbHandler));
document.addEventListener('mouseup', () => document.removeEventListener('mousemove', moveThumbHandler));

updateTrack(track, thumbMin, thumbMax);
}


// Sets up the slider filters when the filters are updated.
function setupFilters() {
window.SerpOptions.registerHook('serp-filters', ({ facets, element }) => {
const targetFilters = ['fs_filter_head height', 'fs_filter_height', 'fs_filter_thickness', 'fs_filter_outside diameter', 'fs_filter_head diameter', 'fs_filter_flange diameter'];

targetFilters.forEach((filterID) => {
const filterElement = element.querySelector(`[id="${filterID}"]`);
if (filterElement) {
const filterValues = Array.from(filterElement.querySelectorAll('.fs-serp-filter-text')).map(el => parseFloat(el.textContent.trim()));
if (filterValues.length > 0) {
createSlider(filterElement, Math.min(...filterValues), Math.max(...filterValues), filterID.replace('fs_filter_', ''));
}
}
});
});
}


// Ensures the filter setup is executed when Fast Simon is ready.
if (window.SerpOptions) {
setupFilters();
} else {
window.addEventListener('fast-serp-ready', setupFilters);
}
//end for Vnext
</script>

Result

image