MultiRangeSlider (Mrs)

Extends jquery-ui slider widget to include multiple ranges. Live example at jsFiddle

by araczkowski

HTML

<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/font-awesome/4.2.0/css/font-awesome.min.css">
<div id="pluginRegion" style="width:960px; overflow:auto;">
        <div id="parent" class="MrsContent" style="width: 1800px; height: 100px;">
            <div id="slider"></div>
        </div>
 </div>

CSS

.MrsContent {
    margin-top: 50px;
    margin-right: 30px;
    margin-bottom: 50px;
    margin-left: 30px;
}
.MrsSteps {
    position: relative;
    height: 40px;
    margin-bottom: 5px;
}
.MrsStep {
    float: left;
    height: 40px;
    background-color: #e6f7fd;
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    box-sizing: border-box;
}
.MrsStepContentFullHour {
    height: 100%;
    border-left: 2px solid #43838c;
}
.MrsStepContentHalfHour {
    height: 100%;
    border-left: 2px solid white;
}
.MrsStepContent {
    height: 100%;
    border-left: 1px solid white;
}
.MrsStepContentEnd {
    height: 100%;
    border-right: 2px solid #43838c;
}
.MrsTick {
    border: 1px solid transparent;
    position: absolute;
    margin-left: -.6em;
    margin-top: -20px;
    text-align: center;
    color: #43838c;
}
.MrsHandleLabel {
    position: absolute;
    font-size: .9em;
    margin-top: 0.5em;
    margin-left: -.9em;
    -webkit-transform: rotate(90deg);
    -moz-transform: rotate(90deg);
    -o-transform: rotate(90deg);
    transform: rotate(90deg);
    padding: .2em;
    -moz-border-radius: 3px 3px 3px 3px;
    border-radius: 3px 3px 3px 3px;
    color: #43838c;
}
i.fa-eject {
    margin-left: -0.1em;
    color: #ff8229;
}
.ui-slider-horizontal {
    width: 96%;
}
.ui-slider-horizontal .ui-slider-range {
    /*background-color: #ff930f;*/
}
.ui-slider-control-plus,
.ui-slider-control-minus {
    width: 26px;
    height: 26px;
    position: absolute;
    z-index: 99;
    margin: 0 0 0 -13px;
    line-height: 26px;
}
.ui-slider-control-plus:after,
.ui-slider-control-minus:after {
    position: absolute;
    width: 26px;
    height: 26px;
    text-align: center;
}
.ui-slider-control-plus:after {
    content: "\f0fe";
    font-family: FontAwesome;
    /*font-weight: bold;
    content: "+";*/
    font-size: 2em;
    color: #00abe8;
}
.ui-slider-control-minus:after {
    content: "\f146";
    font-family: FontAwesome;
    /*content: "x";
   ...

JavaScript

(function (w, $) {
    $.widget('ui.mrs', $.ui.slider, {
        _create: function () {
            this._super();
        },
        _mouseCapture: function (event) {
            if ($(event.target).is('a.ui-slider-handle')) {
                this._lastChangedValue = $(event.target.parentNode).find('.ui-slider-handle').index(event.target);
            }
            return this._super(event);
        }
    });

    /**
     * @class Mrs
     *
     * @constructor
     * @param {String} elementId, this id will be used to create jQuery selector
     * @param {Object} userOptions (optional) Custom options object that overrides default
     * {
     *      @property {Number} userOptions.min Slider minimum value
     *      @property {Number} userOptions.max Slider maximum value
     *      @property {Number} userOptions.step Slider sliding step
     *      @property {Number} userOptions.gap Minimum gap between handles when add/remove range controls are visible
     *      @property {Number} userOptions.newlength Default length for newly created range. Will be adjusted between surrounding handles if not fitted
     *      @property {Object} userOptions.handleLabelDispFormat mrs handle label format default hh24:mi
     *      @property {Object} userOptions.stepLabelDispFormat mrs step Label format default hh24
     * }
     */
    w.Mrs = function (elementId, userOptions) {
        //var _self = this;
        var _slider;
        var _options = {
            min: 0,
            max: 1440,
            step: 30,
            gap: 150,
            newlength: 90,
            handleLabelDispFormat: function (steps) {
                var hours = Math.floor(Math.abs(steps) / 60);
                var minutes = Math.abs(steps) % 60;
                return ((hours < 10 && hours >= 0) ? '0' : '') + hours + ':' + ((minutes < 10 && minutes >= 0) ? '0' : '') + minutes;
            },
            stepLabelDispFormat: function (steps) {
                var hours =...