Rudiger
Rudiger

Reputation: 231

Drag the Range of a UI Input Range Slider

<---------[]=====================================[]-------->

0         10                                     90       100

I need an input range slider with two handles to select a range, and the ability to drag the range (the equals signs in the above diagram). So, in the above example, start=10 and end=90, and it is dragged left by shifting the entire line between the two handles:

<[]=====================================[]------------------>

0                                       80                 100

Now Start is 0 and End is 80, accomplished without dragging the handles.

What library offers this functionality?

Thank you.

Upvotes: 23

Views: 17467

Answers (6)

Lg102
Lg102

Reputation: 4898

noUiSlider offers this feature. You can use it by setting the behaviouroption. It allows for both fixed and user-changeable ranges. There are no dependencies on jQueryUI, and if you prefer Zepto over jQuery: that works too.

enter image description here

Disclosure: I am the plugin author.

Upvotes: 6

ghusse
ghusse

Reputation: 3210

You can also try jQRangeSlider, take a look at the demo.

Upvotes: 4

Overview

jQuery UI Slider widget extension for a rangeDrag feature. This feature allows the user to drag the entire range at once, rather than having to drag the handles to move the range.

Code

https://gist.github.com/3758297

(function( $, undefined ) {

$.widget("ui.dragslider", $.ui.slider, {

    options: $.extend({},$.ui.slider.prototype.options,{rangeDrag:false}),

    _create: function() {
      $.ui.slider.prototype._create.apply(this,arguments);
      this._rangeCapture = false;
    },

    _mouseCapture: function( event ) { 
      var o = this.options;

      if ( o.disabled ) return false;

      if(event.target == this.range.get(0) && o.rangeDrag == true && o.range == true) {
        this._rangeCapture = true;
        this._rangeStart = null;
      }
      else {
        this._rangeCapture = false;
      }

      $.ui.slider.prototype._mouseCapture.apply(this,arguments);

      if(this._rangeCapture == true) {  
          this.handles.removeClass("ui-state-active").blur();   
      }

      return true;
    },

    _mouseStop: function( event ) {
      this._rangeStart = null;
      return $.ui.slider.prototype._mouseStop.apply(this,arguments);
    },

    _slide: function( event, index, newVal ) {
      if(!this._rangeCapture) { 
        return $.ui.slider.prototype._slide.apply(this,arguments);
      }

      if(this._rangeStart == null) {
        this._rangeStart = newVal;
      }

      var oldValLeft = this.options.values[0],
          oldValRight = this.options.values[1],
          slideDist = newVal - this._rangeStart,
          newValueLeft = oldValLeft + slideDist,
          newValueRight = oldValRight + slideDist,
          allowed;

      if ( this.options.values && this.options.values.length ) {
        if(newValueRight > this._valueMax() && slideDist > 0) {
          slideDist -= (newValueRight-this._valueMax());
          newValueLeft = oldValLeft + slideDist;
          newValueRight = oldValRight + slideDist;
        }

        if(newValueLeft < this._valueMin()) {
          slideDist += (this._valueMin()-newValueLeft);
          newValueLeft = oldValLeft + slideDist;
          newValueRight = oldValRight + slideDist;
        }

        if ( slideDist != 0 ) {
          newValues = this.values();
          newValues[ 0 ] = newValueLeft;
          newValues[ 1 ] = newValueRight;

          // A slide can be canceled by returning false from the slide callback
          allowed = this._trigger( "slide", event, {
            handle: this.handles[ index ],
            value: slideDist,
            values: newValues
          } );

          if ( allowed !== false ) {
            this.values( 0, newValueLeft, true );
            this.values( 1, newValueRight, true );
          }
          this._rangeStart = newVal;
        }
      }



    },


    /*
    //only for testing purpose
    value: function(input) {
        console.log("this is working!");
        $.ui.slider.prototype.value.apply(this,arguments);
    }
    */
});

})(jQuery);

Example

http://jsfiddle.net/omnosis/Swd9S/

Usage

HTML

<script type="text/javascript" src="js/jquery-1.5.1.min.js"></script>
<script type="text/javascript" src="js/jquery-ui-1.8.13.custom.min.js"></script>
<script type="text/javascript" src="js/jquery.ui.slider.custom.js"></script>
...
<div id="slider"></div>

JavaScript

$(function(){
// Slider
$('#slider').dragslider({
    animate: true,   // Works with animation.
    range: true,     // Must have a range to drag.
    rangeDrag: true, // Enable range dragging.
    values: [30, 70]        
});
});

Upvotes: 48

Johan Olsson
Johan Olsson

Reputation: 618

You can try adding the drag + drop triggers to the $('.ui-slider-range') element
OR
add you own event to the $('.ui-slider-range') element that just trigger the events on the $('.ui-slider-handle')

Upvotes: 1

Thomas Shields
Thomas Shields

Reputation: 8942

You might try checking out the jQuery UI Slider

The link above demonstrates the "range" selector feature, which is what you're looking for, but there are lots of other ways to use it as well.

Upvotes: 1

Justin Ethier
Justin Ethier

Reputation: 134157

I recommend you have a look a the jQuery UI Slider.

Upvotes: 3

Related Questions