Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Combined total for multiple jQuery-UI Sliders

I'm trying to implement a page where there are 4 jQuery-UI sliders, and I want to make it so the combined total of all 4 sliders will never go over 400.

I don't mind which way this is implemented, it can be from a 0 start, and as soon as you change 1 slider, the remaining available total decreases or setting a slider past the maximum, decreases the values on the other sliders.

P.S. The sliders go in increments of 10.

All ideas & suggestions are welcome, and I've set up a jsFiddle if you'd like to test.

like image 953
Marko Avatar asked Aug 15 '10 05:08

Marko


3 Answers

Well here ya go:

var sliders = $("#sliders .slider");

sliders.each(function() {
    var value = parseInt($(this).text(), 10),
        availableTotal = 400;

    $(this).empty().slider({
        value: 0,
        min: 0,
        max: 400,
        range: "max",
        step: 10,
        slide: function(event, ui) {
            // Update display to current value
            $(this).siblings().text(ui.value);

            // Get current total
            var total = 0;

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });

            // Need to do this because apparently jQ UI
            // does not update value until this event completes
            total += ui.value;

            var max = availableTotal - total;

            // Update each slider
            sliders.not(this).each(function() {
                var t = $(this),
                    value = t.slider("option", "value");

                t.slider("option", "max", max + value)
                    .siblings().text(value + '/' + (max + value));
                t.slider('value', value);
            });
        }
    });
});

Here's a simple demo of this: http://jsfiddle.net/yijiang/Y5ZLL/4/

like image 114
Yi Jiang Avatar answered Nov 02 '22 17:11

Yi Jiang


Made an updated version of the above answer to show percentages of 100%. So as you adjust one slider up, the other two decrease making the percentage of each slider add up to 100%. Also made it easy to set initial values

JSfiddle

var sliders = $("#sliders .slider");
var availableTotal = 100;

sliders.each(function() {
    var init_value = parseInt($(this).text());

    $(this).siblings('.value').text(init_value);

    $(this).empty().slider({
        value: init_value,
        min: 0,
        max: availableTotal,
        range: "max",
        step: 2,
        animate: 0,
        slide: function(event, ui) {

            // Update display to current value
            $(this).siblings('.value').text(ui.value);

            // Get current total
            var total = 0;

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });

            // Need to do this because apparently jQ UI
            // does not update value until this event completes
            total += ui.value;

            var delta = availableTotal - total;

            // Update each slider
            sliders.not(this).each(function() {
                var t = $(this),
                    value = t.slider("option", "value");

                var new_value = value + (delta/2);

                if (new_value < 0 || ui.value == 100) 
                    new_value = 0;
                if (new_value > 100) 
                    new_value = 100;

                t.siblings('.value').text(new_value);
                t.slider('value', new_value);
            });
        }
    });
});
like image 35
Tony Avatar answered Nov 02 '22 16:11

Tony


I found when the other sliders (the ones other than the one you're moving) move around, it's distracting. I've also modified the Yi Jiang fiddle to now simply have it stop when you reach a total of 400. If you want that slider to go higher, you'll first have to lower one of the other ones much like how the first one, but it keeps the slider relative to the overall total.

This means that when you have one slider at 25% and another at 50%, they look like they are at 25 and 50 respectively.

JSfiddle

var sliders = $("#sliders .slider");

sliders.each(function() {
    var value = parseInt($(this).text(), 10),
        availableTotal = 400;

    $(this).empty().slider({
        value: 0,
        min: 0,
        max: 400,
        range: "max",
        step: 10,
        animate: 100,
        slide: function(event, ui) {

            // Get current total
            var total = 0;    

            sliders.not(this).each(function() {
                total += $(this).slider("option", "value");
            });    


            var max = availableTotal - total;            

            if (max - ui.value >= 0) {
                // Need to do this because apparently jQ UI
                // does not update value until this event completes
                total += ui.value;
                console.log(max-ui.value);
                $(this).siblings().text(ui.value);
            } else {
                return false;
            }
        }
    });
});
like image 7
Recognizer Avatar answered Nov 02 '22 17:11

Recognizer