Jquery Slider, How to Make "Step" Size Change

JQuery Slider, how to make step size change

Not sure if you want the slider scale to be in proportion to your values* but if so, I provided a solution to this for someone else who asked the same question. You can find my solution here. Basically I make use of the slide event that gets triggered when you move the slider to mimic the stepping, but based off a custom array defining the steps. This way it only allows you to "step" to your predefined values, even if they're not evenly spread.

*In other words if you want your slider to look like this:

|----|----|----|----|----|----|----|
0 10 20 100 1000 2000 10000 20000

then go with one of the other solutions here, but if you want your slider to look like this (diagram not to scale):

|--|--|-------|-----------|-----------|--------------------|--------------------|
0 10 20 100 1000 2000 10000 20000

Then the solution I linked to may be more what you're after.


Edit: Ok, this version of the script should work with dual sliders:

$(function() {
var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var slider = $("#price-range").slider({
orientation: 'horizontal',
range: true,
min: 0,
max: 1000000,
values: [0, 1000000],
slide: function(event, ui) {
var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
var includeRight = event.keyCode != $.ui.keyCode.LEFT;
var value = findNearest(includeLeft, includeRight, ui.value);
if (ui.value == ui.values[0]) {
slider.slider('values', 0, value);
}
else {
slider.slider('values', 1, value);
}
$("#price-amount").html('$' + slider.slider('values', 0) + ' - $' + slider.slider('values', 1));
return false;
},
change: function(event, ui) {
getHomeListings();
}
});
function findNearest(includeLeft, includeRight, value) {
var nearest = null;
var diff = null;
for (var i = 0; i < values.length; i++) {
if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
var newDiff = Math.abs(value - values[i]);
if (diff == null || newDiff < diff) {
nearest = values[i];
diff = newDiff;
}
}
}
return nearest;
}
});

Note that it looks a little funny down the far left end, since the jumps are so close together compared to the right hand end, but you can see its stepping as desired if you use your keyboard arrows to move the slider. Only way to get around that is to change your scale to not be quite so drastically exponential.


Edit 2:
Ok, if the spacing is too exaggerated when you use the true values, you could use a set of fake values for the slider & then look up the real value this corresponds to when you need to use the real value (in a similar way to what the other solutions here suggested). Here's the code:

$(function() {
var trueValues = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var values = [0, 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 25, 30, 40, 50, 60, 75, 100];
var slider = $("#price-range").slider({
orientation: 'horizontal',
range: true,
min: 0,
max: 100,
values: [0, 100],
slide: function(event, ui) {
var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
var includeRight = event.keyCode != $.ui.keyCode.LEFT;
var value = findNearest(includeLeft, includeRight, ui.value);
if (ui.value == ui.values[0]) {
slider.slider('values', 0, value);
}
else {
slider.slider('values', 1, value);
}
$("#price-amount").html('$' + getRealValue(slider.slider('values', 0)) + ' - $' + getRealValue(slider.slider('values', 1)));
return false;
},
change: function(event, ui) {
getHomeListings();
}
});
function findNearest(includeLeft, includeRight, value) {
var nearest = null;
var diff = null;
for (var i = 0; i < values.length; i++) {
if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
var newDiff = Math.abs(value - values[i]);
if (diff == null || newDiff < diff) {
nearest = values[i];
diff = newDiff;
}
}
}
return nearest;
}
function getRealValue(sliderValue) {
for (var i = 0; i < values.length; i++) {
if (values[i] >= sliderValue) {
return trueValues[i];
}
}
return 0;
}
});

You can fiddle with the numbers in the values array (which represent the slider stop points) until you get them spaced out how you want. This way you can make it feel, from the user's perspective, like it's sliding proportionally to the values, but without being as exaggerated. Obviously if your true values are dynamically created, you may need to come up with an algorithm to generate the slider values instead of statically defining them...

Slider, how to make “step” size change - JQuery

Use num.toPrecision(2) instead of toFixed to always get 2 significant digits. I updated your fiddle.

EDIT. To make numbers below 10, quite simply:

var _num = (num < 10) ? num.toPrecision(2) : Math.round(num)

(num < 10 instead of num < 1)

I updated your fiddle again.

jquery-ui-slider: wrong steps after “step” size change on run time

you can try with this

//stepping from 1 to 20  in steps of 1
if (ui.value < 20) {
$( this ).slider( "option", "min", 1 );
$(this).slider('option', 'step', 1);
}

//stepping from 20 to 100 in steps of 10
if (ui.value >= 20 && ui.value <= 100) {
$( this ).slider( "option", "min", 0 );
$(this).slider('option', 'step', 10);
}

I think it will work!

Jquery Slider UI dynamic step size

I suggest that you look at the slide event. Doc is here.
It says

Return false in order to prevent a slide, based on ui.value.

So you'll just have to return false when the value is not the one you're aiming.

Edit: Damn it, the link just got you to the slider page.
What I'm talking about is in the Events tab, and it's the one named slide

Edit2: a fiddle using it. The main difference with the other solution is that the sliding won't be uniform in this one.

Edit3: Another fiddle. In this one , if an incorrect value is reached at the end of the slide, it will go back to the previous correct value.

step size change

You could check the value on onSlide event and change the step property of the slider once its reached 36:

var $r = $('input[type=range]');
onSlide: function(position, value) {
if (v>=36) {
$r.data().plugin_rangeslider.step = 12;
}
else {
$r.data().plugin_rangeslider.step = 6;
}
}

Check this codepen

EDIT:

The values: min, max and value you should put as attributes on the html element and not while initializing. Also there is no slide function.
Look at this example (codepen)

$("#term").rangeslider({
polyfill: false,
onInit: function() {
$ruler[0].innerHTML = getRulerRange(this.min, this.max, rulerStep);
this.$range.prepend($ruler);},
onSlide: function(p,v) {
if (!$("#term").data().plugin_rangeslider)
return;
if (v>=36) {
$("#term").data().plugin_rangeslider.step = 12;
}
else {
$("#term").data().plugin_rangeslider.step = 6;
}
},
onSlideEnd: function(p, v) {
$('#val').attr('value', v)
}
});

jQuery UI Slider custom step increments and comma on load

What if you just manipulate the value in the slide event, like this:

$(function() {
$( "#slider" ).slider({
value:100,
min: 2501,
max: 50001,
step: 500,
slide: function (event, ui) {
var x = Number(ui.value);
if (x > 2501) {
x = x - (x % 500);
}
$("#LoanAmount").val('$' + addCommas(x));
}
});
$("#LoanAmount").val( '$' + addCommas($("#slider").slider("value") ) );

function addCommas(nStr)
{
nStr += '';
x = nStr.split('.');
x1 = x[0];
x2 = x.length > 1 ? '.' + x[1] : '';
var rgx = /(\d+)(\d{3})/;
while (rgx.test(x1)) {
x1 = x1.replace(rgx, '$1' + ',' + '$2');
}
return x1 + x2;
}
});

See this jsfiddle for an example: https://jsfiddle.net/bpursley/u1nLma3x/7/

Increase and decrease jQuery slider ui value by one step

There are some errors in your code like for instance the click events must be inside the document ready otherwise you need to use the document on event listener. What you are looking for is:

$(function () {  var sizes = ["10", "20", "30", "40", "50", "60", "70", "80", "90", "100", "200", "300", "400", "500", "1000"];  $("#slider-range-max").slider({    range: "max",    min: 0,    max: sizes.length - 1,    step: 1,    create: function(event, ui) {      $("#cap").val(sizes[0] + ' TB');    },    change: function (event, ui) {      $("#cap").val(sizes[ui.value] + ' TB');    }  });
$("#plus1").click(function () { var value = $("#slider-range-max").slider("value"); var step = $("#slider-range-max").slider("option", "step");
$("#slider-range-max").slider("value", value + step); });
$("#minus1").click(function () { var value = $("#slider-range-max").slider("value") var step = $("#slider-range-max").slider("option", "step");
$("#slider-range-max").slider("value", value - step); });});
.slider {  position: relative;  margin-top: 20px;  margin-bottom: 15px;  width: 90%;  background: #2A3137;  /* -moz-box-shadow: inset 0 0 10px #999;  -webkit-box-shadow: inset 0 0 10px #999;  box-shadow: inset 0 0 10px #999;*/  height: 15px;  border-radius: 10px;  border: 1px solid #DDDDDD;  margin-left: 15px;}
.slider .ui-slider-handle { position: absolute; background: #10A447; border-radius: 5px; width: 20px; height: 50px; top: -16px; left: 50px; border-style: none; box-shadow: none;
}
input[type=text] { border: 1px solid #10A447; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; padding: 5px 10px; margin-top: -15px; text-align: center; background-color: #ffffff; width: 120px; color: #2A3137; font-size: 18px; font-weight: bold; margin-top: 5px; margin-left: 5px;}
.minus, .plus { display: inline-block; float: left; border: 1px solid #aaa; -webkit-border-radius: 5px; -moz-border-radius: 5px; border-radius: 5px; padding: 5px 10px; margin-top: -15px; text-align: center; background-color: #e3e3e3; color: #333; font-size: 18px; font-weight: bold; margin-left: 5px; cursor: pointer; width: 10px; margin-top: 5px;}
<link href="http://code.jquery.com/ui/1.11.3/themes/smoothness/jquery-ui.css" rel="stylesheet"/><script src="http://code.jquery.com/jquery-1.11.3.min.js"></script><script src="http://code.jquery.com/ui/1.11.3/jquery-ui.js"></script>

<div id="quote-input" class="slider-input"> <div id="minus1" class="minus"><span>-</span></div> <div id="plus1" class="plus">+</div> <input type="text" id="cap" class="slider-value">

<div id="slider-range-max" class="slider"> <span class="ui-slider-handle"></span> </div></div>

How to set the Step of a jquerymobile slider dynamically based on slider value?

It's possible!!
Try this solution with your value or variable:

$("#slider-step").attr("min", 4);
$("#slider-step").attr("max", 40);
$("#slider-step").attr("step", 4);
$("#slider-step").val(4);
$('#slider-step').slider('refresh');

It works for me!!

JQuery Slider, how to make step size change

Not sure if you want the slider scale to be in proportion to your values* but if so, I provided a solution to this for someone else who asked the same question. You can find my solution here. Basically I make use of the slide event that gets triggered when you move the slider to mimic the stepping, but based off a custom array defining the steps. This way it only allows you to "step" to your predefined values, even if they're not evenly spread.

*In other words if you want your slider to look like this:

|----|----|----|----|----|----|----|
0 10 20 100 1000 2000 10000 20000

then go with one of the other solutions here, but if you want your slider to look like this (diagram not to scale):

|--|--|-------|-----------|-----------|--------------------|--------------------|
0 10 20 100 1000 2000 10000 20000

Then the solution I linked to may be more what you're after.


Edit: Ok, this version of the script should work with dual sliders:

$(function() {
var values = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var slider = $("#price-range").slider({
orientation: 'horizontal',
range: true,
min: 0,
max: 1000000,
values: [0, 1000000],
slide: function(event, ui) {
var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
var includeRight = event.keyCode != $.ui.keyCode.LEFT;
var value = findNearest(includeLeft, includeRight, ui.value);
if (ui.value == ui.values[0]) {
slider.slider('values', 0, value);
}
else {
slider.slider('values', 1, value);
}
$("#price-amount").html('$' + slider.slider('values', 0) + ' - $' + slider.slider('values', 1));
return false;
},
change: function(event, ui) {
getHomeListings();
}
});
function findNearest(includeLeft, includeRight, value) {
var nearest = null;
var diff = null;
for (var i = 0; i < values.length; i++) {
if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
var newDiff = Math.abs(value - values[i]);
if (diff == null || newDiff < diff) {
nearest = values[i];
diff = newDiff;
}
}
}
return nearest;
}
});

Note that it looks a little funny down the far left end, since the jumps are so close together compared to the right hand end, but you can see its stepping as desired if you use your keyboard arrows to move the slider. Only way to get around that is to change your scale to not be quite so drastically exponential.


Edit 2:
Ok, if the spacing is too exaggerated when you use the true values, you could use a set of fake values for the slider & then look up the real value this corresponds to when you need to use the real value (in a similar way to what the other solutions here suggested). Here's the code:

$(function() {
var trueValues = [0, 500, 750, 1000, 1250, 1500, 2000, 2500, 75000, 100000, 150000, 200000, 250000, 300000, 350000, 400000, 500000, 1000000];
var values = [0, 1, 2, 3, 4, 5, 6, 7, 10, 15, 20, 25, 30, 40, 50, 60, 75, 100];
var slider = $("#price-range").slider({
orientation: 'horizontal',
range: true,
min: 0,
max: 100,
values: [0, 100],
slide: function(event, ui) {
var includeLeft = event.keyCode != $.ui.keyCode.RIGHT;
var includeRight = event.keyCode != $.ui.keyCode.LEFT;
var value = findNearest(includeLeft, includeRight, ui.value);
if (ui.value == ui.values[0]) {
slider.slider('values', 0, value);
}
else {
slider.slider('values', 1, value);
}
$("#price-amount").html('$' + getRealValue(slider.slider('values', 0)) + ' - $' + getRealValue(slider.slider('values', 1)));
return false;
},
change: function(event, ui) {
getHomeListings();
}
});
function findNearest(includeLeft, includeRight, value) {
var nearest = null;
var diff = null;
for (var i = 0; i < values.length; i++) {
if ((includeLeft && values[i] <= value) || (includeRight && values[i] >= value)) {
var newDiff = Math.abs(value - values[i]);
if (diff == null || newDiff < diff) {
nearest = values[i];
diff = newDiff;
}
}
}
return nearest;
}
function getRealValue(sliderValue) {
for (var i = 0; i < values.length; i++) {
if (values[i] >= sliderValue) {
return trueValues[i];
}
}
return 0;
}
});

You can fiddle with the numbers in the values array (which represent the slider stop points) until you get them spaced out how you want. This way you can make it feel, from the user's perspective, like it's sliding proportionally to the values, but without being as exaggerated. Obviously if your true values are dynamically created, you may need to come up with an algorithm to generate the slider values instead of statically defining them...



Related Topics



Leave a reply



Submit