3
votes

I have run into an interesting issue with the jQuery UI slider. I need to assign its min and max values from sript and am doing the following

$("#sliCSSHt").slider('values',[minh,maxh]);
$("#sliCSSHt").slider('refresh');

The problem arises when minh = maxh. The MIN button appears to go and sit on TOP of the max button. The innocent user who then tries to inrease the max value finds that the slider has beome unresponsive since he/she is actually dragging the min button beyond the current position of the max button. What if anything can be done to get round this?

I am using jQuery UI 1.91 with jQuery 1.82 - I don't have the option of moving up to jQuery 1.9 since I am using plugins that use the browser object which has now been taken out of jQuery.

3
Can you post your HTML and create a jsFiddle?j08691
Here is the fiddle jsfiddle.net/c934g/2. The steps to follow: a. Click on the reset slider button. b. The two slider handles are now sitting on top of each other. c. Try dragging the handle you see to the right - no joy. d. Now drag it to the left. It works because it is the lowRange handle. e. Now you can drag the other one to the right. Tested with Chrome and Safari on WindowsDroidOS
Strange, I must be missing something simple. Even if I use the same range example that the jQueryUI site uses, I lose the functionality they have there and always end up dragging the min handle as your example shows. Even if I alter the zIndex. Maybe it's a jsFiddle/slider issue.j08691
Well, no it is not a jsFiddle issue - I ran into the bug in my own app which I am developing and testing under Chrome. About the only "solution" I can think of for now is to deliberately right offset the highHandle when I detect that minh = maxhDroidOS
Yeah i thought of that too but it seems hacky.j08691

3 Answers

0
votes

You could always stop the sliders from overlapping. Something like

$( "#sliCSSHt" ).on( "slide", function( event, ui ) {
    if(ui.values[0]+10 > ui.values[1])  
       return false;
} );

http://jsfiddle.net/c934g/5/

Update This bug is fixed in the latest jquery-ui

using the latest jquery-ui files http://code.jquery.com/ui/1.10.3/jquery-ui.js it works.

http://jsfiddle.net/c934g/7/

0
votes

My solution is to patch jQuery UI and redefine the slide behavior. This is my concept:

If one slider handle passes the boundary made up by the other slider handle during sliding: Instead of preventing the user from sliding further (normal jQuery UI behavior), act as if the user grabbed the other one. To put it simply: Swap the slider handles if neccessary.

This is my patch. It doesn't change much and most lines are identical to the original jQuery UI code.

$.widget('ui.slider', $.ui.slider, {

    _start: function( event, index ) {
        this.swapIndex = false;
        return this._super( event, index );
    },

    _slide: function( event, index, newVal ) {
        var otherVal,
            newValues,
            allowed;

        if ( this.options.values && this.options.values.length ) {
            if ( this.swapIndex ) {
                index = index ? 0 : 1;
            }
            otherVal = this.values( index ? 0 : 1 );

            if ( index === 0 && newVal > otherVal || index === 1 && newVal < otherVal ) {
                this.swapIndex = !this.swapIndex;
                index = index ? 0 : 1;
            }

            if ( newVal !== this.values( index ) ) {
                newValues = [];
                newValues[ index ] = newVal;
                newValues[ index ? 0 : 1 ] = otherVal;
                // A slide can be canceled by returning false from the slide callback
                allowed = this._trigger( "slide", event, {
                    handle: this.handles[ index ],
                    value: newVal,
                    values: newValues
                } );
                if ( allowed !== false ) {
                    this.values( index, newVal );
                }
            }
        } else {
            if ( newVal !== this.value() ) {
                // A slide can be canceled by returning false from the slide callback
                allowed = this._trigger( "slide", event, {
                    handle: this.handles[ index ],
                    value: newVal
                } );
                if ( allowed !== false ) {
                    this.value( newVal );
                }
            }
        }
    }
});

Live demo: http://jsfiddle.net/xykwup5a/

I prefer this solution for two reasons:

  1. The jQuery UI fix in version 1.10.3 seems not to work if your values are negative
  2. Better user experience: When not using the patch and two handles overlap the user can only move the handle in one direction and has to play around to increase the range in the other direction.
0
votes

This is not a permanent fix but helpful to make slider draggable agian.

$('#slider-range').slider
  start: (event, ui) ->
    # Only when sliders are overriding
    if ui.values[0] == ui.values[1]
     set_min = ui.values[0] - 0.1
     set_max = ui.values[1]
     # Deducing value of left slider by 0.1(or you can give step value based on your condition)
     $('#slider-range').slider('values', [set_min,set_max])
     return false
  slide: (event, ui) ->
    # Some statements
  stop: (event, ui) ->
    # Some statements