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
varkeyword. When you assign variableidsin aforloop viavarkeyword it doesn't mean you createiamount 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.logshows value ofidsvariable on each iteration. But it doesn't mean that thesliderhandler references to different values ofids. No again. In this piece of code:$(ids + ' .ui-slider-handle:eq(0) .price-range-min')-idsreferences 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
letkeyword instead ofvarwhen 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 onearrayvariable, or simply keep using already existingsearch_typelike so:Here is your example with a little modification (
letinsteadvarbeforeids)EDIT:
If you want to deal with it without using
letyou 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: