From c7facf847f78883e069d50016d2c0971cc166696 Mon Sep 17 00:00:00 2001 From: Sylvain Henry Date: Tue, 14 Aug 2018 12:54:21 +0200 Subject: [PATCH] Slider: add support for crossing multiple handles With this patch, a slider which has both "range = true" and "allowCrossingHandles = true" automatically determines the handlers starting and stopping the range. Handlers can freely cross each other. --- tests/unit/slider/common.js | 1 + tests/unit/slider/options.js | 20 +++++++++++++++ ui/widgets/slider.js | 48 +++++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 14 deletions(-) diff --git a/tests/unit/slider/common.js b/tests/unit/slider/common.js index df53cda4ff3..d9801c8c83b 100644 --- a/tests/unit/slider/common.js +++ b/tests/unit/slider/common.js @@ -22,6 +22,7 @@ common.testWidget( "slider", { step: 1, value: 0, values: null, + allowCrossingHandles: false, // Callbacks create: null, diff --git a/tests/unit/slider/options.js b/tests/unit/slider/options.js index d1eb2b374d6..a189067a295 100644 --- a/tests/unit/slider/options.js +++ b/tests/unit/slider/options.js @@ -401,4 +401,24 @@ QUnit.test( "range", function( assert ) { element.slider( "destroy" ); } ); +QUnit.test( "allowCrossingHandles", function( assert ) { + assert.expect( 1 ); + + element = $( "
" ).slider( { + range: true, + min: 0, + max: 100, + values: [ 25, 75 ], + allowCrossingHandles: true + } ); + + assert.deepEqual( element.slider( "values" ), [ 25, 75 ], "values" ); + + // var handles = element.find( ".ui-slider-handle" ); + // handles.eq( 0 ).simulate( "drag", { dx: 1000 } ); + // assert.deepEqual( element.slider( "values" ), [ 100, 75 ], "values" ); + + element.slider( "destroy" ); +} ); + } ); diff --git a/ui/widgets/slider.js b/ui/widgets/slider.js index 8b0f907f577..571e8047163 100644 --- a/ui/widgets/slider.js +++ b/ui/widgets/slider.js @@ -53,6 +53,7 @@ return $.widget( "ui.slider", $.ui.mouse, { min: 0, orientation: "horizontal", range: false, + allowCrossingHandles: false, step: 1, value: 0, values: null, @@ -330,11 +331,14 @@ return $.widget( "ui.slider", $.ui.mouse, { newValues = this.values(); if ( this._hasMultipleValues() ) { - otherVal = this.values( index ? 0 : 1 ); - currentValue = this.values( index ); + if ( !this.options.allowCrossingHandles ) { + otherVal = this.values( index ? 0 : 1 ); + currentValue = this.values( index ); - if ( this.options.values.length === 2 && this.options.range === true ) { - newVal = index === 0 ? Math.min( otherVal, newVal ) : Math.max( otherVal, newVal ); + if ( this.options.values.length === 2 && this.options.range === true ) { + newVal = index === 0 ? Math.min( otherVal, newVal ) + : Math.max( otherVal, newVal ); + } } newValues[ index ] = newVal; @@ -473,6 +477,7 @@ return $.widget( "ui.slider", $.ui.mouse, { this._animateOff = false; break; case "range": + case "allowCrossingHandles": this._animateOff = true; this._refresh(); this._animateOff = false; @@ -590,7 +595,9 @@ return $.widget( "ui.slider", $.ui.mouse, { }, _refreshValue: function() { - var lastValPercent, valPercent, value, valueMin, valueMax, + var valPercent, value, valueMin, valueMax, + rangeStartIndex = 0, + rangeStopIndex = 1, oRange = this.options.range, o = this.options, that = this, @@ -599,34 +606,48 @@ return $.widget( "ui.slider", $.ui.mouse, { if ( this._hasMultipleValues() ) { this.handles.each( function( i ) { - valPercent = ( that.values( i ) - that._valueMin() ) / ( that._valueMax() - - that._valueMin() ) * 100; + if ( that.values( i ) > that.values( rangeStopIndex ) ) { + rangeStopIndex = i; + } + if ( that.values( i ) < that.values( rangeStartIndex ) ) { + rangeStartIndex = i; + } + } ); + this.handles.each( function( i ) { + var valPercentStart; + var computeValPercent = function( idx ) { + return ( that.values( idx ) - that._valueMin() ) / ( that._valueMax() - + that._valueMin() ) * 100; + }; + valPercent = computeValPercent( i ); _set[ that.orientation === "horizontal" ? "left" : "bottom" ] = valPercent + "%"; $( this ).stop( 1, 1 )[ animate ? "animate" : "css" ]( _set, o.animate ); if ( that.options.range === true ) { if ( that.orientation === "horizontal" ) { - if ( i === 0 ) { + if ( i === rangeStartIndex ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { left: valPercent + "%" }, o.animate ); } - if ( i === 1 ) { + if ( i === rangeStopIndex ) { + valPercentStart = computeValPercent( rangeStartIndex ); that.range[ animate ? "animate" : "css" ]( { - width: ( valPercent - lastValPercent ) + "%" + width: Math.abs ( valPercent - valPercentStart ) + "%" }, { queue: false, duration: o.animate } ); } } else { - if ( i === 0 ) { + if ( i === rangeStartIndex ) { that.range.stop( 1, 1 )[ animate ? "animate" : "css" ]( { bottom: ( valPercent ) + "%" }, o.animate ); } - if ( i === 1 ) { + if ( i === rangeStopIndex ) { + valPercentStart = computeValPercent( rangeStartIndex ); that.range[ animate ? "animate" : "css" ]( { - height: ( valPercent - lastValPercent ) + "%" + height: Math.abs ( valPercent - valPercentStart ) + "%" }, { queue: false, duration: o.animate @@ -634,7 +655,6 @@ return $.widget( "ui.slider", $.ui.mouse, { } } } - lastValPercent = valPercent; } ); } else { value = this.value();