Reputation: 1145
I want to have step from 1 to max and if <=1 , range should have step value of 0.1, I used .prop method and other logic.
This is my full code
$(document).on("input change", ".slider", function() {
var val = $(this).val();
var isdeci = $(this).data("isdeci");
changeSlide(val, isdeci, $(this));
// saveSettings(val, name);
});
function changeSlide(val, isdeci, elem) {
if (isdeci) {
if (val < 1) {
elem.prop("step", 0.1);
elem.prop("min", 0.1);
} else {
elem.prop("step", 1);
if (val % 1 != 0 && val > 1) {
val = parseInt(val);
elem.val(val);
}
}
}
elem.parent().next().find(".outvalue").text(val);
}
//1.plus mins
$(document).on('click', '.icon-plus', function() {
plusminus($(this), "plus");
});
$(document).on('click', '.icon-minus', function() {
plusminus($(this), "minus");
});
function plusminus(elem, type) {
var parent = elem.parent().prev().find("input");
let isdeci = parent.data('isdeci');
let max = parent.prop('max');
let min = parent.prop('min');
let valx = parent.val();
let step = parent.attr('step');
if (type == "plus") {
val = parseFloat(step) + parseFloat(valx);
} else {
val = parseFloat(valx) - parseFloat(step);
}
if (val < 0.1) {
val = 0.1;
}
if (val >= 1 && val % 1 == 0) {
val = parseInt(val);
}
parent.val(val);
changeSlide(val, isdeci, parent);
}
Here I am calling changeSlide, when plus minus is clicked or range slider is moved.
<div class="section">
<span class="one">sl : </span>
<span class="two"><input data-isdeci="1" class="slider" id="sl" type="range" value="4" min="0.1" max="201" step="0.1" /> </span>
<span class="icon-minus"></span>
<span data-type="SL" data-lot="1" class="editquantity outvalue">0.2</span>
<span class="icon-plus"></span>
It works fine for plus button, but for minus button, it skips from 1 to 0.1. Is this the correct way or is there an easier range function?
Upvotes: 1
Views: 2602
Reputation: 23396
The jump occurs because you haven't changed step
according to the direction when the slider is at value 1 (you check (val < 1)
only). And yes, there's an easier way, something like the example below.
In the example I've decreased the range of the slider to 5, that way it's easier to see the decimal values when dragging the slider, it'll work with the maximum value of 201 too. Also, due to how min
attribute value affects on the actual value of the input together with step
value, step
is set to 0.1 from the beginning, and new slider values are forcibly calculated instead of changing the step value of the element.
const buttonWrapper = document.body.querySelector('#buttons'),
slider = document.body.querySelector('#rangeSlider'),
output = document.body.querySelector('.outvalue');
updateOutput(+slider.value);
function updateOutput(text) {
output.textContent = text.toFixed(1);
}
function updateSlider(e) {
let val = +slider.value;
if (e.type === 'click') {
if (!e.target.matches('[data-dir]')) {return;} // Quit, not clicked on +/- button
let dir = +e.target.getAttribute('data-dir'),
step = (val < 1 || (val === 1 && dir < 0)) ? 0.1 : 1;
val = val + step * dir;
}
let newValue = (val > 1) ? Math.round(val) : val;
slider.value = newValue;
updateOutput(+slider.value);
}
buttonWrapper.addEventListener('click', updateSlider);
slider.addEventListener('input', updateSlider);
.outvalue {
display: inline-block;
width: 40px;
border: 1px solid #000;
margin: 5px;
padding: 2px;
text-align: right;
}
<input type='range' min='0.1' max='5' value='2' step="0.1" id='rangeSlider' class='slider' />
<div id="buttons">
<button data-dir='-1' class='prev'>-</button>
<span class="outvalue"></span>
<button data-dir='1' class='next'>+</button>
</div>
Notice how step
is conditionally defined when clicking a button. When the slider gets to 1 from the right side ((val === 1 && dir < 0)
passes), you've to reduce step
too, otherwise newValue
jumps to 0.1 directly.
If you're going to use newValue
somewhere else in your code, you've to limit the values to fit to the range, the view value in the example is limited by the input element only, the JS value is not limited.
The example is written with vanilla JS, but as you seem to use jQuery, you can use this "translated" example.
Upvotes: 1