Built files from Bizgaze WebServer
Vous ne pouvez pas sélectionner plus de 25 sujets Les noms de sujets doivent commencer par une lettre ou un nombre, peuvent contenir des tirets ('-') et peuvent comporter jusqu'à 35 caractères.

jquery-ui-slider-pips.js 23KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812
  1. /*! jQuery-ui-Slider-Pips - v1.11.4 - 2016-09-04
  2. * Copyright (c) 2016 Simon Goellner <simey.me@gmail.com>; Licensed MIT */
  3. (function ($) {
  4. "use strict";
  5. var extensionMethods = {
  6. // pips
  7. pips: function (settings) {
  8. var slider = this,
  9. i, j, p,
  10. collection = "",
  11. mousedownHandlers,
  12. min = slider._valueMin(),
  13. max = slider._valueMax(),
  14. pips = (max - min) / slider.options.step,
  15. $handles = slider.element.find(".ui-slider-handle"),
  16. $pips;
  17. var options = {
  18. first: "label",
  19. /* "label", "pip", false */
  20. last: "label",
  21. /* "label", "pip", false */
  22. rest: "pip",
  23. /* "label", "pip", false */
  24. labels: false,
  25. /* [array], { first: "string", rest: [array], last: "string" }, false */
  26. prefix: "",
  27. /* "", string */
  28. suffix: "",
  29. /* "", string */
  30. step: (pips > 100) ? Math.floor(pips * 0.05) : 1,
  31. /* number */
  32. formatLabel: function (value) {
  33. return this.prefix + value + this.suffix;
  34. }
  35. /* function
  36. must return a value to display in the pip labels */
  37. };
  38. if ($.type(settings) === "object" || $.type(settings) === "undefined") {
  39. $.extend(options, settings);
  40. slider.element.data("pips-options", options);
  41. } else {
  42. if (settings === "destroy") {
  43. destroy();
  44. } else if (settings === "refresh") {
  45. slider.element.slider("pips", slider.element.data("pips-options"));
  46. }
  47. return;
  48. }
  49. // we don't want the step ever to be a floating point or negative
  50. // (or 0 actually, so we'll set it to 1 in that case).
  51. slider.options.pipStep = Math.abs(Math.round(options.step)) || 1;
  52. // get rid of all pips that might already exist.
  53. slider.element
  54. .off(".selectPip")
  55. .addClass("ui-slider-pips")
  56. .find(".ui-slider-pip")
  57. .remove();
  58. // small object with functions for marking pips as selected.
  59. var selectPip = {
  60. single: function (value) {
  61. this.resetClasses();
  62. $pips
  63. .filter(".ui-slider-pip-" + this.classLabel(value))
  64. .addClass("ui-slider-pip-selected");
  65. if (slider.options.range) {
  66. $pips.each(function (k, v) {
  67. var pipVal = $(v).children(".ui-slider-label").data("value");
  68. if ((slider.options.range === "min" && pipVal < value) ||
  69. (slider.options.range === "max" && pipVal > value)) {
  70. $(v).addClass("ui-slider-pip-inrange");
  71. }
  72. });
  73. }
  74. },
  75. range: function (values) {
  76. this.resetClasses();
  77. for (i = 0; i < values.length; i++) {
  78. $pips
  79. .filter(".ui-slider-pip-" + this.classLabel(values[i]))
  80. .addClass("ui-slider-pip-selected-" + (i + 1));
  81. }
  82. if (slider.options.range) {
  83. $pips.each(function (k, v) {
  84. var pipVal = $(v).children(".ui-slider-label").data("value");
  85. if (pipVal > values[0] && pipVal < values[1]) {
  86. $(v).addClass("ui-slider-pip-inrange");
  87. }
  88. });
  89. }
  90. },
  91. classLabel: function (value) {
  92. return value.toString().replace(".", "-");
  93. },
  94. resetClasses: function () {
  95. var regex = /(^|\s*)(ui-slider-pip-selected|ui-slider-pip-inrange)(-{1,2}\d+|\s|$)/gi;
  96. $pips.removeClass(function (index, css) {
  97. return (css.match(regex) || []).join(" ");
  98. });
  99. }
  100. };
  101. function getClosestHandle(val) {
  102. var h, k,
  103. sliderVals,
  104. comparedVals,
  105. closestVal,
  106. tempHandles = [],
  107. closestHandle = 0;
  108. if (slider.values() && slider.values().length) {
  109. // get the current values of the slider handles
  110. sliderVals = slider.values();
  111. // find the offset value from the `val` for each
  112. // handle, and store it in a new array
  113. comparedVals = $.map(sliderVals, function (v) {
  114. return Math.abs(v - val);
  115. });
  116. // figure out the closest handles to the value
  117. closestVal = Math.min.apply(Math, comparedVals);
  118. // if a comparedVal is the closestVal, then
  119. // set the value accordingly, and set the closest handle.
  120. for (h = 0; h < comparedVals.length; h++) {
  121. if (comparedVals[h] === closestVal) {
  122. tempHandles.push(h);
  123. }
  124. }
  125. // set the closest handle to the first handle in array,
  126. // just incase we have no _lastChangedValue to compare to.
  127. closestHandle = tempHandles[0];
  128. // now we want to find out if any of the closest handles were
  129. // the last changed handle, if so we specify that handle to change
  130. for (k = 0; k < tempHandles.length; k++) {
  131. if (slider._lastChangedValue === tempHandles[k]) {
  132. closestHandle = tempHandles[k];
  133. }
  134. }
  135. if (slider.options.range && tempHandles.length === 2) {
  136. if (val > sliderVals[1]) {
  137. closestHandle = tempHandles[1];
  138. } else if (val < sliderVals[0]) {
  139. closestHandle = tempHandles[0];
  140. }
  141. }
  142. }
  143. return closestHandle;
  144. }
  145. function destroy() {
  146. slider.element
  147. .off(".selectPip")
  148. .on("mousedown.slider", slider.element.data("mousedown-original"))
  149. .removeClass("ui-slider-pips")
  150. .find(".ui-slider-pip")
  151. .remove();
  152. }
  153. // when we click on a label, we want to make sure the
  154. // slider's handle actually goes to that label!
  155. // so we check all the handles and see which one is closest
  156. // to the label we clicked. If 2 handles are equidistant then
  157. // we move both of them. We also want to trigger focus on the
  158. // handle.
  159. // without this method the label is just treated like a part
  160. // of the slider and there's no accuracy in the selected value
  161. function labelClick(label, e) {
  162. if (slider.option("disabled")) {
  163. return;
  164. }
  165. var val = $(label).data("value"),
  166. indexToChange = getClosestHandle(val);
  167. if (slider.values() && slider.values().length) {
  168. slider.options.values[indexToChange] = slider._trimAlignValue(val);
  169. } else {
  170. slider.options.value = slider._trimAlignValue(val);
  171. }
  172. slider._refreshValue();
  173. slider._change(e, indexToChange);
  174. }
  175. // method for creating a pip. We loop this for creating all
  176. // the pips.
  177. function createPip(which) {
  178. var label,
  179. percent,
  180. number = which,
  181. classes = "ui-slider-pip",
  182. css = "",
  183. value = slider.value(),
  184. values = slider.values(),
  185. labelValue,
  186. classLabel,
  187. labelIndex;
  188. if (which === "first") {
  189. number = 0;
  190. } else if (which === "last") {
  191. number = pips;
  192. }
  193. // labelValue is the actual value of the pip based on the min/step
  194. labelValue = min + (slider.options.step * number);
  195. // classLabel replaces any decimals with hyphens
  196. classLabel = labelValue.toString().replace(".", "-");
  197. // get the index needed for selecting labels out of the array
  198. labelIndex = (number + min) - min;
  199. // we need to set the human-readable label to either the
  200. // corresponding element in the array, or the appropriate
  201. // item in the object... or an empty string.
  202. if ($.type(options.labels) === "array") {
  203. label = options.labels[labelIndex] || "";
  204. } else if ($.type(options.labels) === "object") {
  205. if (which === "first") {
  206. // set first label
  207. label = options.labels.first || "";
  208. } else if (which === "last") {
  209. // set last label
  210. label = options.labels.last || "";
  211. } else if ($.type(options.labels.rest) === "array") {
  212. // set other labels, but our index should start at -1
  213. // because of the first pip.
  214. label = options.labels.rest[labelIndex - 1] || "";
  215. } else {
  216. // urrggh, the options must be f**ked, just show nothing.
  217. label = labelValue;
  218. }
  219. } else {
  220. label = labelValue;
  221. }
  222. if (which === "first") {
  223. // first Pip on the Slider
  224. percent = "0%";
  225. classes += " ui-slider-pip-first";
  226. classes += (options.first === "label") ? " ui-slider-pip-label" : "";
  227. classes += (options.first === false) ? " ui-slider-pip-hide" : "";
  228. } else if (which === "last") {
  229. // last Pip on the Slider
  230. percent = "100%";
  231. classes += " ui-slider-pip-last";
  232. classes += (options.last === "label") ? " ui-slider-pip-label" : "";
  233. classes += (options.last === false) ? " ui-slider-pip-hide" : "";
  234. } else {
  235. // all other Pips
  236. percent = ((100 / pips) * which).toFixed(4) + "%";
  237. classes += (options.rest === "label") ? " ui-slider-pip-label" : "";
  238. classes += (options.rest === false) ? " ui-slider-pip-hide" : "";
  239. }
  240. classes += " ui-slider-pip-" + classLabel;
  241. // add classes for the initial-selected values.
  242. if (values && values.length) {
  243. for (i = 0; i < values.length; i++) {
  244. if (labelValue === values[i]) {
  245. classes += " ui-slider-pip-initial-" + (i + 1);
  246. classes += " ui-slider-pip-selected-" + (i + 1);
  247. }
  248. }
  249. if (slider.options.range) {
  250. if (labelValue > values[0] &&
  251. labelValue < values[1]) {
  252. classes += " ui-slider-pip-inrange";
  253. }
  254. }
  255. } else {
  256. if (labelValue === value) {
  257. classes += " ui-slider-pip-initial";
  258. classes += " ui-slider-pip-selected";
  259. }
  260. if (slider.options.range) {
  261. if ((slider.options.range === "min" && labelValue < value) ||
  262. (slider.options.range === "max" && labelValue > value)) {
  263. classes += " ui-slider-pip-inrange";
  264. }
  265. }
  266. }
  267. css = (slider.options.orientation === "horizontal") ?
  268. "left: " + percent :
  269. "bottom: " + percent;
  270. // add this current pip to the collection
  271. return "<span class=\"" + classes + "\" style=\"" + css + "\">" +
  272. "<span class=\"ui-slider-line\"></span>" +
  273. "<span class=\"ui-slider-label\" data-value=\"" +
  274. labelValue + "\">" + options.formatLabel(label) + "</span>" +
  275. "</span>";
  276. }
  277. // create our first pip
  278. collection += createPip("first");
  279. // for every stop in the slider where we need a pip; create one.
  280. for (p = slider.options.pipStep; p < pips; p += slider.options.pipStep) {
  281. collection += createPip(p);
  282. }
  283. // create our last pip
  284. collection += createPip("last");
  285. // append the collection of pips.
  286. slider.element.append(collection);
  287. // store the pips for setting classes later.
  288. $pips = slider.element.find(".ui-slider-pip");
  289. // store the mousedown handlers for later, just in case we reset
  290. // the slider, the handler would be lost!
  291. if ($._data(slider.element.get(0), "events").mousedown &&
  292. $._data(slider.element.get(0), "events").mousedown.length) {
  293. mousedownHandlers = $._data(slider.element.get(0), "events").mousedown;
  294. } else {
  295. mousedownHandlers = slider.element.data("mousedown-handlers");
  296. }
  297. slider.element.data("mousedown-handlers", mousedownHandlers.slice());
  298. // loop through all the mousedown handlers on the slider,
  299. // and store the original namespaced (.slider) event handler so
  300. // we can trigger it later.
  301. for (j = 0; j < mousedownHandlers.length; j++) {
  302. if (mousedownHandlers[j].namespace === "slider") {
  303. slider.element.data("mousedown-original", mousedownHandlers[j].handler);
  304. }
  305. }
  306. // unbind the mousedown.slider event, because it interferes with
  307. // the labelClick() method (stops smooth animation), and decide
  308. // if we want to trigger the original event based on which element
  309. // was clicked.
  310. slider.element
  311. .off("mousedown.slider")
  312. .on("mousedown.selectPip", function (e) {
  313. var $target = $(e.target),
  314. closest = getClosestHandle($target.data("value")),
  315. $handle = $handles.eq(closest);
  316. $handle.addClass("ui-state-active");
  317. if ($target.is(".ui-slider-label")) {
  318. labelClick($target, e);
  319. slider.element
  320. .one("mouseup.selectPip", function () {
  321. $handle
  322. .removeClass("ui-state-active")
  323. .focus();
  324. });
  325. } else {
  326. var originalMousedown = slider.element.data("mousedown-original");
  327. originalMousedown(e);
  328. }
  329. });
  330. slider.element.on("slide.selectPip slidechange.selectPip", function (e, ui) {
  331. var $slider = $(this),
  332. value = $slider.slider("value"),
  333. values = $slider.slider("values");
  334. if (ui) {
  335. value = ui.value;
  336. values = ui.values;
  337. }
  338. if (slider.values() && slider.values().length) {
  339. selectPip.range(values);
  340. } else {
  341. selectPip.single(value);
  342. }
  343. });
  344. },
  345. // floats
  346. float: function (settings) {
  347. var i,
  348. slider = this,
  349. min = slider._valueMin(),
  350. max = slider._valueMax(),
  351. value = slider._value(),
  352. values = slider._values(),
  353. tipValues = [],
  354. $handles = slider.element.find(".ui-slider-handle");
  355. var options = {
  356. handle: true,
  357. /* false */
  358. pips: false,
  359. /* true */
  360. labels: false,
  361. /* [array], { first: "string", rest: [array], last: "string" }, false */
  362. prefix: "",
  363. /* "", string */
  364. suffix: "",
  365. /* "", string */
  366. event: "slidechange slide",
  367. /* "slidechange", "slide", "slidechange slide" */
  368. formatLabel: function (value) {
  369. return this.prefix + value + this.suffix;
  370. }
  371. /* function
  372. must return a value to display in the floats */
  373. };
  374. if ($.type(settings) === "object" || $.type(settings) === "undefined") {
  375. $.extend(options, settings);
  376. slider.element.data("float-options", options);
  377. } else {
  378. if (settings === "destroy") {
  379. destroy();
  380. } else if (settings === "refresh") {
  381. slider.element.slider("float", slider.element.data("float-options"));
  382. }
  383. return;
  384. }
  385. if (value < min) {
  386. value = min;
  387. }
  388. if (value > max) {
  389. value = max;
  390. }
  391. if (values && values.length) {
  392. for (i = 0; i < values.length; i++) {
  393. if (values[i] < min) {
  394. values[i] = min;
  395. }
  396. if (values[i] > max) {
  397. values[i] = max;
  398. }
  399. }
  400. }
  401. // add a class for the CSS
  402. slider.element
  403. .addClass("ui-slider-float")
  404. .find(".ui-slider-tip, .ui-slider-tip-label")
  405. .remove();
  406. function destroy() {
  407. slider.element
  408. .off(".sliderFloat")
  409. .removeClass("ui-slider-float")
  410. .find(".ui-slider-tip, .ui-slider-tip-label")
  411. .remove();
  412. }
  413. function getPipLabels(values) {
  414. // when checking the array we need to divide
  415. // by the step option, so we store those values here.
  416. var vals = [],
  417. steppedVals = $.map(values, function (v) {
  418. return Math.ceil((v - min) / slider.options.step);
  419. });
  420. // now we just get the values we need to return
  421. // by looping through the values array and assigning the
  422. // label if it exists.
  423. if ($.type(options.labels) === "array") {
  424. for (i = 0; i < values.length; i++) {
  425. vals[i] = options.labels[steppedVals[i]] || values[i];
  426. }
  427. } else if ($.type(options.labels) === "object") {
  428. for (i = 0; i < values.length; i++) {
  429. if (values[i] === min) {
  430. vals[i] = options.labels.first || min;
  431. } else if (values[i] === max) {
  432. vals[i] = options.labels.last || max;
  433. } else if ($.type(options.labels.rest) === "array") {
  434. vals[i] = options.labels.rest[steppedVals[i] - 1] || values[i];
  435. } else {
  436. vals[i] = values[i];
  437. }
  438. }
  439. } else {
  440. for (i = 0; i < values.length; i++) {
  441. vals[i] = values[i];
  442. }
  443. }
  444. return vals;
  445. }
  446. // apply handle tip if settings allows.
  447. if (options.handle) {
  448. // we need to set the human-readable label to either the
  449. // corresponding element in the array, or the appropriate
  450. // item in the object... or an empty string.
  451. tipValues = (slider.values() && slider.values().length) ?
  452. getPipLabels(values) :
  453. getPipLabels([value]);
  454. for (i = 0; i < tipValues.length; i++) {
  455. $handles
  456. .eq(i)
  457. .append($("<span class=\"ui-slider-tip\">" + options.formatLabel(tipValues[i]) + "</span>"));
  458. }
  459. }
  460. if (options.pips) {
  461. // if this slider also has pip-labels, we make those into tips, too.
  462. slider.element.find(".ui-slider-label").each(function (k, v) {
  463. var $this = $(v),
  464. val = [$this.data("value")],
  465. label,
  466. $tip;
  467. label = options.formatLabel(getPipLabels(val)[0]);
  468. // create a tip element
  469. $tip =
  470. $("<span class=\"ui-slider-tip-label\">" + label + "</span>")
  471. .insertAfter($this);
  472. });
  473. }
  474. // check that the event option is actually valid against our
  475. // own list of the slider's events.
  476. if (options.event !== "slide" &&
  477. options.event !== "slidechange" &&
  478. options.event !== "slide slidechange" &&
  479. options.event !== "slidechange slide") {
  480. options.event = "slidechange slide";
  481. }
  482. // when slider changes, update handle tip label.
  483. slider.element
  484. .off(".sliderFloat")
  485. .on(options.event + ".sliderFloat", function (e, ui) {
  486. var uiValue = ($.type(ui.value) === "array") ? ui.value : [ui.value],
  487. val = options.formatLabel(getPipLabels(uiValue)[0]);
  488. $(ui.handle)
  489. .find(".ui-slider-tip")
  490. .html(val);
  491. });
  492. }
  493. };
  494. $.extend(true, $.ui.slider.prototype, extensionMethods);
  495. })(jQuery);