123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812 |
- /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
- * Copyright (c) 2016 Simon Goellner <simey.me@gmail.com>; Licensed MIT */
-
- (function ($) {
-
- "use strict";
-
- var extensionMethods = {
-
-
-
-
-
- // pips
-
- pips: function (settings) {
-
- var slider = this,
- i, j, p,
- collection = "",
- mousedownHandlers,
- min = slider._valueMin(),
- max = slider._valueMax(),
- pips = (max - min) / slider.options.step,
- $handles = slider.element.find(".ui-slider-handle"),
- $pips;
-
- var options = {
-
- first: "label",
- /* "label", "pip", false */
-
- last: "label",
- /* "label", "pip", false */
-
- rest: "pip",
- /* "label", "pip", false */
-
- labels: false,
- /* [array], { first: "string", rest: [array], last: "string" }, false */
-
- prefix: "",
- /* "", string */
-
- suffix: "",
- /* "", string */
-
- step: (pips > 100) ? Math.floor(pips * 0.05) : 1,
- /* number */
-
- formatLabel: function (value) {
- return this.prefix + value + this.suffix;
- }
- /* function
- must return a value to display in the pip labels */
-
- };
-
- if ($.type(settings) === "object" || $.type(settings) === "undefined") {
-
- $.extend(options, settings);
- slider.element.data("pips-options", options);
-
- } else {
-
- if (settings === "destroy") {
-
- destroy();
-
- } else if (settings === "refresh") {
-
- slider.element.slider("pips", slider.element.data("pips-options"));
-
- }
-
- return;
-
- }
-
-
- // we don't want the step ever to be a floating point or negative
- // (or 0 actually, so we'll set it to 1 in that case).
- slider.options.pipStep = Math.abs(Math.round(options.step)) || 1;
-
- // get rid of all pips that might already exist.
- slider.element
- .off(".selectPip")
- .addClass("ui-slider-pips")
- .find(".ui-slider-pip")
- .remove();
-
- // small object with functions for marking pips as selected.
-
- var selectPip = {
-
- single: function (value) {
-
- this.resetClasses();
-
- $pips
- .filter(".ui-slider-pip-" + this.classLabel(value))
- .addClass("ui-slider-pip-selected");
-
- if (slider.options.range) {
-
- $pips.each(function (k, v) {
-
- var pipVal = $(v).children(".ui-slider-label").data("value");
-
- if ((slider.options.range === "min" && pipVal < value) ||
- (slider.options.range === "max" && pipVal > value)) {
-
- $(v).addClass("ui-slider-pip-inrange");
-
- }
-
- });
-
- }
-
- },
-
- range: function (values) {
-
- this.resetClasses();
-
- for (i = 0; i < values.length; i++) {
-
- $pips
- .filter(".ui-slider-pip-" + this.classLabel(values[i]))
- .addClass("ui-slider-pip-selected-" + (i + 1));
-
- }
-
- if (slider.options.range) {
-
- $pips.each(function (k, v) {
-
- var pipVal = $(v).children(".ui-slider-label").data("value");
-
- if (pipVal > values[0] && pipVal < values[1]) {
-
- $(v).addClass("ui-slider-pip-inrange");
-
- }
-
- });
-
- }
-
- },
-
- classLabel: function (value) {
-
- return value.toString().replace(".", "-");
-
- },
-
- resetClasses: function () {
-
- var regex = /(^|\s*)(ui-slider-pip-selected|ui-slider-pip-inrange)(-{1,2}\d+|\s|$)/gi;
-
- $pips.removeClass(function (index, css) {
- return (css.match(regex) || []).join(" ");
- });
-
- }
-
- };
-
- function getClosestHandle(val) {
-
- var h, k,
- sliderVals,
- comparedVals,
- closestVal,
- tempHandles = [],
- closestHandle = 0;
-
- if (slider.values() && slider.values().length) {
-
- // get the current values of the slider handles
- sliderVals = slider.values();
-
- // find the offset value from the `val` for each
- // handle, and store it in a new array
- comparedVals = $.map(sliderVals, function (v) {
- return Math.abs(v - val);
- });
-
- // figure out the closest handles to the value
- closestVal = Math.min.apply(Math, comparedVals);
-
- // if a comparedVal is the closestVal, then
- // set the value accordingly, and set the closest handle.
- for (h = 0; h < comparedVals.length; h++) {
- if (comparedVals[h] === closestVal) {
- tempHandles.push(h);
- }
- }
-
- // set the closest handle to the first handle in array,
- // just incase we have no _lastChangedValue to compare to.
- closestHandle = tempHandles[0];
-
- // now we want to find out if any of the closest handles were
- // the last changed handle, if so we specify that handle to change
- for (k = 0; k < tempHandles.length; k++) {
- if (slider._lastChangedValue === tempHandles[k]) {
- closestHandle = tempHandles[k];
- }
- }
-
- if (slider.options.range && tempHandles.length === 2) {
-
- if (val > sliderVals[1]) {
-
- closestHandle = tempHandles[1];
-
- } else if (val < sliderVals[0]) {
-
- closestHandle = tempHandles[0];
-
- }
-
- }
-
- }
-
- return closestHandle;
-
- }
-
- function destroy() {
-
- slider.element
- .off(".selectPip")
- .on("mousedown.slider", slider.element.data("mousedown-original"))
- .removeClass("ui-slider-pips")
- .find(".ui-slider-pip")
- .remove();
-
- }
-
- // when we click on a label, we want to make sure the
- // slider's handle actually goes to that label!
- // so we check all the handles and see which one is closest
- // to the label we clicked. If 2 handles are equidistant then
- // we move both of them. We also want to trigger focus on the
- // handle.
-
- // without this method the label is just treated like a part
- // of the slider and there's no accuracy in the selected value
-
- function labelClick(label, e) {
-
- if (slider.option("disabled")) {
- return;
- }
-
- var val = $(label).data("value"),
- indexToChange = getClosestHandle(val);
-
- if (slider.values() && slider.values().length) {
-
- slider.options.values[indexToChange] = slider._trimAlignValue(val);
-
- } else {
-
- slider.options.value = slider._trimAlignValue(val);
-
- }
-
- slider._refreshValue();
- slider._change(e, indexToChange);
-
- }
-
- // method for creating a pip. We loop this for creating all
- // the pips.
-
- function createPip(which) {
-
- var label,
- percent,
- number = which,
- classes = "ui-slider-pip",
- css = "",
- value = slider.value(),
- values = slider.values(),
- labelValue,
- classLabel,
- labelIndex;
-
- if (which === "first") {
-
- number = 0;
-
- } else if (which === "last") {
-
- number = pips;
-
- }
-
- // labelValue is the actual value of the pip based on the min/step
- labelValue = min + (slider.options.step * number);
-
- // classLabel replaces any decimals with hyphens
- classLabel = labelValue.toString().replace(".", "-");
-
- // get the index needed for selecting labels out of the array
- labelIndex = (number + min) - min;
-
- // we need to set the human-readable label to either the
- // corresponding element in the array, or the appropriate
- // item in the object... or an empty string.
-
- if ($.type(options.labels) === "array") {
-
- label = options.labels[labelIndex] || "";
-
- } else if ($.type(options.labels) === "object") {
-
- if (which === "first") {
-
- // set first label
- label = options.labels.first || "";
-
- } else if (which === "last") {
-
- // set last label
- label = options.labels.last || "";
-
- } else if ($.type(options.labels.rest) === "array") {
-
- // set other labels, but our index should start at -1
- // because of the first pip.
- label = options.labels.rest[labelIndex - 1] || "";
-
- } else {
-
- // urrggh, the options must be f**ked, just show nothing.
- label = labelValue;
-
- }
-
- } else {
-
- label = labelValue;
-
- }
-
-
-
-
- if (which === "first") {
-
- // first Pip on the Slider
- percent = "0%";
-
- classes += " ui-slider-pip-first";
- classes += (options.first === "label") ? " ui-slider-pip-label" : "";
- classes += (options.first === false) ? " ui-slider-pip-hide" : "";
-
- } else if (which === "last") {
-
- // last Pip on the Slider
- percent = "100%";
-
- classes += " ui-slider-pip-last";
- classes += (options.last === "label") ? " ui-slider-pip-label" : "";
- classes += (options.last === false) ? " ui-slider-pip-hide" : "";
-
- } else {
-
- // all other Pips
- percent = ((100 / pips) * which).toFixed(4) + "%";
-
- classes += (options.rest === "label") ? " ui-slider-pip-label" : "";
- classes += (options.rest === false) ? " ui-slider-pip-hide" : "";
-
- }
-
- classes += " ui-slider-pip-" + classLabel;
-
-
- // add classes for the initial-selected values.
- if (values && values.length) {
-
- for (i = 0; i < values.length; i++) {
-
- if (labelValue === values[i]) {
-
- classes += " ui-slider-pip-initial-" + (i + 1);
- classes += " ui-slider-pip-selected-" + (i + 1);
-
- }
-
- }
-
- if (slider.options.range) {
-
- if (labelValue > values[0] &&
- labelValue < values[1]) {
-
- classes += " ui-slider-pip-inrange";
-
- }
-
- }
-
- } else {
-
- if (labelValue === value) {
-
- classes += " ui-slider-pip-initial";
- classes += " ui-slider-pip-selected";
-
- }
-
- if (slider.options.range) {
-
- if ((slider.options.range === "min" && labelValue < value) ||
- (slider.options.range === "max" && labelValue > value)) {
-
- classes += " ui-slider-pip-inrange";
-
- }
-
- }
-
- }
-
-
-
- css = (slider.options.orientation === "horizontal") ?
- "left: " + percent :
- "bottom: " + percent;
-
-
- // add this current pip to the collection
- return "<span class=\"" + classes + "\" style=\"" + css + "\">" +
- "<span class=\"ui-slider-line\"></span>" +
- "<span class=\"ui-slider-label\" data-value=\"" +
- labelValue + "\">" + options.formatLabel(label) + "</span>" +
- "</span>";
-
- }
-
- // create our first pip
- collection += createPip("first");
-
- // for every stop in the slider where we need a pip; create one.
- for (p = slider.options.pipStep; p < pips; p += slider.options.pipStep) {
- collection += createPip(p);
- }
-
- // create our last pip
- collection += createPip("last");
-
- // append the collection of pips.
- slider.element.append(collection);
-
- // store the pips for setting classes later.
- $pips = slider.element.find(".ui-slider-pip");
-
-
-
- // store the mousedown handlers for later, just in case we reset
- // the slider, the handler would be lost!
-
- if ($._data(slider.element.get(0), "events").mousedown &&
- $._data(slider.element.get(0), "events").mousedown.length) {
-
- mousedownHandlers = $._data(slider.element.get(0), "events").mousedown;
-
- } else {
-
- mousedownHandlers = slider.element.data("mousedown-handlers");
-
- }
-
- slider.element.data("mousedown-handlers", mousedownHandlers.slice());
-
- // loop through all the mousedown handlers on the slider,
- // and store the original namespaced (.slider) event handler so
- // we can trigger it later.
- for (j = 0; j < mousedownHandlers.length; j++) {
- if (mousedownHandlers[j].namespace === "slider") {
- slider.element.data("mousedown-original", mousedownHandlers[j].handler);
- }
- }
-
- // unbind the mousedown.slider event, because it interferes with
- // the labelClick() method (stops smooth animation), and decide
- // if we want to trigger the original event based on which element
- // was clicked.
- slider.element
- .off("mousedown.slider")
- .on("mousedown.selectPip", function (e) {
-
- var $target = $(e.target),
- closest = getClosestHandle($target.data("value")),
- $handle = $handles.eq(closest);
-
- $handle.addClass("ui-state-active");
-
- if ($target.is(".ui-slider-label")) {
-
- labelClick($target, e);
-
- slider.element
- .one("mouseup.selectPip", function () {
-
- $handle
- .removeClass("ui-state-active")
- .focus();
-
- });
-
- } else {
-
- var originalMousedown = slider.element.data("mousedown-original");
- originalMousedown(e);
-
- }
-
- });
-
-
-
-
- slider.element.on("slide.selectPip slidechange.selectPip", function (e, ui) {
-
- var $slider = $(this),
- value = $slider.slider("value"),
- values = $slider.slider("values");
-
- if (ui) {
-
- value = ui.value;
- values = ui.values;
-
- }
-
- if (slider.values() && slider.values().length) {
-
- selectPip.range(values);
-
- } else {
-
- selectPip.single(value);
-
- }
-
- });
-
-
-
-
- },
-
-
-
-
-
-
-
-
- // floats
-
- float: function (settings) {
-
- var i,
- slider = this,
- min = slider._valueMin(),
- max = slider._valueMax(),
- value = slider._value(),
- values = slider._values(),
- tipValues = [],
- $handles = slider.element.find(".ui-slider-handle");
-
- var options = {
-
- handle: true,
- /* false */
-
- pips: false,
- /* true */
-
- labels: false,
- /* [array], { first: "string", rest: [array], last: "string" }, false */
-
- prefix: "",
- /* "", string */
-
- suffix: "",
- /* "", string */
-
- event: "slidechange slide",
- /* "slidechange", "slide", "slidechange slide" */
-
- formatLabel: function (value) {
- return this.prefix + value + this.suffix;
- }
- /* function
- must return a value to display in the floats */
-
- };
-
- if ($.type(settings) === "object" || $.type(settings) === "undefined") {
-
- $.extend(options, settings);
- slider.element.data("float-options", options);
-
- } else {
-
- if (settings === "destroy") {
-
- destroy();
-
- } else if (settings === "refresh") {
-
- slider.element.slider("float", slider.element.data("float-options"));
-
- }
-
- return;
-
- }
-
-
-
-
- if (value < min) {
- value = min;
- }
-
- if (value > max) {
- value = max;
- }
-
- if (values && values.length) {
-
- for (i = 0; i < values.length; i++) {
-
- if (values[i] < min) {
- values[i] = min;
- }
-
- if (values[i] > max) {
- values[i] = max;
- }
-
- }
-
- }
-
- // add a class for the CSS
- slider.element
- .addClass("ui-slider-float")
- .find(".ui-slider-tip, .ui-slider-tip-label")
- .remove();
-
-
-
- function destroy() {
-
- slider.element
- .off(".sliderFloat")
- .removeClass("ui-slider-float")
- .find(".ui-slider-tip, .ui-slider-tip-label")
- .remove();
-
- }
-
-
- function getPipLabels(values) {
-
- // when checking the array we need to divide
- // by the step option, so we store those values here.
-
- var vals = [],
- steppedVals = $.map(values, function (v) {
- return Math.ceil((v - min) / slider.options.step);
- });
-
- // now we just get the values we need to return
- // by looping through the values array and assigning the
- // label if it exists.
-
- if ($.type(options.labels) === "array") {
-
- for (i = 0; i < values.length; i++) {
-
- vals[i] = options.labels[steppedVals[i]] || values[i];
-
- }
-
- } else if ($.type(options.labels) === "object") {
-
- for (i = 0; i < values.length; i++) {
-
- if (values[i] === min) {
-
- vals[i] = options.labels.first || min;
-
- } else if (values[i] === max) {
-
- vals[i] = options.labels.last || max;
-
- } else if ($.type(options.labels.rest) === "array") {
-
- vals[i] = options.labels.rest[steppedVals[i] - 1] || values[i];
-
- } else {
-
- vals[i] = values[i];
-
- }
-
- }
-
- } else {
-
- for (i = 0; i < values.length; i++) {
-
- vals[i] = values[i];
-
- }
-
- }
-
- return vals;
-
- }
-
- // apply handle tip if settings allows.
- if (options.handle) {
-
- // we need to set the human-readable label to either the
- // corresponding element in the array, or the appropriate
- // item in the object... or an empty string.
-
- tipValues = (slider.values() && slider.values().length) ?
- getPipLabels(values) :
- getPipLabels([value]);
-
- for (i = 0; i < tipValues.length; i++) {
-
- $handles
- .eq(i)
- .append($("<span class=\"ui-slider-tip\">" + options.formatLabel(tipValues[i]) + "</span>"));
-
- }
-
- }
-
- if (options.pips) {
-
- // if this slider also has pip-labels, we make those into tips, too.
- slider.element.find(".ui-slider-label").each(function (k, v) {
-
- var $this = $(v),
- val = [$this.data("value")],
- label,
- $tip;
-
-
- label = options.formatLabel(getPipLabels(val)[0]);
-
- // create a tip element
- $tip =
- $("<span class=\"ui-slider-tip-label\">" + label + "</span>")
- .insertAfter($this);
-
- });
-
- }
-
- // check that the event option is actually valid against our
- // own list of the slider's events.
- if (options.event !== "slide" &&
- options.event !== "slidechange" &&
- options.event !== "slide slidechange" &&
- options.event !== "slidechange slide") {
-
- options.event = "slidechange slide";
-
- }
-
- // when slider changes, update handle tip label.
- slider.element
- .off(".sliderFloat")
- .on(options.event + ".sliderFloat", function (e, ui) {
-
- var uiValue = ($.type(ui.value) === "array") ? ui.value : [ui.value],
- val = options.formatLabel(getPipLabels(uiValue)[0]);
-
- $(ui.handle)
- .find(".ui-slider-tip")
- .html(val);
-
- });
-
- }
-
- };
-
- $.extend(true, $.ui.slider.prototype, extensionMethods);
-
- })(jQuery);
|