I contain a slider which uses an input range the current numbers are
12, 24, 36, 48, 60
I need to add the ability to contain
24, 36, 48, 60, 120
<input type="range" data-id='slider1RangePicker' name="range"
class="form-range slider range" min="24" max="120" step="12"
id="slider1">
<ul class="range-labels">
<li class="active selected">24</li>
<li>36</li>
<li>48</li>
<li>60</li>
<li>120</li>
</ul>
previously I would set the min as 12 max as 60 and then a step of 12 which allows it to range correctly.
However with adding 120 and removing 24 and setting the min max accordingly the step number no longer works because of the 60-120 jump.
How would I solve this?
You should have a contiguous range from 0..max. You no longer have a linear axis, it it essentially a category axis now.
You can use JavaScript to synchronize the labels to the slider like so:
Note: To get the current value, you can use getSlider($rangeSlider).dataset.value
.
const $rangeSlider = document.querySelector('.range-slider');
// Handle slider change
$rangeSlider.addEventListener('change', (e) => {
syncRangeSlider(e.currentTarget);
});
// Handle label click
$rangeSlider.addEventListener('click', (e) => {
if (e.target.tagName === 'LI') {
getSlider(e.currentTarget).value = getElementIndex(e.target);
}
syncRangeSlider(e.currentTarget);
});
// Initial sync
syncRangeSlider($rangeSlider);
function syncRangeSlider(rangeSliderEl) {
const slider = getSlider(rangeSliderEl);
const index = slider.valueAsNumber;
let labelValue;
getLabels(rangeSliderEl).forEach((label, currIndex) => {
const isActive = currIndex === index;
if (isActive) {
labelValue = +label.textContent;
}
toggleLabelActive(label, isActive);
});
slider.dataset.value = labelValue;
}
function toggleLabelActive(label, active) {
label.classList.toggle('active', active);
label.classList.toggle('selected', active);
}
function getSlider(rangeSliderEl) {
return rangeSliderEl.querySelector('.slider.range');
}
function getLabels(rangeSliderEl) {
return rangeSliderEl.querySelectorAll('.range-labels li');
}
function getElementIndex(element) {
return Array.prototype.indexOf.call(element.parentNode.children, element);
}
html, body {
width: 100%;
height: 100%;
margin: 0;
padding: 0;
}
body {
display: flex;
align-items: center;
justify-content: center;
}
.range-slider {
display: flex;
flex-direction: column;
gap: 0.5rem;
padding: 0.5rem;
border: thin solid #AAA;
border-radius: 0.5rem;
background: #EEE;
}
.range-slider .slider.range {
margin: 0 0.5rem;
}
.range-slider .range-labels {
display: flex;
gap: 0.25rem;
margin: 0;
padding: 0;
list-style-type: none;
}
.range-slider .range-labels li {
display: flex;
align-items: center;
justify-content: center;
margin: 0;
padding: 0;
border: thin solid #CCC;
background: #F7F7F7;
border-radius: 50%;
min-width: 2rem;
aspect-ratio: 1 / 1;
cursor: pointer;
user-select: none;
}
.range-slider .range-labels li.active.selected {
background: #FFA;
}
<div class="range-slider">
<input
type="range"
id="slider1"
name="range"
class="form-range slider range"
data-id="slider1RangePicker"
min="0"
max="4"
value="1"
data-value="24" />
<ul class="range-labels">
<li class="active selected">24</li>
<li>36</li>
<li>48</li>
<li>60</li>
<li>120</li>
</ul>
</div>