I have a UISlider I implemented with JQuery UI
. I want to add a legend under the slider showing the numbers. I followed this answer which showed how to implement that, placing then numbers with percentage values. This way when the sliders size changes, (ex. browser gets resized,) the numbers are still at the correct places.
That works fine and well, but if the browsers window is small, or if there are a lot of numbers for the slider, then the legend number get too close to each other.
Question:
How can I delete a number if they are 'x' amount too close.
Here is what I tried doing:
if (i !== 0) {
var prevLegendNum_offsetLeft = $('#legendNum' + i).closest('.sliderLegend').find('.sliderLegendNum').offset().left
var distance = $('#legendNum' + i).offset().left - prevLegendNum_offsetLeft;
console.log(distance); // Logs: 0
if (distance <= 35) {
$('#legendNum' + i).remove();
}
}
The reason why I had to do the whole thing with prevLegendNum_offsetLeft
, and not just $('#legendNum' + (i - 1))
is because, if there are 3 numbers that are less than the distance of 35 away from each other, so 2 numbers behind i
will be deleted. It will then try to access $('#legendNum' + (i - 1)
, but that won't be there, so it will return an error.
When I run the code above, it deletes all numbers besides for the first one.
$("#slider").slider({
value: 4,
min: 1,
max: 15,
step: 1
})
.each(function() {
var opt = $(this).data().uiSlider.options;
var vals = opt.max - opt.min;
for (var i = 0; i <= vals; i++) {
var el = $('<div class="sliderLegend"><div class="sliderLegendMark">|</div><div class="sliderLegendNum" id="legendNum' + i + '">' + (i + 2) + '</div></div>').css('left', (i / vals * 100) + '%');
$('#slider').append(el);
if (i !== 0) {
var prevLegendNum_offsetLeft = $('#legendNum' + i).closest('.sliderLegend').find('.sliderLegendNum').offset().left
var distance = $('#legendNum' + i).offset().left - prevLegendNum_offsetLeft;
console.log(distance);
if (distance <= 35) {
$('#legendNum' + i).remove();
}
}
}
});
#slider > div {
position: absolute;
width: 20px;
margin-left: -10px;
text-align: center;
margin-top: 20px;
}
/* below is not necessary, just for style */
#slider {
width: 50%;
margin: 2em auto;
}
<script src="http://code.jquery.com/jquery-1.10.2.js"></script>
<script src="http://code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<link rel="stylesheet" href="http://code.jquery.com/ui/1.11.4/themes/smoothness/jquery-ui.css">
<div id="slider"></div>
You could iterate over all the
.sliderLegend
elements (except the first one), and compare the element's left position with the closest previous element's right position.If the right side of the closest previous element is greater than the left side of the current element, then you know that they overlap, and you can remove the element you are currently iterating over.
In the example below, the condition is
left < prevRight + 6
, so there is a6px
buffer. Just adjust that number accordingly to how much space you want between the numbers.Updated Example
In addition, part of the problem you were encountering was that all the children
div
elements had a fixed width of20px
. Due to this, you couldn't accurately calculate the offset left position of the element because the text would overflow. To work around this, I removed the fixed width and addedtransform: translateX(-50%)
in order to center the elements horizontally.Updated Example
A range of 1-50 would now generate the following:
A range of 1-100 would generate the following:
Additionally, if you would like to remove the lines as well, remove the entire element rather than just the number: