/*! * jQuery UI Slider - v1.10.4 * http://jqueryui.com * * Copyright 2014 jQuery Foundation and other contributors * Released under the MIT license. * http://jquery.org/license * * http://api.jqueryui.com/slider/ */ define([ 'jquery', 'jquery-ui-modules/core', 'jquery-ui-modules/mouse' ], function ($, undefined) { // number of pages in a slider // (how many times can you page up/down to go through the whole range) var numPages = 5; $.widget("ui.slider", $.ui.mouse, { version: "1.10.4", widgetEventPrefix: "slide", options: { animate: false, distance: 0, max: 100, min: 0, orientation: "horizontal", range: false, step: 1, value: 0, values: null, // callbacks change: null, slide: null, start: null, stop: null }, _create: function () { this._keySliding = false; this._mouseSliding = false; this._animateOff = true; this._handleIndex = null; this._detectOrientation(); this._mouseInit(); this.element .addClass("ui-slider" + " ui-slider-" + this.orientation + " ui-widget" + " ui-widget-content" + " ui-corner-all"); this._refresh(); this._setOption("disabled", this.options.disabled); this._animateOff = false; }, _refresh: function () { this._createRange(); this._createHandles(); this._setupEvents(); this._refreshValue(); }, _createHandles: function () { var i, handleCount, options = this.options, existingHandles = this.element.find(".ui-slider-handle").addClass("ui-state-default ui-corner-all"), handle = "", handles = []; handleCount = (options.values && options.values.length) || 1; if (existingHandles.length > handleCount) { existingHandles.slice(handleCount).remove(); existingHandles = existingHandles.slice(0, handleCount); } for (i = existingHandles.length; i < handleCount; i++) { handles.push(handle); } this.handles = existingHandles.add($(handles.join("")).appendTo(this.element)); this.handle = this.handles.eq(0); this.handles.each(function (i) { $(this).data("ui-slider-handle-index", i); }); }, _createRange: function () { var options = this.options, classes = ""; if (options.range) { if (options.range === true) { if (!options.values) { options.values = [this._valueMin(), this._valueMin()]; } else if (options.values.length && options.values.length !== 2) { options.values = [options.values[0], options.values[0]]; } else if ($.isArray(options.values)) { options.values = options.values.slice(0); } } if (!this.range || !this.range.length) { this.range = $("
") .appendTo(this.element); classes = "ui-slider-range" + // note: this isn't the most fittingly semantic framework class for this element, // but worked best visually with a variety of themes " ui-widget-header ui-corner-all"; } else { this.range.removeClass("ui-slider-range-min ui-slider-range-max") // Handle range switching from true to min/max .css({ "left": "", "bottom": "" }); } this.range.addClass(classes + ((options.range === "min" || options.range === "max") ? " ui-slider-range-" + options.range : "")); } else { if (this.range) { this.range.remove(); } this.range = null; } }, _setupEvents: function () { var elements = this.handles.add(this.range).filter("a"); this._off(elements); this._on(elements, this._handleEvents); this._hoverable(elements); this._focusable(elements); }, _destroy: function () { this.handles.remove(); if (this.range) { this.range.remove(); } this.element .removeClass("ui-slider" + " ui-slider-horizontal" + " ui-slider-vertical" + " ui-widget" + " ui-widget-content" + " ui-corner-all"); this._mouseDestroy(); }, _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) { 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; } }); 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(); mouseOverHandle = !$(event.target).parents().addBack().is(".ui-slider-handle"); 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; }, _mouseStart: function () { return true; }, _mouseDrag: function (event) { var position = {x: event.pageX, y: event.pageY}, normValue = this._normValueFromMouse(position); this._slide(event, this._handleIndex, normValue); return false; }, _mouseStop: function (event) { this.handles.removeClass("ui-state-active"); this._mouseSliding = false; this._stop(event, this._handleIndex); this._change(event, this._handleIndex); this._handleIndex = null; this._clickOffset = null; this._animateOff = false; return false; }, _detectOrientation: function () { this.orientation = (this.options.orientation === "vertical") ? "vertical" : "horizontal"; }, _normValueFromMouse: function (position) { var pixelTotal, pixelMouse, percentMouse, valueTotal, valueMouse; if (this.orientation === "horizontal") { pixelTotal = this.elementSize.width; pixelMouse = position.x - this.elementOffset.left - (this._clickOffset ? this._clickOffset.left : 0); } else { pixelTotal = this.elementSize.height; pixelMouse = position.y - this.elementOffset.top - (this._clickOffset ? this._clickOffset.top : 0); } percentMouse = (pixelMouse / pixelTotal); if (percentMouse > 1) { percentMouse = 1; } if (percentMouse < 0) { percentMouse = 0; } if (this.orientation === "vertical") { percentMouse = 1 - percentMouse; } valueTotal = this._valueMax() - this._valueMin(); valueMouse = this._valueMin() + percentMouse * valueTotal; return this._trimAlignValue(valueMouse); }, _start: function (event, index) { var uiHash = { handle: this.handles[index], value: this.value() }; if (this.options.values && this.options.values.length) { uiHash.value = this.values(index); uiHash.values = this.values(); } return this._trigger("start", event, uiHash); }, _slide: function (event, index, newVal) { var otherVal, newValues, allowed; if (this.options.values && this.options.values.length) { otherVal = this.values(index ? 0 : 1); if ((this.options.values.length === 2 && this.options.range === true) && ((index === 0 && newVal > otherVal) || (index === 1 && newVal < otherVal)) ) { newVal = otherVal; } if (newVal !== this.values(index)) { newValues = this.values(); newValues[index] = newVal; // 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 }); otherVal = this.values(index ? 0 : 1); 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); } } } }, _stop: function (event, index) { var uiHash = { handle: this.handles[index], value: this.value() }; if (this.options.values && this.options.values.length) { uiHash.value = this.values(index); uiHash.values = this.values(); } this._trigger("stop", event, uiHash); }, _change: function (event, index) { if (!this._keySliding && !this._mouseSliding) { var uiHash = { handle: this.handles[index], value: this.value() }; if (this.options.values && this.options.values.length) { uiHash.value = this.values(index); uiHash.values = this.values(); } //store the last changed value index for reference when handles overlap this._lastChangedValue = index; this._trigger("change", event, uiHash); } }, value: function (newValue) { if (arguments.length) { this.options.value = this._trimAlignValue(newValue); this._refreshValue(); this._change(null, 0); return; } return this._value(); }, values: function (index, newValue) { var vals, newValues, i; if (arguments.length > 1) { this.options.values[index] = this._trimAlignValue(newValue); this._refreshValue(); this._change(null, index); return; } if (arguments.length) { if ($.isArray(arguments[0])) { vals = this.options.values; newValues = arguments[0]; for (i = 0; i < vals.length; i += 1) { vals[i] = this._trimAlignValue(newValues[i]); this._change(null, i); } this._refreshValue(); } else { if (this.options.values && this.options.values.length) { return this._values(index); } else { return this.value(); } } } else { return this._values(); } }, _setOption: function (key, value) { var i, valsLength = 0; if (key === "range" && this.options.range === true) { if (value === "min") { this.options.value = this._values(0); this.options.values = null; } else if (value === "max") { this.options.value = this._values(this.options.values.length - 1); this.options.values = null; } } if ($.isArray(this.options.values)) { valsLength = this.options.values.length; } $.Widget.prototype._setOption.apply(this, arguments); switch (key) { case "orientation": this._detectOrientation(); this.element .removeClass("ui-slider-horizontal ui-slider-vertical") .addClass("ui-slider-" + this.orientation); this._refreshValue(); break; case "value": this._animateOff = true; this._refreshValue(); this._change(null, 0); this._animateOff = false; break; case "values": this._animateOff = true; this._refreshValue(); for (i = 0; i < valsLength; i += 1) { this._change(null, i); } this._animateOff = false; break; case "min": case "max": this._animateOff = true; this._refreshValue(); this._animateOff = false; break; case "range": this._animateOff = true; this._refresh(); this._animateOff = false; break; } }, //internal value getter // _value() returns value trimmed by min and max, aligned by step _value: function () { var val = this.options.value; val = this._trimAlignValue(val); return val; }, //internal values getter // _values() returns array of values trimmed by min and max, aligned by step // _values( index ) returns single value trimmed by min and max, aligned by step _values: function (index) { var val, vals, i; if (arguments.length) { val = this.options.values[index]; val = this._trimAlignValue(val); return val; } else if (this.options.values && this.options.values.length) { // .slice() creates a copy of the array // this copy gets trimmed by min and max and then returned vals = this.options.values.slice(); for (i = 0; i < vals.length; i += 1) { vals[i] = this._trimAlignValue(vals[i]); } return vals; } else { return []; } }, // returns the step-aligned value that val is closest to, between (inclusive) min and max _trimAlignValue: function (val) { if (val <= this._valueMin()) { return this._valueMin(); } if (val >= this._valueMax()) { return this._valueMax(); } var step = (this.options.step > 0) ? this.options.step : 1, valModStep = (val - this._valueMin()) % step, alignValue = val - valModStep; if (Math.abs(valModStep) * 2 >= step) { alignValue += (valModStep > 0) ? step : (-step); } // Since JavaScript has problems with large floats, round // the final value to 5 digits after the decimal point (see #4124) return parseFloat(alignValue.toFixed(5)); }, _valueMin: function () { return this.options.min; }, _valueMax: function () { return this.options.max; }, _refreshValue: function () { var lastValPercent, valPercent, value, valueMin, valueMax, oRange = this.options.range, o = this.options, that = this, animate = (!this._animateOff) ? o.animate : false, _set = {}; if (this.options.values && this.options.values.length) { this.handles.each(function (i) { valPercent = (that.values(i) - that._valueMin()) / (that._valueMax() - that._valueMin()) * 100; _set[that.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%"; $(this).stop(1, 1)[animate ? "animate" : "css"](_set, o.animate); if (that.options.range === true) { if (that.orientation === "horizontal") { if (i === 0) { that.range.stop(1, 1)[animate ? "animate" : "css"]({left: valPercent + "%"}, o.animate); } if (i === 1) { that.range[animate ? "animate" : "css"]({width: (valPercent - lastValPercent) + "%"}, { queue: false, duration: o.animate }); } } else { if (i === 0) { that.range.stop(1, 1)[animate ? "animate" : "css"]({bottom: (valPercent) + "%"}, o.animate); } if (i === 1) { that.range[animate ? "animate" : "css"]({height: (valPercent - lastValPercent) + "%"}, { queue: false, duration: o.animate }); } } } lastValPercent = valPercent; }); } else { value = this.value(); valueMin = this._valueMin(); valueMax = this._valueMax(); valPercent = (valueMax !== valueMin) ? (value - valueMin) / (valueMax - valueMin) * 100 : 0; _set[this.orientation === "horizontal" ? "left" : "bottom"] = valPercent + "%"; this.handle.stop(1, 1)[animate ? "animate" : "css"](_set, o.animate); if (oRange === "min" && this.orientation === "horizontal") { this.range.stop(1, 1)[animate ? "animate" : "css"]({width: valPercent + "%"}, o.animate); } if (oRange === "max" && this.orientation === "horizontal") { this.range[animate ? "animate" : "css"]({width: (100 - valPercent) + "%"}, { queue: false, duration: o.animate }); } if (oRange === "min" && this.orientation === "vertical") { this.range.stop(1, 1)[animate ? "animate" : "css"]({height: valPercent + "%"}, o.animate); } if (oRange === "max" && this.orientation === "vertical") { this.range[animate ? "animate" : "css"]({height: (100 - valPercent) + "%"}, { queue: false, duration: o.animate }); } } }, _handleEvents: { keydown: function (event) { var allowed, curVal, newVal, step, index = $(event.target).data("ui-slider-handle-index"); switch (event.keyCode) { case $.ui.keyCode.HOME: case $.ui.keyCode.END: case $.ui.keyCode.PAGE_UP: case $.ui.keyCode.PAGE_DOWN: case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: event.preventDefault(); if (!this._keySliding) { this._keySliding = true; $(event.target).addClass("ui-state-active"); allowed = this._start(event, index); if (allowed === false) { return; } } break; } step = this.options.step; if (this.options.values && this.options.values.length) { curVal = newVal = this.values(index); } else { curVal = newVal = this.value(); } switch (event.keyCode) { case $.ui.keyCode.HOME: newVal = this._valueMin(); break; case $.ui.keyCode.END: newVal = this._valueMax(); break; case $.ui.keyCode.PAGE_UP: newVal = this._trimAlignValue(curVal + ((this._valueMax() - this._valueMin()) / numPages)); break; case $.ui.keyCode.PAGE_DOWN: newVal = this._trimAlignValue(curVal - ((this._valueMax() - this._valueMin()) / numPages)); break; case $.ui.keyCode.UP: case $.ui.keyCode.RIGHT: if (curVal === this._valueMax()) { return; } newVal = this._trimAlignValue(curVal + step); break; case $.ui.keyCode.DOWN: case $.ui.keyCode.LEFT: if (curVal === this._valueMin()) { return; } newVal = this._trimAlignValue(curVal - step); break; } this._slide(event, index, newVal); }, click: function (event) { event.preventDefault(); }, keyup: function (event) { var index = $(event.target).data("ui-slider-handle-index"); if (this._keySliding) { this._keySliding = false; this._stop(event, index); this._change(event, index); $(event.target).removeClass("ui-state-active"); } } } }); });