Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

jquery ui slider- trying to disable individual handles

I have a ui range slider. I've altered the script to add additional ranges and handles. I'm trying to disable one of the handles, (to show a portion of the whole that is always going to be part of the calculation, so shouldn't be alterable, but needs to be a visible segment).

I've tried within the slide: if ( ui.value == ui.values[3] && ui.value > 98) { off();

    }
           if ( ui.value == ui.values[3] && ui.value < 98 ) {
         off();
    }

using both off() and return false, and the handle itself is then frozen, but it is still calculating values as if it was being moved.

So, I tried to disable- i've tried: $('A.ui-slider-handle').eq(2).draggable(false); //this somehow lets me drag it all over the page and

$('A.ui-slider-handle').eq(2).attr('disabled', 'disabled'); and $('A.ui-slider-handle').eq(2).prop('disabled');

but these aren't working either. Any suggestions? I'm new to this and lost. Thanks!

like image 824
helixmat Avatar asked Apr 22 '13 16:04

helixmat


2 Answers

As far as I can tell, the jQuery UI slider widget does not have the ability to disable individual handles. However, if you don't mind extending the jQuery UI slider widget, you can add this functionality.

In the code below, I extended the _mouseCapture function in the jQuery UI slider widget to prevent the mouse from moving/selecting handles that have the ui-slider-handle-disabled class. It's a bit large, as I had to copy the existing _mouseCapture function and add a few lines. I marked my insertions with comments.

You can test this code here on jsfiddle.

// extend jQuery UI slider widget's _mouseCapture function to allow disabling handles
// _mouseCapture function copied from jQuery UI v1.10.3
$.widget("ui.slider", $.ui.slider, {
    _mouseCapture: function (event) {
        var position, normValue, distance, closestHandle, index, allowed, offset, mouseOverHandle,
        that = this,
            o = this.options;

        if (o.disabled) {
            return false;
        }

        this.elementSize = {
            width: this.element.outerWidth(),
            height: this.element.outerHeight()
        };
        this.elementOffset = this.element.offset();

        position = {
            x: event.pageX,
            y: event.pageY
        };
        normValue = this._normValueFromMouse(position);
        distance = this._valueMax() - this._valueMin() + 1;
        this.handles.each(function (i) {
            // Added condition to skip closestHandle test if this handle is disabled.
            // This prevents disabled handles from being moved or selected with the mouse.
            if (!$(this).hasClass("ui-slider-handle-disabled")) {
                var thisDistance = Math.abs(normValue - that.values(i));
                if ((distance > thisDistance) || (distance === thisDistance && (i === that._lastChangedValue || that.values(i) === o.min))) {
                    distance = thisDistance;
                    closestHandle = $(this);
                    index = i;
                }
            }
        });

        // Added check to exit gracefully if, for some reason, all handles are disabled
        if(typeof closestHandle === 'undefined')
            return false;

        allowed = this._start(event, index);
        if (allowed === false) {
            return false;
        }
        this._mouseSliding = true;

        this._handleIndex = index;

        closestHandle.addClass("ui-state-active")
            .focus();

        offset = closestHandle.offset();
        // Added extra condition to check if the handle currently under the mouse cursor is disabled.
        // This ensures that if a disabled handle is clicked, the nearest handle will remain under the mouse cursor while dragged.
        mouseOverHandle = !$(event.target).parents().addBack().is(".ui-slider-handle") || $(event.target).parents().addBack().is(".ui-slider-handle-disabled");
        this._clickOffset = mouseOverHandle ? {
            left: 0,
            top: 0
        } : {
            left: event.pageX - offset.left - (closestHandle.width() / 2),
            top: event.pageY - offset.top - (closestHandle.height() / 2) - (parseInt(closestHandle.css("borderTopWidth"), 10) || 0) - (parseInt(closestHandle.css("borderBottomWidth"), 10) || 0) + (parseInt(closestHandle.css("marginTop"), 10) || 0)
        };

        if (!this.handles.hasClass("ui-state-hover")) {
            this._slide(event, index, normValue);
        }
        this._animateOff = true;
        return true;
    }
});
like image 94
finLprtoTyp Avatar answered Oct 12 '22 10:10

finLprtoTyp


Define the handles yourself within the slider div:

<div id="slider-range">
  <div class="ui-slider-handle first-handle"></div>
  <div class="ui-slider-handle second-handle"></div>
</div>

Disable all interactions with the slider:

.ui-widget {
    pointer-events: none;
}

And set the according css style to enable interaction:

#slider-range.ui-slider .ui-slider-handle.first-handle {
    pointer-events: all;
}

Everything but the first handle is now disabled

like image 34
4ndro1d Avatar answered Oct 12 '22 11:10

4ndro1d