DotaNoobs main site.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

538 lines
15 KiB

  1. /*! UIkit 2.5.0 | http://www.getuikit.com | (c) 2014 YOOtheme | MIT License */
  2. /*
  3. * Based on https://github.com/jdewit/bootstrap-timepicker
  4. */
  5. (function(addon) {
  6. if (typeof define == "function" && define.amd) { // AMD
  7. define("uikit-timepicker", ["uikit"], function(){
  8. return jQuery.UIkit.timepicker || addon(window, window.jQuery, window.jQuery.UIkit);
  9. });
  10. }
  11. if(window && window.jQuery && window.jQuery.UIkit) {
  12. addon(window, window.jQuery, window.jQuery.UIkit);
  13. }
  14. })(function(global, $, UI){
  15. // Timepicker
  16. var TimePicker = function(element, options) {
  17. var $this = this, $element = $(element);
  18. if($element.data("timepicker")) return;
  19. this.$element = $element;
  20. this.element = this.$element[0];
  21. this.options = $.extend({}, TimePicker.defaults, options);
  22. this.$element.on({
  23. 'focus.timepicker.uikit' : $.proxy(this.highlightUnit, this),
  24. 'click.timepicker.uikit' : $.proxy(this.highlightUnit, this),
  25. 'keydown.timepicker.uikit': $.proxy(this.onKeydown, this),
  26. 'blur.timepicker.uikit' : $.proxy(this.blurElement, this)
  27. });
  28. this.setDefaultTime(this.options.defaultTime);
  29. this.$element.data("timepicker", this);
  30. };
  31. TimePicker.defaults = {
  32. defaultTime: 'current',
  33. disableFocus: false,
  34. minuteStep: 15,
  35. secondStep: 15,
  36. showSeconds: false,
  37. showMeridian: false
  38. };
  39. $.extend(TimePicker.prototype, {
  40. setDefaultTime: function(defaultTime){
  41. if (!this.element.value) {
  42. if (defaultTime === 'current') {
  43. var d = new Date();
  44. this.hour = d.getHours(),
  45. this.minute = Math.floor(d.getMinutes() / this.options.minuteStep) * this.options.minuteStep,
  46. this.second = Math.floor(d.getSeconds() / this.options.secondStep) * this.options.secondStep,
  47. this.meridian = 'AM';
  48. if (this.options.showMeridian) {
  49. if (this.hour === 0) {
  50. this.hour = 12;
  51. } else if (this.hour >= 12) {
  52. if (this.hour > 12) this.hour = this.hour - 12;
  53. this.meridian = 'PM';
  54. } else {
  55. this.meridian = 'AM';
  56. }
  57. }
  58. this.update();
  59. } else if (defaultTime === false) {
  60. this.hour = 0;
  61. this.minute = 0;
  62. this.second = 0;
  63. this.meridian = 'AM';
  64. } else {
  65. this.setTime(defaultTime);
  66. }
  67. } else {
  68. this.updateFromElementVal();
  69. }
  70. },
  71. setTime: function(time) {
  72. var arr, timeArray;
  73. if (this.options.showMeridian) {
  74. arr = time.split(' ');
  75. timeArray = arr[0].split(':');
  76. this.meridian = arr[1];
  77. } else {
  78. timeArray = time.split(':');
  79. }
  80. this.hour = parseInt(timeArray[0], 10);
  81. this.minute = parseInt(timeArray[1], 10);
  82. this.second = parseInt(timeArray[2], 10);
  83. if (isNaN(this.hour)) this.hour = 0;
  84. if (isNaN(this.minute)) this.minute = 0;
  85. if (this.options.showMeridian) {
  86. if (this.hour > 12) {
  87. this.hour = 12;
  88. } else if (this.hour < 1) {
  89. this.hour = 12;
  90. }
  91. if (this.meridian === 'am' || this.meridian === 'a') {
  92. this.meridian = 'AM';
  93. } else if (this.meridian === 'pm' || this.meridian === 'p') {
  94. this.meridian = 'PM';
  95. }
  96. if (this.meridian !== 'AM' && this.meridian !== 'PM') {
  97. this.meridian = 'AM';
  98. }
  99. } else {
  100. if (this.hour >= 24) {
  101. this.hour = 23;
  102. } else if (this.hour < 0) {
  103. this.hour = 0;
  104. }
  105. }
  106. if (this.minute < 0) {
  107. this.minute = 0;
  108. } else if (this.minute >= 60) {
  109. this.minute = 59;
  110. }
  111. if (this.options.showSeconds) {
  112. if (isNaN(this.second)) {
  113. this.second = 0;
  114. } else if (this.second < 0) {
  115. this.second = 0;
  116. } else if (this.second >= 60) {
  117. this.second = 59;
  118. }
  119. }
  120. this.update();
  121. },
  122. blurElement: function() {
  123. this.highlightedUnit = undefined;
  124. this.updateFromElementVal();
  125. },
  126. decrementHour: function(noupdate) {
  127. if (this.options.showMeridian) {
  128. if (this.hour === 1) {
  129. this.hour = 12;
  130. } else if (this.hour === 12) {
  131. this.hour--;
  132. return this.toggleMeridian();
  133. } else if (this.hour === 0) {
  134. this.hour = 11;
  135. return this.toggleMeridian();
  136. } else {
  137. this.hour--;
  138. }
  139. } else {
  140. if (this.hour === 0) {
  141. this.hour = 23;
  142. } else {
  143. this.hour--;
  144. }
  145. }
  146. if(!noupdate) this.update();
  147. },
  148. decrementMinute: function(step) {
  149. var newVal = (step) ? this.minute - step : this.minute - this.options.minuteStep;
  150. if (newVal < 0) {
  151. this.decrementHour(true);
  152. this.minute = newVal + 60;
  153. } else {
  154. this.minute = newVal;
  155. }
  156. this.update();
  157. },
  158. decrementSecond: function() {
  159. var newVal = this.second - this.options.secondStep;
  160. if (newVal < 0) {
  161. this.decrementMinute(true);
  162. this.second = newVal + 60;
  163. } else {
  164. this.second = newVal;
  165. }
  166. this.update();
  167. },
  168. onKeydown: function(e) {
  169. switch (e.keyCode) {
  170. case 9: //tab
  171. this.updateFromElementVal();
  172. switch (this.highlightedUnit) {
  173. case 'hour':
  174. e.preventDefault();
  175. this.highlightNextUnit();
  176. break;
  177. case 'minute':
  178. if (this.options.showMeridian || this.options.showSeconds) {
  179. e.preventDefault();
  180. this.highlightNextUnit();
  181. }
  182. break;
  183. case 'second':
  184. if (this.options.showMeridian) {
  185. e.preventDefault();
  186. this.highlightNextUnit();
  187. }
  188. break;
  189. }
  190. break;
  191. case 27: // escape
  192. this.updateFromElementVal();
  193. break;
  194. case 37: // left arrow
  195. e.preventDefault();
  196. this.highlightPrevUnit();
  197. this.updateFromElementVal();
  198. break;
  199. case 38: // up arrow
  200. e.preventDefault();
  201. switch (this.highlightedUnit) {
  202. case 'hour':
  203. this.incrementHour();
  204. this.highlightHour();
  205. break;
  206. case 'minute':
  207. this.incrementMinute();
  208. this.highlightMinute();
  209. break;
  210. case 'second':
  211. this.incrementSecond();
  212. this.highlightSecond();
  213. break;
  214. case 'meridian':
  215. this.toggleMeridian();
  216. this.highlightMeridian();
  217. break;
  218. }
  219. break;
  220. case 39: // right arrow
  221. e.preventDefault();
  222. this.updateFromElementVal();
  223. this.highlightNextUnit();
  224. break;
  225. case 40: // down arrow
  226. e.preventDefault();
  227. switch (this.highlightedUnit) {
  228. case 'hour':
  229. this.decrementHour();
  230. this.highlightHour();
  231. break;
  232. case 'minute':
  233. this.decrementMinute();
  234. this.highlightMinute();
  235. break;
  236. case 'second':
  237. this.decrementSecond();
  238. this.highlightSecond();
  239. break;
  240. case 'meridian':
  241. this.toggleMeridian();
  242. this.highlightMeridian();
  243. break;
  244. }
  245. break;
  246. }
  247. },
  248. formatTime: function(hour, minute, second, meridian) {
  249. hour = hour < 10 ? '0' + hour : hour;
  250. minute = minute < 10 ? '0' + minute : minute;
  251. second = second < 10 ? '0' + second : second;
  252. return hour + ':' + minute + (this.options.showSeconds ? ':' + second : '') + (this.options.showMeridian ? ' ' + meridian : '');
  253. },
  254. getCursorPosition: function() {
  255. if ('selectionStart' in this.element) {// Standard-compliant browsers
  256. return this.element.selectionStart;
  257. } else if (document.selection) {// IE fix
  258. this.element.focus();
  259. var sel = document.selection.createRange(),
  260. selLen = document.selection.createRange().text.length;
  261. sel.moveStart('character', - this.element.value.length);
  262. return sel.text.length - selLen;
  263. }
  264. },
  265. getTime: function() {
  266. return this.formatTime(this.hour, this.minute, this.second, this.meridian);
  267. },
  268. highlightUnit: function() {
  269. this.position = this.getCursorPosition();
  270. if (this.position >= 0 && this.position <= 2) {
  271. this.highlightHour();
  272. } else if (this.position >= 3 && this.position <= 5) {
  273. this.highlightMinute();
  274. } else if (this.position >= 6 && this.position <= 8) {
  275. if (this.options.showSeconds) {
  276. this.highlightSecond();
  277. } else {
  278. this.highlightMeridian();
  279. }
  280. } else if (this.position >= 9 && this.position <= 11) {
  281. this.highlightMeridian();
  282. }
  283. },
  284. highlightNextUnit: function() {
  285. switch (this.highlightedUnit) {
  286. case 'hour':
  287. this.highlightMinute();
  288. break;
  289. case 'minute':
  290. if (this.options.showSeconds) {
  291. this.highlightSecond();
  292. } else if (this.options.showMeridian){
  293. this.highlightMeridian();
  294. } else {
  295. this.highlightHour();
  296. }
  297. break;
  298. case 'second':
  299. if (this.options.showMeridian) {
  300. this.highlightMeridian();
  301. } else {
  302. this.highlightHour();
  303. }
  304. break;
  305. case 'meridian':
  306. this.highlightHour();
  307. break;
  308. }
  309. },
  310. highlightPrevUnit: function() {
  311. switch (this.highlightedUnit) {
  312. case 'hour':
  313. this.highlightMeridian();
  314. break;
  315. case 'minute':
  316. this.highlightHour();
  317. break;
  318. case 'second':
  319. this.highlightMinute();
  320. break;
  321. case 'meridian':
  322. if (this.options.showSeconds) {
  323. this.highlightSecond();
  324. } else {
  325. this.highlightMinute();
  326. }
  327. break;
  328. }
  329. },
  330. highlightHour: function() {
  331. var $element = this.element;
  332. this.highlightedUnit = 'hour';
  333. if ($element.setSelectionRange) {
  334. setTimeout(function() {
  335. $element.setSelectionRange(0,2);
  336. }, 0);
  337. }
  338. },
  339. highlightMinute: function() {
  340. var $element = this.element;
  341. this.highlightedUnit = 'minute';
  342. if ($element.setSelectionRange) {
  343. setTimeout(function() {
  344. $element.setSelectionRange(3,5);
  345. }, 0);
  346. }
  347. },
  348. highlightSecond: function() {
  349. var $element = this.element;
  350. this.highlightedUnit = 'second';
  351. if ($element.setSelectionRange) {
  352. setTimeout(function() {
  353. $element.setSelectionRange(6,8);
  354. }, 0);
  355. }
  356. },
  357. highlightMeridian: function() {
  358. var $element = this.element;
  359. this.highlightedUnit = 'meridian';
  360. if ($element.setSelectionRange) {
  361. if (this.options.showSeconds) {
  362. setTimeout(function() {
  363. $element.setSelectionRange(9,11);
  364. }, 0);
  365. } else {
  366. setTimeout(function() {
  367. $element.setSelectionRange(6,8);
  368. }, 0);
  369. }
  370. }
  371. },
  372. incrementHour: function(noupdate) {
  373. if (this.options.showMeridian) {
  374. if (this.hour === 11) {
  375. this.hour++;
  376. return this.toggleMeridian();
  377. } else if (this.hour === 12) {
  378. this.hour = 0;
  379. }
  380. }
  381. if (this.hour === 23) {
  382. this.hour = 0;
  383. return;
  384. }
  385. this.hour++;
  386. if(!noupdate) this.update();
  387. },
  388. incrementMinute: function(step) {
  389. var newVal = step ? (this.minute + step) : (this.minute + this.options.minuteStep - (this.minute % this.options.minuteStep));
  390. if (newVal > 59) {
  391. this.incrementHour(true);
  392. this.minute = newVal - 60;
  393. } else {
  394. this.minute = newVal;
  395. }
  396. this.update();
  397. },
  398. incrementSecond: function() {
  399. var newVal = this.second + this.options.secondStep - (this.second % this.options.secondStep);
  400. if (newVal > 59) {
  401. this.incrementMinute(true);
  402. this.second = newVal - 60;
  403. } else {
  404. this.second = newVal;
  405. }
  406. this.update();
  407. },
  408. remove: function() {
  409. $('document').off('.timepicker.uikit');
  410. delete this.$element.data().timepicker;
  411. },
  412. toggleMeridian: function() {
  413. this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
  414. this.update();
  415. },
  416. update: function() {
  417. this.$element.trigger({
  418. 'type': 'changeTime.timepicker',
  419. 'time': {
  420. 'value': this.getTime(),
  421. 'hours': this.hour,
  422. 'minutes': this.minute,
  423. 'seconds': this.second,
  424. 'meridian': this.meridian
  425. }
  426. });
  427. this.updateElement();
  428. },
  429. updateElement: function() {
  430. this.$element.val(this.getTime()).trigger("change");
  431. },
  432. updateFromElementVal: function() {
  433. if (this.element.value) this.setTime(this.element.value);
  434. }
  435. });
  436. // init code
  437. $(document).on("focus.timepicker.uikit", "[data-uk-timepicker]", function(e) {
  438. var ele = $(this);
  439. if (!ele.data("timepicker")) {
  440. e.preventDefault();
  441. var obj = new TimePicker(ele, UI.Utils.options(ele.attr("data-uk-timepicker")));
  442. ele.trigger("focus");
  443. }
  444. });
  445. UI["timepicker"] = TimePicker;
  446. return TimePicker;
  447. });