Jquery multiple sliders interconnected - javascript

I try to set 3 jquery ui slider interconnected, the sum of the 3 sliders must always stay at 100, so when I change the value for one slider, the others slider must be updated.
In exemple, if one slider have a value of 40 and I raise this value to 50, the two others slider have to decreased by 5.
Can anyone help me please?
thanks'

the probability of high value is 50 in any case... so set all the three sliders to 0 to 50... and their class as class="selector inactive"
$(".selector").slide(function(event, ui){
$(event.srcElement).removeClass('inactive');
var valuechange = 0;
$('.inactive').each(function(value, item){
// get sum of other two sliders
valuechange += $(item).slider( "option", "value");
});
// subtract sum(othertwo) + this value with 100 to get current changed value
valuechange = (valuechange + (ui.values[0])) - 100;
$('.inactive').each(function(value, item){
// add other sliders values to changedvalue / 2
$(item).slider( "option", "value", $(item).slider( "option", "value") + (( valuechange / 2) * -1));
});
$(event.srcElement).toggleClass('inactive');
});
hope this solved your problem

Related

jquery-ui slider bounded to select list using numbers greater then 100 strange behaviour

Probably most stupid question ever, but it is really annoying, the code compiles well and work great with range numbers 0 to 100, however, I cannot figure out why my slider control stop working when I use numbers greater than 100 ... I'm using simple jquery-ui sample
and all looks good, but soon as change numbers greater then 100 (due to our requirements we want to use it for years), the select list stop changing the dates and slider doesn't move ... Does it support numbers greater then 100 or there is some limitations ?! js code I'm using:
$(function() {
var select = $( "#minbeds" );
var slider = $( "<div id='slider'></div>" ).insertAfter( select ).slider({
min: 100,
max: 1000,
step: 100,
range: "min",
create: function( event, ui ) {
setSliderTicks(event.target);
},
value: select[ 0 ].selectedIndex + 1,
slide: function( event, ui ) {
select[ 0 ].selectedIndex = ui.value - 1;
}
});
$( "#minbeds" ).change(function() {
slider.slider( "value", this.selectedIndex + 1 );
});
});
function setSliderTicks(el) {
var $slider = $(el);
var max = $slider.slider("option", "max");
var min = $slider.slider("option", "min");
var spacing = 100 / (max - min);
$slider.find('.ui-slider-tick-mark').remove();
for (var i = 0; i < max-min ; i++) {
$('<span class="ui-slider-tick-mark"></span>').css('left', (spacing * i) + '%').appendTo($slider);
}
}
and here is HTML:
<form id="reservation">
<select name="minbeds" id="minbeds">
<option>100</option>
<option>200</option>
<option>300</option>
<option>400</option>
<option>500</option>
<option>600</option>
<option>700</option>
<option>800</option>
<option>900</option>
<option>1000</option>
</select>
</form>
And some CSS styles for tick-marks:
.ui-slider-tick-mark{
display:inline-block;
width:2px;
background:grey;
height:16px;
position:absolute;
top:-1px;
}
Can anyone please let me know, what is wrong with it, and in case if there are some limitations, can anyone recommend me some other library to use (open source), with the same functionality, taking input from html (select list) and with tick-marks/labels available ?! Any help appreciated ! Thank you.
The problem is that you simply copy pasted the example and expect it to work without understanding how it works even though you have a different requirement.
The demo is using selectedIndex property directly because the values are ranging from 1-6 and the slider steps by one. Your values and steps are different so if you want to find the option to select by index, you should divide the slider value by step value which is 100 and subtract 1 (since the options index is 0 based). Similarly if you want to set the slider value based on selected option index, you should increment it by 1 and multiply by 100.
Instead of doing all that you can simply use the selected options value and slider value directly like:
$(function() {
var select = $("#minbeds");
var slider = $("<div id='slider'></div>").insertAfter(select).slider({
min: 100,
max: 1000,
step: 100,
range: "min",
value: 100,
slide: function(event, ui) {
select.val(ui.value);
}
});
$("#minbeds").change(function() {
slider.slider("value", this.value);
});
});
<link href="//code.jquery.com/ui/1.11.4/themes/ui-lightness/jquery-ui.css" rel="stylesheet" />
<script src="https://ajax.googleapis.com/ajax/libs/jquery/2.1.1/jquery.min.js"></script>
<script src="//code.jquery.com/ui/1.11.4/jquery-ui.js"></script>
<form id="reservation">
<select name="minbeds" id="minbeds">
<option>100</option>
<option>200</option>
<option>300</option>
<option>400</option>
<option>500</option>
<option>600</option>
<option>700</option>
<option>800</option>
<option>900</option>
<option>1000</option>
</select>
</form>

jQuery Knob partially read only

I have a collection of jQuery knobs on my page that represent percentages. Each knob can have a value from 0-100, however, each subsequent knob should not have a value less than the previous knob. Essentially I want to make part of the knob read only - to prevent the user from dragging the value below the previous knob's value - similar to a 'min' value.
Example
Knob 1 25%
Knob 2 50% (min value still 0, max 100, but the value has to be greater than 25)
Knob 3 75%
Knob 4 100%
I have tried binding to the 'change' event on the knob, but that is not giving me what I want. Below I'm binding to the change event to try to limit the value - this is hard coded to test the simple use case. I am probably going to want to bind to the 'draw' event to limit the values on animation but haven't got that far.
$(this).trigger('configure', {
'change': function (v) {
console.log("Updating value " + v);
if(v < 25) {
console.log("Updating value");
this.cv = 25;
}
}
});
Not sure if this is the best way to do it, but you can manipulate the angleOffset and angleArc options of the dial based on the value of the previous one. For example, if you have two dials:
HTML
<input type="text" value="75" id="dial1">
<input type="text" value="75" id="dial2">
Your javascript would be something like this:
$(function () {
$("#dial1").knob({
'change': function (v) {
$('#dial2')
.trigger(
'configure', {
'angleOffset': (v / 100 * 360),
'angleArc': ((100-v) / 100 * 360),
'min': v,
});
}
});
$("#dial2").knob();
});
As for the empty space left in the dial, you can fix that by setting the canvas background to an image of a full knob.
CSS
canvas {
background: url('http://imgur.com/aeTBhL9.png');
}
Here's a jsFiddle example.

jQuery Mobile slider snap?

I've spent the better past of 2 hours trying out random code from different sources that claim they've managed to snap the slider to particular points. I'm not sure if this is feasible with the jQuery Mobile library, since the jQuery UI version does support it, but i'm really needing to figure something out for a current project.
Essentially I have a timeline with different dates. They're not in "steps", like 10's or 20's, they're different numbers. Something like 1, 3, 10, 12, 32. I need the slider to snap at those points.
Currently, I have something that's testing the step attr only.
$('#slider-1').live( "change", function(e) {
var step = $(this).attr('step'),
val = $(this).val();
if(step % val == step || val == step){
console.log(val)
}
});
The issue i'm having with the slider, not only the snapping, is when i slide anywhere near 20 or 40 or 60 etc, i'm getting console logs. It's not logging ON 20 etc.
Figured it out after many iterations of code and reading the documentation for specific events I can bind.
So essentially I had a timeline of numbers in my array that looks something like:
-0--10--20-----70--100---150---200---250---300---350---400-----500----------------1000
I needed to snap to the nearest number depending on the position of the slider-handle. I did this by testing the current value when the slider was being moved against the closest number in the array. I would then dynamically change the sliders value and would then have to do a force refresh of the slider to see the change.
$(function() {
/*
Array of values between 0 - 1000 (can be any set of numbers you want to snap to,
but you must make sure the 'max' attribute on the input element is <= the last
value in the array)
*/
var values = [0, 10, 20, 70, 100, 150, 200, 250, 300, 350, 400, 500, 1000],
/*
A way for us to check the current and previous values of the slider so we only
call doSomething() if these are different. This way the function isn't called twice. These should NOT have the same values on init.
*/
currentVal = 0,
prevVal = null,
// Assign our slider to a variable so we're not hitting the dom repeatedly.
$slider = $("#slider-1");
/*
After each change of our input value, we assign the slider value to the nearest number
in our array for our "snap" effect
*/
$($slider).bind("change", function(){
$($slider).val(findNearest($($slider).val()))
});
/*
We must capture click events on the slider itself if the user doesn't drag the handle.
*/
$(".ui-slider[role=application]").bind("vclick",function(){
$($slider).slider('refresh');
})
/*
jQuery creates new dom elements for us, which in the case of the handle, is an anchor element.
Use mouseup method to test on the computer, otherwise touchend method for mobile devices.
*/
$("a.ui-slider-handle").touchend(function(){
// If our currentVal hasn't changed after a snap action, do nothing, otherwise call doSomething()
if(currentVal != prevVal) {
prevVal = currentVal;
doSomething();
}
// Force slider refresh for visible snap effect
$($slider).slider('refresh');
})
// Used to iterate over our array and check for nearest value to what is passed in
function findNearest(goal) {
var closest = null;
$.each(values, function(){
if (closest == null || Math.abs(this - goal) < Math.abs(closest - goal)) {
closest = this;
}
});
return currentVal = Number(closest);
}
function doSomething(){
...
}
});
And my HTML:
<label for="slider-1" id="slider_label_1">Input slider:</label>
<input type="range" name="slider-1" id="slider-1" value="0" min="0" max="1000" step="10" />

Presenting indicators and milestone labels for ui slider bar

Using HTML & JavaScript
I created a slide bar which successfully responds both ways with a select option.
However i have choosen to 'hide' the select option box. I was wondering if anyone could give me any tips on creating labels for the slider bar as the user now has no idea what they are selecting. Examples i have found show perfect indicators, milestone numbers and floating numbers when hovering over yet everything is slide bar related and rather than labels. Help!
My JavaScript Slider Bar Code
$(function() {
var select = $( "#logbytes");
var slider = $( " <div id='slider'></div>").insertAfter(select).slider({
min: 1,
max: 6,
step: 1,
value: select[0].selectedIndex + 1,
slide: function(event, ui) {
select[0].selectedIndex = ui.value - 1;
}
});
$('#logbytes').after(slider).hide();
});
The basic idea is to wrap your slider inside a wrapper div. Then to add another div inside the wrapper. Its text will be the current value of the slider.
And then the only thing left to do is to move that div around and to update it's text. It's something like:
slide: function(event, ui) {
$( ".amount" ).text( ui.value );
$( ".amount" ).css("margin-left",(ui.value-min)/(max-min)*100+"%");
}
Where min and max are the min and max of your slider.
See http://jsfiddle.net/WYdLF/ for an example.

jQuery UI: smooth slider with one snap (to default value)?

I'd like to make a slider that snaps to the center while retaining smooth action elsewhere. Something like a jQuery version of a real-life speaker balance slider. Is it possible?
Or should I just create my own slider with a draggable object, constricted to one axis with containing it frame, snapping to another object (or grid) positioned in the center of the frame?
Edit: I simply need a slider that allows values e.g. from -10 to -1, 0, and 1 to 10 (between -1 and 1 snap to 0) with step: 0.1
You should be able to use the jQuery slider, but restrict its motion with the slide event:
jSlider.slider({
// other options...
slide: function (event, ui) {
if (ui.value > -1 && ui.value < 1 && ui.value != 0) {
// force it to 0 between -1 and 1.
jSlider.slider('value', 0);
return false;
}
return true;
}
});
Hmmm...so this is what I'm envisioning in my head...A background that slides on a timer like a carousel (maybe these are big images), with a row of thumbnails on top that slides smooth. That what you want to build?
EDIT: Here's what you need to do:
I rarely find the need to use jQuery plugins. Here is what you need:
Mousedown (on the slider). api.jquery.com/mousedown/. There is a callback on mouse down an on release.
Track mouse position inside the slider container while you're dragging the slider docs.jquery.com/Tutorials:Mouse_Position
Use the animate function to move the slider while your mouse still hasn't been released api.jquery.com/animate/ Stop animate on release.
When your slider gets to a certain x position in it's container, force the "smooth" function - ie a different animate function.
Use the following so that your jquery slider automatically snaps to the nearest in the step. The trick is to implement your own step-interval-slider. The problem is, if your max and min are separated by a small distance (for e.g. 5-10) your slide will behave in steps because the default step=1, so you need to compute your step based on that. If your max-min values are separated by a huge distance (e.g. 1-1000 or more) you can leave the computed_step calculation and initialize it to 1.
max_limit = 30;
min_limit = 5;
stick_to_steps_of = 5;
var computed_step = max_term/100; //you can vary the denominator to make it smoother
$("#my_slider" ).slider({
animate : true,
value: max_limit,
min: min_limit,
max: max_limit,
step: computed_step,
stop: function( event, ui ) {
d = parseInt(parseInt(ui.value)/stick_to_steps_of);
rem = parseInt(ui.value)%stick_to_steps_of;
var fval = 0;
if (rem <= parseInt(stick_to_steps_of/2)) {
fval = d*stick_to_steps_of;
}else{
fval = (d+1)*stick_to_steps_of;
}
$("#my_slider").slider('option', 'value', fval);
$('#myslider_current_value').html(fval); //some placeholder to show the current value
}
});

Categories

Resources