I am trying to create multiple slide bar with jquery ui slider. Problem is the value change in the last bar only when slide on the other bars. When slide on the other slide bar value change in the last bar only. Fiddle link
function collision($div1, $div2) {
var x1 = $div1.offset().left;
var w1 = 40;
var r1 = x1 + w1;
var x2 = $div2.offset().left;
var w2 = 40;
var r2 = x2 + w2;
if (r1 < x2 || x1 > r2) return false;
return true;
}
// // slider call
var search_type = ['id1','id2','id3','id4'];
for(var i = 0; i<search_type.length; i++){
var ids = '#' + search_type[i] + '-range';
var $this = '#'+search_type[i]+'-c';
console.log($this);
console.log(ids);
$(ids).slider({
range: true,
min: 0,
max: 500,
values: [ 75, 300 ],
slide: function(event, ui) {
$(ids +' .ui-slider-handle:eq(0) .price-range-min').html(ui.values[ 0 ]);
$(ids +' .ui-slider-handle:eq(1) .price-range-max').html( ui.values[ 1 ]);
$(ids +' .price-range-both').html('<i>' + ui.values[ 0 ] + ' - </i>' + ui.values[ 1 ] );
console.log(ids +' .ui-slider-handle:eq(1) .price-range-max');
//
if ( ui.values[0] == ui.values[1] ) {
$(ids+' .price-range-both i').css('display', 'none');
} else {
$(ids+' .price-range-both i').css('display', 'inline');
}
//
if (collision($('.price-range-min'), $('.price-range-max')) == true) {
$(ids +' .price-range-min,'+ ids+ ' .price-range-max').css('opacity', '0');
$(ids +' .price-range-both').css('display', 'block');
} else {
$(ids +' .price-range-min,'+ ids+ ' .price-range-max').css('opacity', '1');
$(ids +' .price-range-both').css('display', 'none');
}
}
});
$(ids +' .ui-slider-range').append('<span class="price-range-both value"><i>' + $(ids).slider('values', 0 ) + ' - </i>' + $(ids).slider('values', 1 ) + '</span>');
$(ids +' .ui-slider-handle:eq(0)').append('<span class="price-range-min value">' + $(ids).slider('values', 0 ) + '</span>');
$(ids +' .ui-slider-handle:eq(1)').append('<span class="price-range-max value">' + $(ids).slider('values', 1 ) + '</span>');
}
<br>
<input type="textbox" id="id1-min">
<input type="textbox" id="id1-max">
<p> </p>
<div id="id1-range"></div>
<p> </p>
<input type="textbox" id="id2-min">
<input type="textbox" id="id2-max">
<p> </p>
<div id="id2-range" data-max="800"></div>
<p> </p>
<input type="textbox" id="id3-min">
<input type="textbox" id="id3-max">
<p> </p>
<div id="id3-range" data-max="800"></div>
<p> </p>
<input type="textbox" id="id4-min">
<input type="textbox" id="id4-max">
<p> </p>
<div id="id4-range" data-max="800"></div>
The reason of such behavior is in
var
keyword. When you assign variableids
in afor
loop viavar
keyword it doesn't mean you createi
amount ofids
. No, sir. Actually you create one variableids
, which you reassign later in every iteration of your loop. This calls variable hoisting (and here is another article about it).Your
console.log
shows value ofids
variable on each iteration. But it doesn't mean that theslider
handler references to different values ofids
. No again. In this piece of code:$(ids + ' .ui-slider-handle:eq(0) .price-range-min')
-ids
references to one certain variable (one certain cell in RAM), which after all loop iterations contains'#id4-range'
string. So you will always update the last slider.You may ask: "why then all sliders created and not only the last one?". Thats because sliders are creating just once in each iteration. You set listeners on specific node and after that they will always be attached to that node.
So, how then you obtain needed behavior? One way is to simply use
let
keyword instead ofvar
when declaringids
. This is ES6 (you better read a lot about it, it's super handy), so you may encounter with browser incompatibility (babel will help you with this). Another (wrong, see comment below) way is to save full selector string paths in onearray
variable, or simply keep using already existingsearch_type
like so:Here is your example with a little modification (
let
insteadvar
beforeids
)EDIT:
If you want to deal with it without using
let
you should create functioncreateSlider
, for example. Which will do the following:Simply call this function in every iteration of the loop and pass
search_type[i]
as an argument like so: