jQuery Slider SuperRange

by Jens Kühn

HTML

<div>
    Minimum range width is 2<br/>
    Maximum range width is 24<br/>
    Lower handle can't go over 24<br/>
    Upper handle can't go below 4<br>
    Dragging over maximum range drags the other handle along
</div>
<hr/>
<div id="values">initializing...</div>
<div id="range" />

CSS

div
{
    font-family: Segoe UI, sans-serif;
    font-size: 9pt;
}
#values
{
    margin-left: 50px;
    padding: 3px 5px;
    background: #eee;
    display: inline-block;
    border: 1px solid #ccc;
    margin-bottom: -1px;
}
.ui-slider
{
    margin-left: 50px;
    height: 12px;
    width: 360px;
    background: #eee;
    position: relative;
    border: 1px solid #ccc;
}
.ui-slider .ui-slider-range
{
    top: 1px;
    height: 10px;
    background: #0c0;
    position: absolute;
}
.ui-slider .ui-slider-handle
{
    width: 10px;
    height: 16px;
    border: 1px solid #009;
    background: #99f;
    position: absolute;
    top: -3px;
    margin-left: -6px;
    border-radius: 3px;
}

JavaScript

// slider extension
(function ($) {
    if ($.ui.slider)
    {
        // add minimum range length option
        $.extend($.ui.slider.prototype.options, {
            minRangeSize: 0,
            maxRangeSize: 100,
            autoShift: false,
            lowMax: 100,
            topMin: 0
        });

        $.extend($.ui.slider.prototype, {
            _slide: function (event, index, newVal) {
                var otherVal,
                newValues,
                allowed,
                factor;

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

                    if (this.options.values.length === 2 && this.options.range === true)
                    {
                        // lower bound max
                        if (index === 0 && newVal > this.options.lowMax)
                        {
                            newVal = this.options.lowMax;
                        }
                        // upper bound min
                        if (index === 1 && newVal < this.options.topMin)
                        {
                            newVal = this.options.topMin;
                        }
                        // minimum range requirements
                        if ((otherVal - newVal) * factor < this.options.minRangeSize)
                        {
                            newVal = otherVal - this.options.minRangeSize * factor;
                        }
                        // maximum range requirements
                        if ((otherVal - newVal) * factor > this.options.maxRangeSize)
                        {
                            if (this.options.autoShift === true)
                            {
                                otherVal = newVal + this.options.maxRangeSize * factor;
                            }
                            else
                            {
       ...