1

I have a multi-value jQuery slider with a defined step (it is defined by another slider, lets pretend for example's sake that it is a step:15) and a range of say 0-600. I want users to be able to drag the two values to the left and right like usual. But if a click is performed inside of the two values, they should be able to drag the whole range left and right.

A user is forced to set values like the following:

0,600
15,120
240,255
150,150

When, I want a user to be able to set values like the following:

1,271
15,165
25,115
580,595

These numbers still follow the step:15 rule of the slider, but can't be accessed with the basics of a jQuery slider because it wants to snap values to 30 increments (0,15,30,..,585,600). The most intuitive way I can think of this to be done is letting a user drag their 'range' of values left and right. But when the slider is clicked in between the two values, jQuery sets this as a new value.

I have used the slider's start event to detect if a user is clicking within the range (instead of clicking on a handle or the un-selected portion of the slider). I then need to set some sort of slide function within the slider that constantly detects the mouse position and slides left and right like that. I am at an intermediate level of Javascript (in my opinion) and not quite sure how I would go about doing that. You can play with my JSFiddle: http://jsfiddle.net/JhKxh/9/

*note: the only problem with my JSFiddle is if you click the slider's border, it doesn't count as the class ui-slider-range (but some CSS tweaking should be able to fix this).

Sam
  • 20,096
  • 2
  • 45
  • 71
  • make jsfiddle and provide some, code, what you already tried ? – zb' Oct 09 '12 at 02:35
  • @eicto JSFiddle provided. I don't really have an idea of where to start, but I have all of the slider skeleton made. (this is a very simplified version of what I have). – Sam Oct 09 '12 at 02:58

2 Answers2

1

your answer should be here

Drag the Range of a UI Input Range Slider

Community
  • 1
  • 1
zb'
  • 8,071
  • 4
  • 41
  • 68
  • I might not be understanding the answer, but I think you misunderstood the question. Yes, I want a user to be able to pick any specific values. I want a user to be able to slide the range back and forth. So if he has selected [30,150], he will be able to slide this range from [0,120] all the way to [480,600] and everything in between by dragging the slider. – Sam Oct 09 '12 at 04:09
  • not understand that part, where to select 30,150 and where to slide 0,120 - 480,600.... – zb' Oct 09 '12 at 04:18
  • I want a user to be able to select two values using the handles. Lets say they are [30,150]. Then the user can click on the gray range and slide the bar left and right to get a more specific range..say [29,149] or [33,153]. They could not however, select [30,151] if the step was set to 30 with the first slider (because that range is not a multiple of the step). – Sam Oct 09 '12 at 04:33
  • Thank you so much this is exactly what I was looking for (my searches found nothing). I will update my JSFiddle in the morning with the final answer for my implementation. – Sam Oct 09 '12 at 04:57
  • also it would be good if you fix the code on github to be able to work with jquery>1.6 (not sure why it isn't compatible with 1.7.2) – zb' Oct 09 '12 at 05:01
0

Look here:

http://docs.jquery.com/UI/API/1.8/Slider

The following code works well and is an extension of your original jsfiddle. I finally understood what you wanted and it seems to work fine now:

Live Working Code Sample

JavaScript:

$(document).ready(function () {
    'use strict';

    var stepSlider = $('#stepSlider');
    var stepText = $('#stepText');
    var rangeSlider = $('#rangeSlider');
    var rangeText = $('#rangeText');
    var oldStep;

    stepSlider.slider({
        min:0,
        max:120,
        slide:function (event, ui) {
            stepText.text(ui.value);

            var rsValues = rangeSlider.slider("option", "values");
            var stepDiff = ui.value - oldStep;
            var rsMax = rangeSlider.slider("option", "max");
            var rsMin = rangeSlider.slider("option", "min");
            if (stepDiff > 0) {
                rsValues[1] += stepDiff;
                if (rsValues[1] > rsMax) {
                    rsValues[0] = rsMax - ui.value;
                    rsValues[1] = rsMax;
                }
            } else if (stepDiff < 0) {
                rsValues[1] += stepDiff;
                if (rsValues[1] < rsMin) {
                    rsValues[0] = rsMin;
                    rsValues[1] = ui.value;
                }
            }
            rangeSlider.slider("option", "values", rsValues);
            rangeText.text(rsValues[0] + ' - ' + rsValues[1]);
            oldStep = ui.value;
        }
    });

    rangeSlider.slider({
        min:0,
        max:600,
        values:[0, 0],
        slide:function (event, ui) {
            var step = stepSlider.slider("option", "value");
            var oldValues = rangeSlider.slider("option", "values");
            var rsMax = rangeSlider.slider("option", "max");
            var rsMin = rangeSlider.slider("option", "min");
            var diff;

            if (oldValues[0] != ui.values[0]) {
                diff = ui.values[0] - oldValues[0];
                if (diff > 0 && diff <= step && ui.values[1] === rsMax) {
                    return false;
                }
                ui.values[1] += diff;
                if (ui.values[1] > rsMax) {
                    ui.values[1] = rsMax;
                    ui.values[0] = ui.values[1] - step;
                }
                rangeSlider.slider("option", "values", ui.values);
                rangeText.text(ui.values[0] + ' - ' + ui.values[1]);
                return false;
            }
            if (oldValues[1] != ui.values[1]) {
                diff = ui.values[1] - oldValues[1];
                if (diff < 0 && diff >= -step && ui.values[0] === rsMin) {
                    return false;
                }
                ui.values[0] += diff;
                if (ui.values[0] < rsMin) {
                    ui.values[0] = rsMin;
                    ui.values[1] = ui.values[0] + step;
                }
                rangeSlider.slider("option", "values", ui.values);
                rangeText.text(ui.values[0] + ' - ' + ui.values[1]);
                return false;
            }
            rangeText.text(ui.values[0] + ' - ' + ui.values[1]);
        }
    });
    oldStep = stepSlider.slider("option", "value");
});

HTML:

<!DOCTYPE html>
<html>
    <head>
        <title>Sliders</title>
        <link href="rangeSliders.css" rel="stylesheet" type="text/css"/>
        <link href="http://code.jquery.com/ui/1.9.0/themes/base/jquery-ui.css" rel="stylesheet" type="text/css"/>
        <script src="http://code.jquery.com/jquery-1.8.2.js"></script>
        <script src="http://code.jquery.com/ui/1.9.0/jquery-ui.js"></script>
    </head>
    <body>
        <div id="stepSlider">
            <div id="stepText">0</div>
        </div>

        <div id="rangeSlider">
            <div id="rangeText">0-600</div>
        </div>
        <script type="text/javascript" src="rangeSliders.js"></script>
    </body>
</html>

CSS:

body {
    margin: 50px;
}

#stepSlider, #rangeSlider {
    width: 200px;
    margin-bottom: 25px;
}

#stepText, #rangeText {
    margin: -4px 0 0 225px;
    width: 100%;
}
Xitalogy
  • 1,592
  • 1
  • 14
  • 17
  • I am looking into this, I will let you know what I come up with. (I like this documentation more than what I was reading on the jqueryui site) – Sam Oct 09 '12 at 03:01
  • I have updated my JSFiddle to work with this. I captured the start event though, because I want to know right when a user clicks whether or not he will be dragging the whole range or adjusting one value. Now I am stuck because I don't know how to slide the whole range left or right. http://jsfiddle.net/JhKxh/9/ – Sam Oct 09 '12 at 03:53
  • This code seems to be what you wanted. I did not understand what you wanted at first and my earlier code was not the right stuff. You might wish to look at this because it extends your original code on jsfiddle but seems to be very workable. It actually works pretty nifty, I think! Good Luck! – Xitalogy Oct 09 '12 at 09:47