1/************************ 2jquery-timepicker v1.3.2 3http://jonthornton.github.com/jquery-timepicker/ 4 5requires jQuery 1.7+ 6************************/ 7 8 9(function (factory) { 10 if (typeof define === 'function' && define.amd) { 11 // AMD. Register as an anonymous module. 12 define(['jquery'], factory); 13 } else { 14 // Browser globals 15 factory(jQuery); 16 } 17}(function ($) { 18 var _baseDate = _generateBaseDate(); 19 var _ONE_DAY = 86400; 20 var _defaults = { 21 className: null, 22 minTime: null, 23 maxTime: null, 24 durationTime: null, 25 step: 30, 26 showDuration: false, 27 timeFormat: 'g:ia', 28 scrollDefaultNow: false, 29 scrollDefaultTime: false, 30 selectOnBlur: false, 31 disableTouchKeyboard: false, 32 forceRoundTime: false, 33 appendTo: 'body', 34 disableTimeRanges: [], 35 closeOnWindowScroll: false, 36 typeaheadHighlight: true, 37 noneOption: false 38 }; 39 var _lang = { 40 decimal: '.', 41 mins: 'mins', 42 hr: 'hr', 43 hrs: 'hrs' 44 }; 45 46 var methods = 47 { 48 init: function(options) 49 { 50 return this.each(function() 51 { 52 var self = $(this); 53 54 // pick up settings from data attributes 55 var attributeOptions = []; 56 for (key in _defaults) { 57 if (self.data(key)) { 58 attributeOptions[key] = self.data(key); 59 } 60 } 61 62 var settings = $.extend({}, _defaults, attributeOptions, options); 63 64 if (settings.lang) { 65 _lang = $.extend(_lang, settings.lang); 66 } 67 68 settings = _parseSettings(settings); 69 self.data('timepicker-settings', settings); 70 self.addClass('ui-timepicker-input'); 71 72 if (settings.useSelect) { 73 _render(self); 74 } else { 75 self.prop('autocomplete', 'off'); 76 self.on('click.timepicker focus.timepicker', methods.show); 77 self.on('change.timepicker', _formatValue); 78 self.on('keydown.timepicker', _keydownhandler); 79 self.on('keyup.timepicker', _keyuphandler); 80 81 _formatValue.call(self.get(0)); 82 } 83 }); 84 }, 85 86 show: function(e) 87 { 88 if (e) { 89 e.preventDefault(); 90 } 91 92 var self = $(this); 93 var settings = self.data('timepicker-settings'); 94 95 if (settings.useSelect) { 96 self.data('timepicker-list').focus(); 97 return; 98 } 99 100 if (_hideKeyboard(self)) { 101 // block the keyboard on mobile devices 102 self.blur(); 103 } 104 105 var list = self.data('timepicker-list'); 106 107 // check if input is readonly 108 if (self.prop('readonly')) { 109 return; 110 } 111 112 // check if list needs to be rendered 113 if (!list || list.length === 0 || typeof settings.durationTime === 'function') { 114 _render(self); 115 list = self.data('timepicker-list'); 116 } 117 118 if (list.is(':visible')) { 119 return; 120 } 121 122 // make sure other pickers are hidden 123 methods.hide(); 124 125 list.show(); 126 127 if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) { 128 // position the dropdown on top 129 list.offset({ 130 'left': self.offset().left + parseInt(list.css('marginLeft').replace('px', ''), 10), 131 'top': self.offset().top - list.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10) 132 }); 133 } else { 134 // put it under the input 135 list.offset({ 136 'left':self.offset().left + parseInt(list.css('marginLeft').replace('px', ''), 10), 137 'top': self.offset().top + self.outerHeight() + parseInt(list.css('marginTop').replace('px', ''), 10) 138 }); 139 } 140 141 // position scrolling 142 var selected = list.find('.ui-timepicker-selected'); 143 144 if (!selected.length) { 145 if (_getTimeValue(self)) { 146 selected = _findRow(self, list, _time2int(_getTimeValue(self))); 147 } else if (settings.scrollDefaultNow) { 148 selected = _findRow(self, list, _time2int(new Date())); 149 } else if (settings.scrollDefaultTime !== false) { 150 selected = _findRow(self, list, _time2int(settings.scrollDefaultTime)); 151 } 152 } 153 154 if (selected && selected.length) { 155 var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight(); 156 list.scrollTop(topOffset); 157 } else { 158 list.scrollTop(0); 159 } 160 161 // attach close handlers 162 $(document).on('touchstart.ui-timepicker mousedown.ui-timepicker', _closeHandler); 163 if (settings.closeOnWindowScroll) { 164 $(document).on('scroll.ui-timepicker', _closeHandler); 165 } 166 167 self.trigger('showTimepicker'); 168 169 return this; 170 }, 171 172 hide: function(e) 173 { 174 var self = $(this); 175 var settings = self.data('timepicker-settings'); 176 177 if (settings && settings.useSelect) { 178 self.blur(); 179 } 180 181 $('.ui-timepicker-wrapper:visible').each(function() { 182 var list = $(this); 183 var self = list.data('timepicker-input'); 184 var settings = self.data('timepicker-settings'); 185 186 if (settings && settings.selectOnBlur) { 187 _selectValue(self); 188 } 189 190 list.hide(); 191 self.trigger('hideTimepicker'); 192 }); 193 194 return this; 195 }, 196 197 option: function(key, value) 198 { 199 var self = this; 200 var settings = self.data('timepicker-settings'); 201 var list = self.data('timepicker-list'); 202 203 if (typeof key == 'object') { 204 settings = $.extend(settings, key); 205 206 } else if (typeof key == 'string' && typeof value != 'undefined') { 207 settings[key] = value; 208 209 } else if (typeof key == 'string') { 210 return settings[key]; 211 } 212 213 settings = _parseSettings(settings); 214 215 self.data('timepicker-settings', settings); 216 217 if (list) { 218 list.remove(); 219 self.data('timepicker-list', false); 220 } 221 222 if (settings.useSelect) { 223 _render(self); 224 } 225 226 return this; 227 }, 228 229 getSecondsFromMidnight: function() 230 { 231 return _time2int(_getTimeValue(this)); 232 }, 233 234 getTime: function(relative_date) 235 { 236 var self = this; 237 238 var time_string = _getTimeValue(self); 239 if (!time_string) { 240 return null; 241 } 242 243 if (!relative_date) { 244 relative_date = new Date(); 245 } 246 247 relative_date.setHours(0, 0, 0, 0); 248 return new Date(relative_date.valueOf() + (_time2int(time_string)*1000)); 249 }, 250 251 setTime: function(value) 252 { 253 var self = this; 254 var prettyTime = _int2time(_time2int(value), self.data('timepicker-settings').timeFormat); 255 256 _setTimeValue(self, prettyTime); 257 if (self.data('timepicker-list')) { 258 _setSelected(self, self.data('timepicker-list')); 259 } 260 261 return this; 262 }, 263 264 remove: function() 265 { 266 var self = this; 267 268 // check if this element is a timepicker 269 if (!self.hasClass('ui-timepicker-input')) { 270 return; 271 } 272 273 self.removeAttr('autocomplete', 'off'); 274 self.removeClass('ui-timepicker-input'); 275 self.removeData('timepicker-settings'); 276 self.off('.timepicker'); 277 278 // timepicker-list won't be present unless the user has interacted with this timepicker 279 if (self.data('timepicker-list')) { 280 self.data('timepicker-list').remove(); 281 } 282 283 self.removeData('timepicker-list'); 284 285 return this; 286 } 287 }; 288 289 // private methods 290 291 function _parseSettings(settings) 292 { 293 if (settings.minTime) {
294 settings.minTime = _time2int(settings.minTime); 295 } 296 297 if (settings.maxTime) { 298 settings.maxTime = _time2int(settings.maxTime); 299 } 300 301 if (settings.durationTime && typeof settings.durationTime !== 'function') { 302 settings.durationTime = _time2int(settings.durationTime); 303 } 304 305 if (settings.disableTimeRanges.length > 0) { 306 // convert string times to integers 307 for (var i in settings.disableTimeRanges) { 308 settings.disableTimeRanges[i] = [ 309 _time2int(settings.disableTimeRanges[i][0]), 310 _time2int(settings.disableTimeRanges[i][1]) 311 ]; 312 } 313 314 // sort by starting time 315 settings.disableTimeRanges = settings.disableTimeRanges.sort(function(a, b){ 316 return a[0] - b[0]; 317 }); 318 319 // merge any overlapping ranges 320 for (var i = settings.disableTimeRanges.length-1; i > 0; i--) { 321 if (settings.disableTimeRanges[i][0] <= settings.disableTimeRanges[i-1][1]) { 322 settings.disableTimeRanges[i-1] = [ 323 Math.min(settings.disableTimeRanges[i][0], settings.disableTimeRanges[i-1][0]), 324 Math.max(settings.disableTimeRanges[i][1], settings.disableTimeRanges[i-1][1]) 325 ]; 326 settings.disableTimeRanges.splice(i, 1); 327 } 328 } 329 } 330 331 return settings; 332 } 333 334 function _render(self) 335 { 336 var settings = self.data('timepicker-settings'); 337 var list = self.data('timepicker-list'); 338 339 if (list && list.length) { 340 list.remove(); 341 self.data('timepicker-list', false); 342 } 343 344 if (settings.useSelect) { 345 list = $('<select />', { 'class': 'ui-timepicker-select' }); 346 var wrapped_list = list; 347 } else { 348 list = $('<ul />', { 'class': 'ui-timepicker-list' }); 349 350 var wrapped_list = $('<div />', { 'class': 'ui-timepicker-wrapper', 'tabindex': -1 }); 351 wrapped_list.css({'display':'none', 'position': 'absolute' }).append(list); 352 } 353 354 if (settings.noneOption) { 355 var defaultLabel = (settings.useSelect) ? 'Time...' : 'None'; 356 var label = (typeof settings.noneOption == 'string') ? settings.noneOption : defaultLabel; 357 if (settings.useSelect) { 358 list.append($('<option value="">'+label+'</option>')); 359 } else { 360 list.append($('<li>'+label+'</li>')); 361 } 362 } 363 364 if (settings.className) { 365 wrapped_list.addClass(settings.className); 366 } 367 368 if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) { 369 wrapped_list.addClass('ui-timepicker-with-duration'); 370 } 371 372 var durStart = settings.minTime; 373 if (typeof settings.durationTime === 'function') { 374 durStart = _time2int(settings.durationTime()); 375 } else if (settings.durationTime !== null) { 376 durStart = settings.durationTime; 377 } 378 var start = (settings.minTime !== null) ? settings.minTime : 0; 379 var end = (settings.maxTime !== null) ? settings.maxTime : (start + _ONE_DAY - 1); 380 381 if (end <= start) { 382 // make sure the end time is greater than start time, otherwise there will be no list to show 383 end += _ONE_DAY; 384 } 385 386 if (end === _ONE_DAY-1 && settings.timeFormat.indexOf('H') !== -1) { 387 // show a 24:00 option when using military time 388 end = _ONE_DAY; 389 } 390 391 var dr = settings.disableTimeRanges; 392 var drCur = 0; 393 var drLen = dr.length; 394 395 for (var i=start; i <= end; i += settings.step*60) { 396 var timeInt = i; 397 var timeString = _int2time(timeInt, settings.timeFormat); 398 399 if (settings.useSelect) { 400 var row = $('<option />', { 'value': timeString }); 401 row.text(timeString); 402 } else { 403 var row = $('<li />'); 404 row.data('time', (timeInt <= 86400 ? timeInt : timeInt % 86400)); 405 row.text(timeString); 406 } 407 408 if ((settings.minTime !== null || settings.durationTime !== null) && settings.showDuration) { 409 var durationString = _int2duration(i - durStart); 410 if (settings.useSelect) { 411 row.text(row.text()+' ('+durationString+')'); 412 } else { 413 var duration = $('<span />', { 'class': 'ui-timepicker-duration' }); 414 duration.text(' ('+durationString+')'); 415 row.append(duration); 416 } 417 } 418 419 if (drCur < drLen) { 420 if (timeInt >= dr[drCur][1]) { 421 drCur += 1; 422 } 423 424 if (dr[drCur] && timeInt >= dr[drCur][0] && timeInt < dr[drCur][1]) { 425 if (settings.useSelect) { 426 row.prop('disabled', true); 427 } else { 428 row.addClass('ui-timepicker-disabled'); 429 } 430 } 431 } 432 433 list.append(row); 434 } 435 436 wrapped_list.data('timepicker-input', self); 437 self.data('timepicker-list', wrapped_list); 438 439 if (settings.useSelect) { 440 list.val(_roundTime(self.val(), settings)); 441 list.on('focus', function(){ 442 $(this).data('timepicker-input').trigger('showTimepicker'); 443 }); 444 list.on('blur', function(){ 445 $(this).data('timepicker-input').trigger('hideTimepicker'); 446 }); 447 list.on('change', function(){ 448 _setTimeValue(self, $(this).val(), 'select'); 449 }); 450 451 self.hide().after(list); 452 } else { 453 var appendTo = settings.appendTo; 454 if (typeof appendTo === 'string') { 455 appendTo = $(appendTo); 456 } else if (typeof appendTo === 'function') { 457 appendTo = appendTo(self); 458 } 459 appendTo.append(wrapped_list); 460 _setSelected(self, list); 461 462 list.on('click', 'li', function(e) { 463 464 // hack: temporarily disable the focus handler 465 // to deal with the fact that IE fires 'focus' 466 // events asynchronously 467 self.off('focus.timepicker'); 468 self.on('focus.timepicker-ie-hack', function(){ 469 self.off('focus.timepicker-ie-hack'); 470 self.on('focus.timepicker', methods.show); 471 }); 472 473 if (!_hideKeyboard(self)) { 474 self[0].focus(); 475 } 476 477 // make sure only the clicked row is selected 478 list.find('li').removeClass('ui-timepicker-selected'); 479 $(this).addClass('ui-timepicker-selected'); 480 481 if (_selectValue(self)) { 482 self.trigger('hideTimepicker'); 483 wrapped_list.hide(); 484 } 485 }); 486 } 487 } 488 489 function _roundTime(time, settings) 490 { 491 if (!$.isNumeric(time)) { 492 time = _time2int(time); 493 } 494 495 if (time === null) { 496 return null; 497 } else { 498 var step = settings.step*60; 499 // round to the nearest step 500 return _int2time(Math.round(time / step) * step, settings.timeFormat); 501 } 502 } 503 504 function _generateBaseDate() 505 { 506 return new Date(1970, 1, 1, 0, 0, 0); 507 } 508 509 // event handler to decide whether to close timepicker 510 function _closeHandler(e) 511 { 512 var target = $(e.target); 513 var input = target.closest('.ui-timepicker-input'); 514 if (input.length === 0 && target.closest('.ui-timepicker-wrapper').length === 0) { 515 methods.hide(); 516 $(document).unbind('.ui-timepicker'); 517 } 518 } 519 520 function _hideKeyboard(self) 521 { 522 var settings = self.data('timepicker-settings'); 523 return ((window.navigator.msMaxTouchPoints || 'ontouchstart' in document) && settings.disableTouchKeyboard); 524 } 525 526 function _findRow(self, list, value) 527 { 528 if (!value && value !== 0) { 529 return false;
530 } 531 532 var settings = self.data('timepicker-settings'); 533 var out = false; 534 var halfStep = settings.step*30; 535 536 // loop through the menu items 537 list.find('li').each(function(i, obj) { 538 var jObj = $(obj); 539 540 var offset = jObj.data('time') - value; 541 542 // check if the value is less than half a step from each row 543 if (Math.abs(offset) < halfStep || offset == halfStep) { 544 out = jObj; 545 return false; 546 } 547 }); 548 549 return out; 550 } 551 552 function _setSelected(self, list) 553 { 554 list.find('li').removeClass('ui-timepicker-selected'); 555 556 var timeValue = _time2int(_getTimeValue(self)); 557 if (timeValue === null) { 558 return; 559 } 560 561 var selected = _findRow(self, list, timeValue); 562 if (selected) { 563 564 var topDelta = selected.offset().top - list.offset().top; 565 566 if (topDelta + selected.outerHeight() > list.outerHeight() || topDelta < 0) { 567 list.scrollTop(list.scrollTop() + selected.position().top - selected.outerHeight()); 568 } 569 570 selected.addClass('ui-timepicker-selected'); 571 } 572 } 573 574 575 function _formatValue() 576 { 577 if (this.value === '') { 578 return; 579 } 580 581 var self = $(this); 582 var list = self.data('timepicker-list'); 583 584 if (list && list.is(':visible')) { 585 return; 586 } 587 588 var seconds = _time2int(this.value); 589 590 if (seconds === null) { 591 self.trigger('timeFormatError'); 592 return; 593 } 594 595 var settings = self.data('timepicker-settings'); 596 var rangeError = false;
597 // check that the time in within bounds 598 if (settings.minTime !== null && seconds < settings.minTime) { 599 rangeError = true; 600 } else if (settings.maxTime !== null && seconds > settings.maxTime) { 601 rangeError = true; 602 } 603 604 // check that time isn't within disabled time ranges 605 $.each(settings.disableTimeRanges, function(){ 606 if (seconds >= this[0] && seconds < this[1]) { 607 rangeError = true; 608 return false; 609 } 610 }); 611 612 if (settings.forceRoundTime) { 613 var offset = seconds % (settings.step*60); // step is in minutes 614 615 if (offset >= settings.step*30) { 616 // if offset is larger than a half step, round up 617 seconds += (settings.step*60) - offset; 618 } else { 619 // round down 620 seconds -= offset; 621 } 622 } 623 624 var prettyTime = _int2time(seconds, settings.timeFormat); 625 626 if (rangeError) { 627 if (_setTimeValue(self, prettyTime, 'error')) { 628 self.trigger('timeRangeError'); 629 } 630 } else { 631 _setTimeValue(self, prettyTime); 632 } 633 } 634 635 function _getTimeValue(self) 636 { 637 if (self.is('input')) { 638 return self.val(); 639 } else { 640 // use the element's data attributes to store values 641 return self.data('ui-timepicker-value'); 642 } 643 } 644 645 function _setTimeValue(self, value, source) 646 { 647 if (self.is('input')) { 648 self.val(value); 649 650 var settings = self.data('timepicker-settings'); 651 if (settings.useSelect) { 652 self.data('timepicker-list').val(_roundTime(value, settings)); 653 } 654 } 655 656 if (self.data('ui-timepicker-value') != value) { 657 self.data('ui-timepicker-value', value); 658 if (source == 'select') { 659 self.trigger('selectTime').trigger('changeTime').trigger('change'); 660 } else if (source != 'error') { 661 self.trigger('changeTime'); 662 } 663 664 return true; 665 } else { 666 self.trigger('selectTime'); 667 return false; 668 } 669 } 670 671 /* 672 * Keyboard navigation via arrow keys 673 */ 674 function _keydownhandler(e) 675 { 676 var self = $(this); 677 var list = self.data('timepicker-list'); 678 679 if (!list || !list.is(':visible')) { 680 if (e.keyCode == 40) { 681 if (!_hideKeyboard(self)) { 682 self.focus(); 683 } 684 } else { 685 return true; 686 } 687 } 688 689 switch (e.keyCode) { 690 691 case 13: // return 692 if (_selectValue(self)) { 693 methods.hide.apply(this); 694 } 695 696 e.preventDefault(); 697 return false; 698 699 case 38: // up 700 var selected = list.find('.ui-timepicker-selected'); 701 702 if (!selected.length) { 703 list.find('li').each(function(i, obj) { 704 if ($(obj).position().top > 0) { 705 selected = $(obj); 706 return false; 707 } 708 }); 709 selected.addClass('ui-timepicker-selected'); 710 711 } else if (!selected.is(':first-child')) { 712 selected.removeClass('ui-timepicker-selected'); 713 selected.prev().addClass('ui-timepicker-selected'); 714 715 if (selected.prev().position().top < selected.outerHeight()) { 716 list.scrollTop(list.scrollTop() - selected.outerHeight()); 717 } 718 } 719 720 return false; 721 722 case 40: // down 723 selected = list.find('.ui-timepicker-selected'); 724 725 if (selected.length === 0) { 726 list.find('li').each(function(i, obj) { 727 if ($(obj).position().top > 0) { 728 selected = $(obj); 729 return false; 730 } 731 }); 732 733 selected.addClass('ui-timepicker-selected'); 734 } else if (!selected.is(':last-child')) { 735 selected.removeClass('ui-timepicker-selected'); 736 selected.next().addClass('ui-timepicker-selected'); 737 738 if (selected.next().position().top + 2*selected.outerHeight() > list.outerHeight()) { 739 list.scrollTop(list.scrollTop() + selected.outerHeight()); 740 } 741 } 742 743 return false; 744 745 case 27: // escape 746 list.find('li').removeClass('ui-timepicker-selected'); 747 methods.hide(); 748 break; 749 750 case 9: //tab 751 methods.hide(); 752 break; 753 754 default: 755 return true; 756 } 757 } 758 759 /* 760 * Time typeahead 761 */ 762 function _keyuphandler(e) 763 { 764 var self = $(this); 765 var list = self.data('timepicker-list'); 766 767 if (!list || !list.is(':visible')) { 768 return true; 769 } 770 771 if (!self.data('timepicker-settings').typeaheadHighlight) { 772 list.find('li').removeClass('ui-timepicker-selected'); 773 return true; 774 } 775 776 switch (e.keyCode) { 777 778 case 96: // numpad numerals 779 case 97: 780 case 98: 781 case 99: 782 case 100: 783 case 101: 784 case 102: 785 case 103: 786 case 104: 787 case 105: 788 case 48: // numerals 789 case 49: 790 case 50: 791 case 51: 792 case 52: 793 case 53: 794 case 54: 795 case 55: 796 case 56: 797 case 57: 798 case 65: // a 799 case 77: // m 800 case 80: // p 801 case 186: // colon 802 case 8: // backspace 803 case 46: // delete 804 _setSelected(self, list); 805 break; 806 807 default: 808 // list.find('li').removeClass('ui-timepicker-selected'); 809 return; 810 } 811 } 812 813 function _selectValue(self) 814 { 815 var settings = self.data('timepicker-settings'); 816 var list = self.data('timepicker-list'); 817 var timeValue = null; 818 819 var cursor = list.find('.ui-timepicker-selected'); 820 821 if (cursor.hasClass('ui-timepicker-disabled')) { 822 return false;
823 } 824 825 if (cursor.length) { 826 // selected value found 827 timeValue = cursor.data('time'); 828 829 } else if (_getTimeValue(self)) { 830 831 // no selected value; fall back on input value 832 timeValue = _time2int(_getTimeValue(self)); 833 834 _setSelected(self, list); 835 } 836 837 if (timeValue !== null) { 838 var timeString = _int2time(timeValue, settings.timeFormat); 839 _setTimeValue(self, timeString, 'select'); 840 } 841 842 //self.trigger('change').trigger('selectTime'); 843 return true; 844 } 845 846 function _int2duration(seconds) 847 { 848 var minutes = Math.round(seconds/60); 849 var duration; 850 851 if (Math.abs(minutes) < 60) { 852 duration = [minutes, _lang.mins]; 853 } else if (minutes == 60) { 854 duration = ['1', _lang.hr]; 855 } else { 856 var hours = (minutes/60).toFixed(1); 857 if (_lang.decimal != '.') hours = hours.replace('.', _lang.decimal); 858 duration = [hours, _lang.hrs]; 859 } 860 861 return duration.join(' '); 862 } 863 864 function _int2time(seconds, format) 865 { 866 if (seconds === null) { 867 return; 868 } 869 870 var time = new Date(_baseDate.valueOf() + (seconds*1000)); 871 872 if (isNaN(time.getTime())) { 873 return; 874 } 875 876 var output = ''; 877 var hour, code; 878 879 for (var i=0; i<format.length; i++) { 880 881 code = format.charAt(i); 882 switch (code) { 883 884 case 'a': 885 output += (time.getHours() > 11) ? 'pm' : 'am'; 886 break; 887 888 case 'A': 889 output += (time.getHours() > 11) ? 'PM' : 'AM'; 890 break; 891 892 case 'g': 893 hour = time.getHours() % 12; 894 output += (hour === 0) ? '12' : hour; 895 break; 896 897 case 'G': 898 output += time.getHours(); 899 break; 900 901 case 'h': 902 hour = time.getHours() % 12; 903 904 if (hour !== 0 && hour < 10) { 905 hour = '0'+hour; 906 } 907 908 output += (hour === 0) ? '12' : hour; 909 break; 910 911 case 'H': 912 hour = time.getHours(); 913 if (seconds === _ONE_DAY) hour = 24; 914 output += (hour > 9) ? hour : '0'+hour; 915 break; 916 917 case 'i': 918 var minutes = time.getMinutes(); 919 output += (minutes > 9) ? minutes : '0'+minutes; 920 break; 921 922 case 's': 923 seconds = time.getSeconds(); 924 output += (seconds > 9) ? seconds : '0'+seconds; 925 break; 926 927 default: 928 output += code; 929 } 930 } 931 932 return output; 933 } 934 935 function _time2int(timeString) 936 { 937 if (timeString === '') return null; 938 if (!timeString || timeString+0 == timeString) return timeString; 939 940 if (typeof(timeString) == 'object') { 941 timeString = timeString.getHours()+':'+_pad2(timeString.getMinutes())+':'+_pad2(timeString.getSeconds()); 942 } 943 944 timeString = timeString.toLowerCase(); 945 946 var d = new Date(0); 947 var time; 948 949 // try to parse time input 950 if (timeString.indexOf(":") === -1) { 951 // no colon present
952 time = timeString.match(/^([0-9]):?([0-5][0-9])?:?([0-5][0-9])?\s*([pa]?)m?$/); 953 954 if (!time) { 955 time = timeString.match(/^([0-2][0-9]):?([0-5][0-9])?:?([0-5][0-9])?\s*([pa]?)m?$/); 956 } 957 } else { 958 time = timeString.match(/^(\d{1,2})(?::([0-5][0-9]))?(?::([0-5][0-9]))?\s*([pa]?)m?$/); 959 } 960 961 if (!time) { 962 return null; 963 } 964 965 var hour = parseInt(time[1]*1, 10); 966 var hours; 967 968 if (time[4]) { 969 if (hour == 12) { 970 hours = (time[4] == 'p') ? 12 : 0; 971 } else { 972 hours = (hour + (time[4] == 'p' ? 12 : 0)); 973 } 974 975 } else { 976 hours = hour; 977 } 978 979 var minutes = ( time[2]*1 || 0 ); 980 var seconds = ( time[3]*1 || 0 ); 981 return hours*3600 + minutes*60 + seconds; 982 } 983 984 function _pad2(n) { 985 return ("0" + n).slice(-2); 986 } 987 988 // Plugin entry 989 $.fn.timepicker = function(method) 990 { 991 if (!this.length) return this; 992 if(methods[method]) { return methods[method].apply(this, Array.prototype.slice.call(arguments, 1)); } 993 else if(typeof method === "object" || !method) { return methods.init.apply(this, arguments); } 994 else { $.error("Method "+ method + " does not exist on jQuery.timepicker"); } 995 }; 996}));
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.