timepicker.js 30 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806
  1. /* =========================================================
  2. * bootstrap-timepicker.js
  3. * http://www.github.com/jdewit/bootstrap-timepicker
  4. * =========================================================
  5. * Copyright 2012
  6. *
  7. * Created By:
  8. * Joris de Wit @joris_dewit
  9. *
  10. * Contributions By:
  11. * Gilbert @mindeavor
  12. * Koen Punt info@koenpunt.nl
  13. * Nek
  14. * Chris Martin
  15. * Dominic Barnes contact@dominicbarnes.us
  16. * Olivier Louvignes @olouv
  17. *
  18. * Licensed under the Apache License, Version 2.0 (the "License");
  19. * you may not use this file except in compliance with the License.
  20. * You may obtain a copy of the License at
  21. *
  22. * http://www.apache.org/licenses/LICENSE-2.0
  23. *
  24. * Unless required by applicable law or agreed to in writing, software
  25. * distributed under the License is distributed on an "AS IS" BASIS,
  26. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  27. * See the License for the specific language governing permissions and
  28. * limitations under the License.
  29. * ========================================================= */
  30. !function($) {
  31. "use strict"; // jshint ;_;
  32. var isTouch = 'ontouchstart' in window;
  33. /* TIMEPICKER PUBLIC CLASS DEFINITION
  34. * ================================== */
  35. var Timepicker = function(element, options) {
  36. this.$element = $(element);
  37. this.options = $.extend({}, $.fn.timepicker.defaults, options, this.$element.data());
  38. this.minuteStep = this.options.minuteStep || this.minuteStep;
  39. this.secondStep = this.options.secondStep || this.secondStep;
  40. this.showMeridian = this.options.showMeridian || this.showMeridian;
  41. this.showSeconds = this.options.showSeconds || this.showSeconds;
  42. this.showInputs = this.options.showInputs || this.showInputs;
  43. this.disableFocus = this.options.disableFocus || this.disableFocus;
  44. this.template = this.options.template || this.template;
  45. this.modalBackdrop = this.options.modalBackdrop || this.modalBackdrop;
  46. this.defaultTime = this.options.defaultTime || this.defaultTime;
  47. this.open = false;
  48. this.init();
  49. };
  50. Timepicker.prototype = {
  51. constructor: Timepicker
  52. , init: function () {
  53. if (this.$element.parent().hasClass('input-append')) {
  54. this.$element.parent('.input-append').find('.add-on').on('click', $.proxy(this.showWidget, this));
  55. this.$element.on({
  56. focus: $.proxy(this.highlightUnit, this),
  57. click: $.proxy(this.highlightUnit, this),
  58. keydown: $.proxy(this.elementKeydown, this),
  59. blur: $.proxy(this.blurElement, this)
  60. });
  61. } else {
  62. if (this.template) {
  63. this.$element.on({
  64. focus: $.proxy(this.showWidget, this),
  65. click: $.proxy(this.showWidget, this),
  66. blur: $.proxy(this.blurElement, this)
  67. });
  68. } else {
  69. this.$element.on({
  70. focus: $.proxy(this.highlightUnit, this),
  71. click: $.proxy(this.highlightUnit, this),
  72. keydown: $.proxy(this.elementKeydown, this),
  73. blur: $.proxy(this.blurElement, this)
  74. });
  75. }
  76. }
  77. this.$widget = $(this.getTemplate()).appendTo('body');
  78. this.$widget.on('click', $.proxy(this.widgetClick, this));
  79. if (this.showInputs) {
  80. this.$widget.find('input').on({
  81. click: function() { this.select(); },
  82. keydown: $.proxy(this.widgetKeydown, this),
  83. change: $.proxy(this.updateFromWidgetInputs, this)
  84. });
  85. }
  86. this.setDefaultTime(this.defaultTime);
  87. }
  88. , showWidget: function(e) {
  89. e.stopPropagation();
  90. e.preventDefault();
  91. if (this.open) {
  92. return;
  93. }
  94. this.$element.trigger('show');
  95. if (isTouch || this.disableFocus) {
  96. this.$element.blur();
  97. }
  98. var pos = $.extend({}, this.$element.offset(), {
  99. height: this.$element[0].offsetHeight
  100. });
  101. this.updateFromElementVal();
  102. $('html')
  103. .one(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', $.proxy(this.hideWidget, this))
  104. .on(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', '.bootstrap-timepicker', function (e) { e.stopPropagation() });
  105. if (this.template === 'modal') {
  106. this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this));
  107. } else {
  108. this.$widget.css({
  109. top: pos.top + pos.height
  110. , left: pos.left
  111. })
  112. if (!this.open) {
  113. this.$widget.addClass('open');
  114. }
  115. }
  116. this.open = true;
  117. this.$element.trigger('shown');
  118. }
  119. , hideWidget: function(){
  120. this.$element.trigger('hide');
  121. if (this.template === 'modal') {
  122. this.$widget.modal('hide');
  123. } else {
  124. this.$widget.removeClass('open');
  125. }
  126. this.open = false;
  127. this.$element.trigger('hidden');
  128. }
  129. , widgetClick: function(e) {
  130. e.stopPropagation();
  131. e.preventDefault();
  132. var action = $(e.target).closest('a').data('action');
  133. if (action) {
  134. this[action]();
  135. this.update();
  136. }
  137. }
  138. , widgetKeydown: function(e) {
  139. var input = $(e.target).closest('input').attr('name');
  140. switch (e.keyCode) {
  141. case 9: //tab
  142. if (this.showMeridian) {
  143. if (input == 'meridian') {
  144. this.hideWidget();
  145. }
  146. } else {
  147. if (this.showSeconds) {
  148. if (input == 'second') {
  149. this.hideWidget();
  150. }
  151. } else {
  152. if (input == 'minute') {
  153. this.hideWidget();
  154. }
  155. }
  156. }
  157. break;
  158. case 27: // escape
  159. this.hideWidget();
  160. break;
  161. case 38: // up arrow
  162. switch (input) {
  163. case 'hour':
  164. this.incrementHour();
  165. break;
  166. case 'minute':
  167. this.incrementMinute();
  168. break;
  169. case 'second':
  170. this.incrementSecond();
  171. break;
  172. case 'meridian':
  173. this.toggleMeridian();
  174. break;
  175. }
  176. this.update();
  177. break;
  178. case 40: // down arrow
  179. switch (input) {
  180. case 'hour':
  181. this.decrementHour();
  182. break;
  183. case 'minute':
  184. this.decrementMinute();
  185. break;
  186. case 'second':
  187. this.decrementSecond();
  188. break;
  189. case 'meridian':
  190. this.toggleMeridian();
  191. break;
  192. }
  193. this.update();
  194. break;
  195. }
  196. }
  197. , elementKeydown: function(e) {
  198. var input = this.$element.get(0);
  199. switch (e.keyCode) {
  200. case 0: //input
  201. break;
  202. case 9: //tab
  203. this.updateFromElementVal();
  204. if (this.showMeridian) {
  205. if (this.highlightedUnit != 'meridian') {
  206. e.preventDefault();
  207. this.highlightNextUnit();
  208. }
  209. } else {
  210. if (this.showSeconds) {
  211. if (this.highlightedUnit != 'second') {
  212. e.preventDefault();
  213. this.highlightNextUnit();
  214. }
  215. } else {
  216. if (this.highlightedUnit != 'minute') {
  217. e.preventDefault();
  218. this.highlightNextUnit();
  219. }
  220. }
  221. }
  222. break;
  223. case 27: // escape
  224. this.updateFromElementVal();
  225. break;
  226. case 37: // left arrow
  227. this.updateFromElementVal();
  228. this.highlightPrevUnit();
  229. break;
  230. case 38: // up arrow
  231. switch (this.highlightedUnit) {
  232. case 'hour':
  233. this.incrementHour();
  234. break;
  235. case 'minute':
  236. this.incrementMinute();
  237. break;
  238. case 'second':
  239. this.incrementSecond();
  240. break;
  241. case 'meridian':
  242. this.toggleMeridian();
  243. break;
  244. }
  245. this.updateElement();
  246. break;
  247. case 39: // right arrow
  248. this.updateFromElementVal();
  249. this.highlightNextUnit();
  250. break;
  251. case 40: // down arrow
  252. switch (this.highlightedUnit) {
  253. case 'hour':
  254. this.decrementHour();
  255. break;
  256. case 'minute':
  257. this.decrementMinute();
  258. break;
  259. case 'second':
  260. this.decrementSecond();
  261. break;
  262. case 'meridian':
  263. this.toggleMeridian();
  264. break;
  265. }
  266. this.updateElement();
  267. break;
  268. }
  269. if (e.keyCode !== 0 && e.keyCode !== 8 && e.keyCode !== 9 && e.keyCode !== 46) {
  270. e.preventDefault();
  271. }
  272. }
  273. , setValues: function(time) {
  274. if (this.showMeridian) {
  275. var arr = time.split(' ');
  276. var timeArray = arr[0].split(':');
  277. this.meridian = arr[1];
  278. } else {
  279. var timeArray = time.split(':');
  280. }
  281. this.hour = parseInt(timeArray[0], 10);
  282. this.minute = parseInt(timeArray[1], 10);
  283. this.second = parseInt(timeArray[2], 10);
  284. if (isNaN(this.hour)) {
  285. this.hour = 0;
  286. }
  287. if (isNaN(this.minute)) {
  288. this.minute = 0;
  289. }
  290. if (this.showMeridian) {
  291. if (this.hour > 12) {
  292. this.hour = 12;
  293. } else if (this.hour < 1) {
  294. this.hour = 1;
  295. }
  296. if (this.meridian == 'am' || this.meridian == 'a') {
  297. this.meridian = 'AM';
  298. } else if (this.meridian == 'pm' || this.meridian == 'p') {
  299. this.meridian = 'PM';
  300. }
  301. if (this.meridian != 'AM' && this.meridian != 'PM') {
  302. this.meridian = 'AM';
  303. }
  304. } else {
  305. if (this.hour >= 24) {
  306. this.hour = 23;
  307. } else if (this.hour < 0) {
  308. this.hour = 0;
  309. }
  310. }
  311. if (this.minute < 0) {
  312. this.minute = 0;
  313. } else if (this.minute >= 60) {
  314. this.minute = 59;
  315. }
  316. if (this.showSeconds) {
  317. if (isNaN(this.second)) {
  318. this.second = 0;
  319. } else if (this.second < 0) {
  320. this.second = 0;
  321. } else if (this.second >= 60) {
  322. this.second = 59;
  323. }
  324. }
  325. if ( this.$element.val() != '' )
  326. this.updateElement();
  327. this.updateWidget();
  328. }
  329. , setMeridian: function(meridian) {
  330. if (meridian == 'a' || meridian == 'am' || meridian == 'AM' ) {
  331. this.meridian = 'AM';
  332. } else if (meridian == 'p' || meridian == 'pm' || meridian == 'PM' ) {
  333. this.meridian = 'PM';
  334. } else {
  335. this.updateWidget();
  336. }
  337. this.updateElement();
  338. }
  339. , setDefaultTime: function(defaultTime){
  340. if (defaultTime) {
  341. if (defaultTime === 'current') {
  342. var dTime = new Date();
  343. var hours = dTime.getHours();
  344. var minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep;
  345. var seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep;
  346. var meridian = "AM";
  347. if (this.showMeridian) {
  348. if (hours === 0) {
  349. hours = 12;
  350. } else if (hours >= 12) {
  351. if (hours > 12) {
  352. hours = hours - 12;
  353. }
  354. meridian = "PM";
  355. } else {
  356. meridian = "AM";
  357. }
  358. }
  359. this.hour = hours;
  360. this.minute = minutes;
  361. this.second = seconds;
  362. this.meridian = meridian;
  363. } else if (defaultTime === 'value') {
  364. this.setValues(this.$element.val());
  365. } else {
  366. this.setValues(defaultTime);
  367. }
  368. if ( this.$element.val() != '' )
  369. this.updateElement();
  370. this.updateWidget();
  371. } else {
  372. this.hour = 0;
  373. this.minute = 0;
  374. this.second = 0;
  375. }
  376. }
  377. , formatTime: function(hour, minute, second, meridian) {
  378. hour = hour < 10 ? '0' + hour : hour;
  379. minute = minute < 10 ? '0' + minute : minute;
  380. second = second < 10 ? '0' + second : second;
  381. return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : '');
  382. }
  383. , getTime: function() {
  384. return this.formatTime(this.hour, this.minute, this.second, this.meridian);
  385. }
  386. , setTime: function(time) {
  387. this.setValues(time);
  388. this.update();
  389. }
  390. , update: function() {
  391. this.updateElement();
  392. this.updateWidget();
  393. }
  394. , blurElement: function() {
  395. this.highlightedUnit = undefined;
  396. this.updateFromElementVal();
  397. }
  398. , updateElement: function() {
  399. var time = this.getTime();
  400. this.$element.val(time).change();
  401. switch (this.highlightedUnit) {
  402. case 'hour':
  403. this.highlightHour();
  404. break;
  405. case 'minute':
  406. this.highlightMinute();
  407. break;
  408. case 'second':
  409. this.highlightSecond();
  410. break;
  411. case 'meridian':
  412. this.highlightMeridian();
  413. break;
  414. }
  415. }
  416. , updateWidget: function() {
  417. if (this.showInputs) {
  418. this.$widget.find('input.bootstrap-timepicker-hour').val(this.hour < 10 ? '0' + this.hour : this.hour);
  419. this.$widget.find('input.bootstrap-timepicker-minute').val(this.minute < 10 ? '0' + this.minute : this.minute);
  420. if (this.showSeconds) {
  421. this.$widget.find('input.bootstrap-timepicker-second').val(this.second < 10 ? '0' + this.second : this.second);
  422. }
  423. if (this.showMeridian) {
  424. this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian);
  425. }
  426. } else {
  427. this.$widget.find('span.bootstrap-timepicker-hour').text(this.hour);
  428. this.$widget.find('span.bootstrap-timepicker-minute').text(this.minute < 10 ? '0' + this.minute : this.minute);
  429. if (this.showSeconds) {
  430. this.$widget.find('span.bootstrap-timepicker-second').text(this.second < 10 ? '0' + this.second : this.second);
  431. }
  432. if (this.showMeridian) {
  433. this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian);
  434. }
  435. }
  436. }
  437. , updateFromElementVal: function (e) {
  438. var time = this.$element.val();
  439. if (time) {
  440. this.setValues(time);
  441. this.updateWidget();
  442. }
  443. }
  444. , updateFromWidgetInputs: function () {
  445. var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' +
  446. $('input.bootstrap-timepicker-minute', this.$widget).val() +
  447. (this.showSeconds ?
  448. ':' + $('input.bootstrap-timepicker-second', this.$widget).val()
  449. : '') +
  450. (this.showMeridian ?
  451. ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val()
  452. : '');
  453. this.setValues(time);
  454. }
  455. , getCursorPosition: function() {
  456. var input = this.$element.get(0);
  457. if ('selectionStart' in input) {
  458. // Standard-compliant browsers
  459. return input.selectionStart;
  460. } else if (document.selection) {
  461. // IE fix
  462. input.focus();
  463. var sel = document.selection.createRange();
  464. var selLen = document.selection.createRange().text.length;
  465. sel.moveStart('character', - input.value.length);
  466. return sel.text.length - selLen;
  467. }
  468. }
  469. , highlightUnit: function () {
  470. var input = this.$element.get(0);
  471. this.position = this.getCursorPosition();
  472. if (this.position >= 0 && this.position <= 2) {
  473. this.highlightHour();
  474. } else if (this.position >= 3 && this.position <= 5) {
  475. this.highlightMinute();
  476. } else if (this.position >= 6 && this.position <= 8) {
  477. if (this.showSeconds) {
  478. this.highlightSecond();
  479. } else {
  480. this.highlightMeridian();
  481. }
  482. } else if (this.position >= 9 && this.position <= 11) {
  483. this.highlightMeridian();
  484. }
  485. }
  486. , highlightNextUnit: function() {
  487. switch (this.highlightedUnit) {
  488. case 'hour':
  489. this.highlightMinute();
  490. break;
  491. case 'minute':
  492. if (this.showSeconds) {
  493. this.highlightSecond();
  494. } else {
  495. this.highlightMeridian();
  496. }
  497. break;
  498. case 'second':
  499. this.highlightMeridian();
  500. break;
  501. case 'meridian':
  502. this.highlightHour();
  503. break;
  504. }
  505. }
  506. , highlightPrevUnit: function() {
  507. switch (this.highlightedUnit) {
  508. case 'hour':
  509. this.highlightMeridian();
  510. break;
  511. case 'minute':
  512. this.highlightHour();
  513. break;
  514. case 'second':
  515. this.highlightMinute();
  516. break;
  517. case 'meridian':
  518. if (this.showSeconds) {
  519. this.highlightSecond();
  520. } else {
  521. this.highlightMinute();
  522. }
  523. break;
  524. }
  525. }
  526. , highlightHour: function() {
  527. this.highlightedUnit = 'hour';
  528. this.$element.get(0).setSelectionRange(0,2);
  529. }
  530. , highlightMinute: function() {
  531. this.highlightedUnit = 'minute';
  532. this.$element.get(0).setSelectionRange(3,5);
  533. }
  534. , highlightSecond: function() {
  535. this.highlightedUnit = 'second';
  536. this.$element.get(0).setSelectionRange(6,8);
  537. }
  538. , highlightMeridian: function() {
  539. this.highlightedUnit = 'meridian';
  540. if (this.showSeconds) {
  541. this.$element.get(0).setSelectionRange(9,11);
  542. } else {
  543. this.$element.get(0).setSelectionRange(6,8);
  544. }
  545. }
  546. , incrementHour: function() {
  547. if (this.showMeridian) {
  548. if (this.hour === 11) {
  549. this.toggleMeridian();
  550. } else if (this.hour === 12) {
  551. return this.hour = 1;
  552. }
  553. }
  554. if (this.hour === 23) {
  555. return this.hour = 0;
  556. }
  557. this.hour = this.hour + 1;
  558. }
  559. , decrementHour: function() {
  560. if (this.showMeridian) {
  561. if (this.hour === 1) {
  562. return this.hour = 12;
  563. }
  564. else if (this.hour === 12) {
  565. this.toggleMeridian();
  566. }
  567. }
  568. if (this.hour === 0) {
  569. return this.hour = 23;
  570. }
  571. this.hour = this.hour - 1;
  572. }
  573. , incrementMinute: function() {
  574. var newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep);
  575. if (newVal > 59) {
  576. this.incrementHour();
  577. this.minute = newVal - 60;
  578. } else {
  579. this.minute = newVal;
  580. }
  581. }
  582. , decrementMinute: function() {
  583. var newVal = this.minute - this.minuteStep;
  584. if (newVal < 0) {
  585. this.decrementHour();
  586. this.minute = newVal + 60;
  587. } else {
  588. this.minute = newVal;
  589. }
  590. }
  591. , incrementSecond: function() {
  592. var newVal = this.second + this.secondStep - (this.second % this.secondStep);
  593. if (newVal > 59) {
  594. this.incrementMinute();
  595. this.second = newVal - 60;
  596. } else {
  597. this.second = newVal;
  598. }
  599. }
  600. , decrementSecond: function() {
  601. var newVal = this.second - this.secondStep;
  602. if (newVal < 0) {
  603. this.decrementMinute();
  604. this.second = newVal + 60;
  605. } else {
  606. this.second = newVal;
  607. }
  608. }
  609. , toggleMeridian: function() {
  610. this.meridian = this.meridian === 'AM' ? 'PM' : 'AM';
  611. this.update();
  612. }
  613. , getTemplate: function() {
  614. if (this.options.templates[this.options.template]) {
  615. return this.options.templates[this.options.template];
  616. }
  617. if (this.showInputs) {
  618. var hourTemplate = '<input type="text" name="hour" class="bootstrap-timepicker-hour" maxlength="2"/>';
  619. var minuteTemplate = '<input type="text" name="minute" class="bootstrap-timepicker-minute" maxlength="2"/>';
  620. var secondTemplate = '<input type="text" name="second" class="bootstrap-timepicker-second" maxlength="2"/>';
  621. var meridianTemplate = '<input type="text" name="meridian" class="bootstrap-timepicker-meridian" maxlength="2"/>';
  622. } else {
  623. var hourTemplate = '<span class="bootstrap-timepicker-hour"></span>';
  624. var minuteTemplate = '<span class="bootstrap-timepicker-minute"></span>';
  625. var secondTemplate = '<span class="bootstrap-timepicker-second"></span>';
  626. var meridianTemplate = '<span class="bootstrap-timepicker-meridian"></span>';
  627. }
  628. var templateContent = '<table class="'+ (this.showSeconds ? 'show-seconds' : '') +' '+ (this.showMeridian ? 'show-meridian' : '') +'">'+
  629. '<tr>'+
  630. '<td><a href="#" data-action="incrementHour"><i class="icon-chevron-up"></i></a></td>'+
  631. '<td class="separator">&nbsp;</td>'+
  632. '<td><a href="#" data-action="incrementMinute"><i class="icon-chevron-up"></i></a></td>'+
  633. (this.showSeconds ?
  634. '<td class="separator">&nbsp;</td>'+
  635. '<td><a href="#" data-action="incrementSecond"><i class="icon-chevron-up"></i></a></td>'
  636. : '') +
  637. (this.showMeridian ?
  638. '<td class="separator">&nbsp;</td>'+
  639. '<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="icon-chevron-up"></i></a></td>'
  640. : '') +
  641. '</tr>'+
  642. '<tr>'+
  643. '<td>'+ hourTemplate +'</td> '+
  644. '<td class="separator">:</td>'+
  645. '<td>'+ minuteTemplate +'</td> '+
  646. (this.showSeconds ?
  647. '<td class="separator">:</td>'+
  648. '<td>'+ secondTemplate +'</td>'
  649. : '') +
  650. (this.showMeridian ?
  651. '<td class="separator">&nbsp;</td>'+
  652. '<td>'+ meridianTemplate +'</td>'
  653. : '') +
  654. '</tr>'+
  655. '<tr>'+
  656. '<td><a href="#" data-action="decrementHour"><i class="icon-chevron-down"></i></a></td>'+
  657. '<td class="separator"></td>'+
  658. '<td><a href="#" data-action="decrementMinute"><i class="icon-chevron-down"></i></a></td>'+
  659. (this.showSeconds ?
  660. '<td class="separator">&nbsp;</td>'+
  661. '<td><a href="#" data-action="decrementSecond"><i class="icon-chevron-down"></i></a></td>'
  662. : '') +
  663. (this.showMeridian ?
  664. '<td class="separator">&nbsp;</td>'+
  665. '<td><a href="#" data-action="toggleMeridian"><i class="icon-chevron-down"></i></a></td>'
  666. : '') +
  667. '</tr>'+
  668. '</table>';
  669. var template;
  670. switch(this.options.template) {
  671. case 'modal':
  672. template = '<div class="bootstrap-timepicker modal hide fade in" style="top: 30%; margin-top: 0; width: 200px; margin-left: -100px;" data-backdrop="'+ (this.modalBackdrop ? 'true' : 'false') +'">'+
  673. '<div class="modal-header">'+
  674. '<a href="#" class="close" data-dismiss="modal">×</a>'+
  675. '<h3>Pick a Time</h3>'+
  676. '</div>'+
  677. '<div class="modal-content">'+
  678. templateContent +
  679. '</div>'+
  680. '<div class="modal-footer">'+
  681. '<a href="#" class="btn btn-primary" data-dismiss="modal">Ok</a>'+
  682. '</div>'+
  683. '</div>';
  684. break;
  685. case 'dropdown':
  686. template = '<div class="bootstrap-timepicker dropdown-menu">'+
  687. templateContent +
  688. '</div>';
  689. break;
  690. }
  691. return template;
  692. }
  693. };
  694. /* TIMEPICKER PLUGIN DEFINITION
  695. * =========================== */
  696. $.fn.timepicker = function (option) {
  697. return this.each(function () {
  698. var $this = $(this)
  699. , data = $this.data('timepicker')
  700. , options = typeof option == 'object' && option;
  701. if (!data) {
  702. $this.data('timepicker', (data = new Timepicker(this, options)));
  703. }
  704. if (typeof option == 'string') {
  705. data[option]();
  706. }
  707. })
  708. }
  709. $.fn.timepicker.defaults = {
  710. minuteStep: 15
  711. , secondStep: 15
  712. , disableFocus: false
  713. , defaultTime: 'current'
  714. , showSeconds: false
  715. , showInputs: true
  716. , showMeridian: true
  717. , template: 'dropdown'
  718. , modalBackdrop: false
  719. , templates: {} // set custom templates
  720. }
  721. $.fn.timepicker.Constructor = Timepicker
  722. }(window.jQuery);