My personal site (brandoncornejo.name) (binaryatrocity.name)
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.

520 lines
14 KiB

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