I have this simple jQuery UI Slider setup with a range and a two default values that overlap. The entire thing (with a few bells and whistles) can be found in this jsfiddle:
With apologies to Ivo there, whose excellent answer there I'm sure took a lot of effort to create. The problem is that I couldn't apply that solution, because I'm already on 1.8.6, I can't find the 1.8.5 sources anywhere to apply it to, and somehow I just couldn't get the patch to work for 1.8.6, even when I tried adding in the lines manually.
The following is my solution to the problem. It is simpler than Ivo's, but that might be because of differences between the two point releases. The solution is as follows:
_handleIndex
) around, causing the maximum handle to be used for reference for the internal _slide
function instead of the first. The diff
is as follows:
46a47,48
>
> this._originalVal;
310a313,314
>
> this._originalVal = this.values();
323a328,331
>
> if(this._originalVal[0] === this._originalVal[1] && normValue > this._originalVal[0]){
> this._handleIndex = 1;
> }
The first part should be inserted into the initialising area, where the variables are declared, the second into the _mouseCapture
function right before the call to _slide
, and the last part into the _mouseDrag
function, also right before the call to _slide
.
Here's a working example with the patch: http://www.jsfiddle.net/HcGXZ/
A copy of the patched jQuery UI 1.8.6 Slider file can be found here: http://dl.dropbox.com/u/1722364/jQuery%20UI%20Slider%20Patch/jquery.ui.slider.patched.js
As always, this patch has not been extensively tested and is not guaranteed to work for all scenarios.
Ah, I like it to eat through 11k libs, don't you too? :)
Note: The following is for jQuery UI 1.8.5
Anyways, here's a pretty clean solution:
// add some stuff to the slider instance
this._handleIndex = null;
this._handleStartValue = -1;
// remember the starting values in _mouseCapture
this._handleStartValue = this.values( this._handleIndex );
this._mouseDownOffset = this._normValueFromMouse( { x: event.pageX, y: event.pageY } );
// modify _mouseDrag
oldValue = this.values( this._handleIndex ),
curValue;
curValue = this.values(this._handleIndex);
if ( curValue === oldValue && this._handleStartValue !== -1 ) {
if ( normValue - this._mouseDownOffset > 0
&& ( curValue === this.values( ( this._handleIndex + 1 ) % 2 ) )
&& oldValue === this._handleStartValue) {
this._handleIndex = (this._handleIndex + 1) % 2;
}
} else {
this._handleStartValue = - 1
}
// reset everything in _mouseStop
this._handleIndex = null;
this._handleStartValue = -1;
And that's all there is to it, oh how it works, of course:
And for your pleasure here's a diff
:
9960c9960,9962
<
---
>
> this._handleIndex = null;
> this._handleStartValue = -1;
10215a10218,10219
> this._handleStartValue = this.values( this._handleIndex );
> this._mouseDownOffset = this._normValueFromMouse( { x: event.pageX, y: event.pageY } );
10243c10247,10249
< normValue = this._normValueFromMouse( position );
---
> normValue = this._normValueFromMouse( position ),
> oldValue = this.values( this._handleIndex ),
> curValue;
10246c10252,10263
<
---
> curValue = this.values(this._handleIndex);
> if ( curValue === oldValue && this._handleStartValue !== -1 ) {
> if ( normValue - this._mouseDownOffset > 0
> && ( curValue === this.values( ( this._handleIndex + 1 ) % 2 ) )
> && oldValue === this._handleStartValue) {
>
> this._handleIndex = (this._handleIndex + 1) % 2;
> }
>
> } else {
> this._handleStartValue = - 1
> }
10257a10275,10276
> this._handleStartValue = -1;
> this._handleIndex = null;
Save it to ui.diff
then do patch -i ui.diff jquery-ui.js
.
I tried Yi Jiang's solution with 1.8.12 and it broke on a slider with a single handle, but worked perfectly after I changed
this._originalVal = this.values();
to
this._originalVal = this.options.values === null ? this.value() : this.values();
Put this into the initialising area, where the variables are declared:
this._originalVal;
Put this into the _mouseCapture
function right before the call to _slide
:
this._originalVal = this.values();
And this into the _mouseDrag
function, also right before the call to _slide
if (this._originalVal[0] === this._originalVal[1]
&& normValue > this._originalVal[0]) {
this._handleIndex = 1;
} else if (this._originalVal[0] === this._originalVal[1]
&& normValue < this._originalVal[0]) {
this._handleIndex = 0;
}
I just added an else if
to the above code; it's working fine in jQuery 1.8.14 for
both left and right button handlers.
Here's a new version for jQuery UI 1.10.2
Patch file: http://pastebin.com/Dsxw8NYR
Complete file: http://pastebin.com/ibSpAAX1
Another solution: Test for both values and if they are the same, return to the last step.
$("#slider").slider({
range:true,
min:0,
max:250,
step: 25,
slide: function( event, ui ) {
if (ui.values[0] == ui.values[1]){
return false;
}else{
$( "#amount" ).html( "€" + ui.values[0] + " - €" + ui.values[1] );
}
}
});