1/*! 2 * Timepicker Component for Twitter Bootstrap 3 * 4 * Copyright 2013 Joris de Wit 5 * 6 * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors 7 * 8 * For the full copyright and license information, please view the LICENSE 9 * file that was distributed with this source code. 10 */ 11;(function($, window, document, undefined) { 12 13 'use strict'; // jshint ;_; 14 15 // TIMEPICKER PUBLIC CLASS DEFINITION 16 var Timepicker = function(element, options) { 17 this.widget = ''; 18 this.$element = $(element); 19 this.defaultTime = options.defaultTime; 20 this.disableFocus = options.disableFocus; 21 this.isOpen = options.isOpen; 22 this.minuteStep = options.minuteStep; 23 this.modalBackdrop = options.modalBackdrop; 24 this.secondStep = options.secondStep; 25 this.showInputs = options.showInputs; 26 this.showMeridian = options.showMeridian; 27 this.showSeconds = options.showSeconds; 28 this.template = options.template; 29 this.appendWidgetTo = options.appendWidgetTo; 30 31 this._init(); 32 }; 33 34 Timepicker.prototype = { 35 36 constructor: Timepicker, 37 38 _init: function() { 39 var self = this; 40 41 if (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend')) { 42 this.$element.parent('.input-append, .input-prepend').find('.add-on').on({ 43 'click.timepicker': $.proxy(this.showWidget, this) 44 }); 45 this.$element.on({ 46 'focus.timepicker': $.proxy(this.highlightUnit, this), 47 'click.timepicker': $.proxy(this.highlightUnit, this), 48 'keydown.timepicker': $.proxy(this.elementKeydown, this), 49 'blur.timepicker': $.proxy(this.blurElement, this) 50 }); 51 } else { 52 if (this.template) { 53 this.$element.on({ 54 'focus.timepicker': $.proxy(this.showWidget, this), 55 'click.timepicker': $.proxy(this.showWidget, this), 56 'blur.timepicker': $.proxy(this.blurElement, this) 57 }); 58 } else { 59 this.$element.on({ 60 'focus.timepicker': $.proxy(this.highlightUnit, this), 61 'click.timepicker': $.proxy(this.highlightUnit, this), 62 'keydown.timepicker': $.proxy(this.elementKeydown, this), 63 'blur.timepicker': $.proxy(this.blurElement, this) 64 }); 65 } 66 } 67 68 if (this.template !== false) { 69 this.$widget = $(this.getTemplate()).prependTo(this.$element.parents(this.appendWidgetTo)).on('click', $.proxy(this.widgetClick, this)); 70 } else { 71 this.$widget = false; 72 } 73 74 if (this.showInputs && this.$widget !== false) { 75 this.$widget.find('input').each(function() { 76 $(this).on({ 77 'click.timepicker': function() { $(this).select(); }, 78 'keydown.timepicker': $.proxy(self.widgetKeydown, self) 79 }); 80 }); 81 } 82 83 this.setDefaultTime(this.defaultTime); 84 }, 85 86 blurElement: function() { 87 this.highlightedUnit = undefined; 88 this.updateFromElementVal(); 89 }, 90 91 decrementHour: function() { 92 if (this.showMeridian) { 93 if (this.hour === 1) { 94 this.hour = 12; 95 } else if (this.hour === 12) { 96 this.hour--; 97 98 return this.toggleMeridian(); 99 } else if (this.hour === 0) { 100 this.hour = 11; 101 102 return this.toggleMeridian(); 103 } else { 104 this.hour--; 105 } 106 } else { 107 if (this.hour === 0) { 108 this.hour = 23; 109 } else { 110 this.hour--; 111 } 112 } 113 this.update(); 114 }, 115 116 decrementMinute: function(step) { 117 var newVal; 118 119 if (step) { 120 newVal = this.minute - step; 121 } else { 122 newVal = this.minute - this.minuteStep; 123 } 124 125 if (newVal < 0) { 126 this.decrementHour(); 127 this.minute = newVal + 60; 128 } else { 129 this.minute = newVal; 130 } 131 this.update(); 132 }, 133 134 decrementSecond: function() { 135 var newVal = this.second - this.secondStep; 136 137 if (newVal < 0) { 138 this.decrementMinute(true); 139 this.second = newVal + 60; 140 } else { 141 this.second = newVal; 142 } 143 this.update(); 144 }, 145
146 elementKeydown: function(e) { 147 switch (e.keyCode) { 148 case 9: //tab 149 this.updateFromElementVal(); 150 151 switch (this.highlightedUnit) { 152 case 'hour': 153 e.preventDefault(); 154 this.highlightNextUnit(); 155 break; 156 case 'minute': 157 if (this.showMeridian || this.showSeconds) { 158 e.preventDefault(); 159 this.highlightNextUnit(); 160 } 161 break; 162 case 'second': 163 if (this.showMeridian) { 164 e.preventDefault(); 165 this.highlightNextUnit(); 166 } 167 break; 168 } 169 break; 170 case 27: // escape 171 this.updateFromElementVal(); 172 break; 173 case 37: // left arrow 174 e.preventDefault(); 175 this.highlightPrevUnit(); 176 this.updateFromElementVal(); 177 break; 178 case 38: // up arrow 179 e.preventDefault(); 180 switch (this.highlightedUnit) { 181 case 'hour': 182 this.incrementHour(); 183 this.highlightHour(); 184 break; 185 case 'minute': 186 this.incrementMinute(); 187 this.highlightMinute(); 188 break; 189 case 'second': 190 this.incrementSecond(); 191 this.highlightSecond(); 192 break; 193 case 'meridian': 194 this.toggleMeridian(); 195 this.highlightMeridian(); 196 break; 197 } 198 break; 199 case 39: // right arrow 200 e.preventDefault(); 201 this.updateFromElementVal(); 202 this.highlightNextUnit(); 203 break; 204 case 40: // down arrow 205 e.preventDefault(); 206 switch (this.highlightedUnit) { 207 case 'hour': 208 this.decrementHour(); 209 this.highlightHour(); 210 break; 211 case 'minute': 212 this.decrementMinute(); 213 this.highlightMinute(); 214 break; 215 case 'second': 216 this.decrementSecond(); 217 this.highlightSecond(); 218 break; 219 case 'meridian': 220 this.toggleMeridian(); 221 this.highlightMeridian(); 222 break; 223 } 224 break; 225 } 226 }, 227 228 formatTime: function(hour, minute, second, meridian) { 229 hour = hour < 10 ? '0' + hour : hour; 230 minute = minute < 10 ? '0' + minute : minute; 231 second = second < 10 ? '0' + second : second; 232 233 return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : ''); 234 }, 235 236 getCursorPosition: function() { 237 var input = this.$element.get(0); 238 239 if ('selectionStart' in input) {// Standard-compliant browsers 240 241 return input.selectionStart; 242 } else if (document.selection) {// IE fix 243 input.focus(); 244 var sel = document.selection.createRange(), 245 selLen = document.selection.createRange().text.length; 246 247 sel.moveStart('character', - input.value.length); 248 249 return sel.text.length - selLen; 250 } 251 }, 252 253 getTemplate: function() { 254 var template, 255 hourTemplate, 256 minuteTemplate, 257 secondTemplate, 258 meridianTemplate, 259 templateContent; 260 261 if (this.showInputs) { 262 hourTemplate = '<input type="text" name="hour" class="bootstrap-timepicker-hour" maxlength="2"/>'; 263 minuteTemplate = '<input type="text" name="minute" class="bootstrap-timepicker-minute" maxlength="2"/>'; 264 secondTemplate = '<input type="text" name="second" class="bootstrap-timepicker-second" maxlength="2"/>'; 265 meridianTemplate = '<input type="text" name="meridian" class="bootstrap-timepicker-meridian" maxlength="2"/>'; 266 } else { 267 hourTemplate = '<span class="bootstrap-timepicker-hour"></span>'; 268 minuteTemplate = '<span class="bootstrap-timepicker-minute"></span>'; 269 secondTemplate = '<span class="bootstrap-timepicker-second"></span>'; 270 meridianTemplate = '<span class="bootstrap-timepicker-meridian"></span>'; 271 } 272 273 templateContent = '<table>'+ 274 '<tr>'+ 275 '<td><a href="#" data-action="incrementHour"><i class="icon-chevron-up"></i></a></td>'+ 276 '<td class="separator"> </td>'+ 277 '<td><a href="#" data-action="incrementMinute"><i class="icon-chevron-up"></i></a></td>'+ 278 (this.showSeconds ? 279 '<td class="separator"> </td>'+ 280 '<td><a href="#" data-action="incrementSecond"><i class="icon-chevron-up"></i></a></td>' 281 : '') + 282 (this.showMeridian ? 283 '<td class="separator"> </td>'+ 284 '<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="icon-chevron-up"></i></a></td>' 285 : '') + 286 '</tr>'+ 287 '<tr>'+ 288 '<td>'+ hourTemplate +'</td> '+ 289 '<td class="separator">:</td>'+ 290 '<td>'+ minuteTemplate +'</td> '+ 291 (this.showSeconds ? 292 '<td class="separator">:</td>'+ 293 '<td>'+ secondTemplate +'</td>' 294 : '') + 295 (this.showMeridian ? 296 '<td class="separator"> </td>'+ 297 '<td>'+ meridianTemplate +'</td>' 298 : '') + 299 '</tr>'+ 300 '<tr>'+ 301 '<td><a href="#" data-action="decrementHour"><i class="icon-chevron-down"></i></a></td>'+ 302 '<td class="separator"></td>'+ 303 '<td><a href="#" data-action="decrementMinute"><i class="icon-chevron-down"></i></a></td>'+ 304 (this.showSeconds ? 305 '<td class="separator"> </td>'+ 306 '<td><a href="#" data-action="decrementSecond"><i class="icon-chevron-down"></i></a></td>' 307 : '') + 308 (this.showMeridian ? 309 '<td class="separator"> </td>'+ 310 '<td><a href="#" data-action="toggleMeridian"><i class="icon-chevron-down"></i></a></td>' 311 : '') + 312 '</tr>'+ 313 '</table>'; 314 315 switch(this.template) { 316 case 'modal': 317 template = '<div class="bootstrap-timepicker-widget modal hide fade in" data-backdrop="'+ (this.modalBackdrop ? 'true' : 'false') +'">'+ 318 '<div class="modal-header">'+ 319 '<a href="#" class="close" data-dismiss="modal">
319Ã</a>'+ 320 '<h3>Pick a Time</h3>'+ 321 '</div>'+ 322 '<div class="modal-content">'+ 323 templateContent + 324 '</div>'+ 325 '<div class="modal-footer">'+ 326 '<a href="#" class="btn btn-primary" data-dismiss="modal">OK</a>'+ 327 '</div>'+ 328 '</div>'; 329 break; 330 case 'dropdown': 331 template = '<div class="bootstrap-timepicker-widget dropdown-menu">'+ templateContent +'</div>'; 332 break; 333 } 334 335 return template; 336 }, 337 338 getTime: function() { 339 return this.formatTime(this.hour, this.minute, this.second, this.meridian); 340 }, 341 342 hideWidget: function() { 343 if (this.isOpen === false) { 344 return; 345 } 346 347 if (this.showInputs) { 348 this.updateFromWidgetInputs(); 349 } 350 351 this.$element.trigger({ 352 'type': 'hide.timepicker', 353 'time': { 354 'value': this.getTime(), 355 'hours': this.hour, 356 'minutes': this.minute, 357 'seconds': this.second, 358 'meridian': this.meridian 359 } 360 }); 361 362 if (this.template === 'modal') { 363 this.$widget.modal('hide'); 364 } else { 365 this.$widget.removeClass('open'); 366 } 367 368 $(document).off('mousedown.timepicker'); 369 370 this.isOpen = false; 371 }, 372 373 highlightUnit: function() { 374 this.position = this.getCursorPosition(); 375 if (this.position >= 0 && this.position <= 2) { 376 this.highlightHour(); 377 } else if (this.position >= 3 && this.position <= 5) { 378 this.highlightMinute(); 379 } else if (this.position >= 6 && this.position <= 8) { 380 if (this.showSeconds) { 381 this.highlightSecond(); 382 } else { 383 this.highlightMeridian(); 384 } 385 } else if (this.position >= 9 && this.position <= 11) { 386 this.highlightMeridian(); 387 } 388 }, 389 390 highlightNextUnit: function() { 391 switch (this.highlightedUnit) { 392 case 'hour': 393 this.highlightMinute(); 394 break; 395 case 'minute': 396 if (this.showSeconds) { 397 this.highlightSecond(); 398 } else if (this.showMeridian){ 399 this.highlightMeridian(); 400 } else { 401 this.highlightHour(); 402 } 403 break; 404 case 'second': 405 if (this.showMeridian) { 406 this.highlightMeridian(); 407 } else { 408 this.highlightHour(); 409 } 410 break; 411 case 'meridian': 412 this.highlightHour(); 413 break; 414 } 415 }, 416 417 highlightPrevUnit: function() { 418 switch (this.highlightedUnit) { 419 case 'hour': 420 this.highlightMeridian(); 421 break; 422 case 'minute': 423 this.highlightHour(); 424 break; 425 case 'second': 426 this.highlightMinute(); 427 break; 428 case 'meridian': 429 if (this.showSeconds) { 430 this.highlightSecond(); 431 } else { 432 this.highlightMinute(); 433 } 434 break; 435 } 436 }, 437 438 highlightHour: function() { 439 var $element = this.$element.get(0); 440 441 this.highlightedUnit = 'hour'; 442 443 if ($element.setSelectionRange) { 444 setTimeout(function() { 445 $element.setSelectionRange(0,2); 446 }, 0); 447 } 448 }, 449 450 highlightMinute: function() { 451 var $element = this.$element.get(0); 452 453 this.highlightedUnit = 'minute'; 454 455 if ($element.setSelectionRange) { 456 setTimeout(function() { 457 $element.setSelectionRange(3,5); 458 }, 0); 459 } 460 }, 461 462 highlightSecond: function() { 463 var $element = this.$element.get(0); 464 465 this.highlightedUnit = 'second'; 466 467 if ($element.setSelectionRange) { 468 setTimeout(function() { 469 $element.setSelectionRange(6,8); 470 }, 0); 471 } 472 }, 473 474 highlightMeridian: function() { 475 var $element = this.$element.get(0); 476 477 this.highlightedUnit = 'meridian'; 478 479 if ($element.setSelectionRange) { 480 if (this.showSeconds) { 481 setTimeout(function() { 482 $element.setSelectionRange(9,11);
483 }, 0); 484 } else { 485 setTimeout(function() { 486 $element.setSelectionRange(6,8); 487 }, 0); 488 } 489 } 490 }, 491 492 incrementHour: function() { 493 if (this.showMeridian) { 494 if (this.hour === 11) { 495 this.hour++; 496 return this.toggleMeridian(); 497 } else if (this.hour === 12) { 498 this.hour = 0; 499 } 500 } 501 if (this.hour === 23) { 502 return this.hour = 0; 503 } 504 this.hour++; 505 this.update(); 506 }, 507 508 incrementMinute: function(step) { 509 var newVal; 510 511 if (step) { 512 newVal = this.minute + step; 513 } else { 514 newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep); 515 } 516 517 if (newVal > 59) { 518 this.incrementHour(); 519 this.minute = newVal - 60; 520 } else { 521 this.minute = newVal; 522 } 523 this.update(); 524 }, 525 526 incrementSecond: function() { 527 var newVal = this.second + this.secondStep - (this.second % this.secondStep); 528 529 if (newVal > 59) { 530 this.incrementMinute(true); 531 this.second = newVal - 60; 532 } else { 533 this.second = newVal; 534 } 535 this.update(); 536 }, 537 538 remove: function() { 539 $('document').off('.timepicker'); 540 if (this.$widget) { 541 this.$widget.remove(); 542 } 543 delete this.$element.data().timepicker; 544 }, 545 546 setDefaultTime: function(defaultTime){ 547 if (!this.$element.val()) { 548 if (defaultTime === 'current') { 549 var dTime = new Date(), 550 hours = dTime.getHours(), 551 minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep, 552 seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep, 553 meridian = 'AM'; 554 555 if (this.showMeridian) { 556 if (hours === 0) { 557 hours = 12; 558 } else if (hours >= 12) { 559 if (hours > 12) { 560 hours = hours - 12; 561 } 562 meridian = 'PM'; 563 } else { 564 meridian = 'AM'; 565 } 566 } 567 568 this.hour = hours; 569 this.minute = minutes; 570 this.second = seconds; 571 this.meridian = meridian; 572 573 this.update(); 574 575 } else if (defaultTime === false) { 576 this.hour = 0; 577 this.minute = 0; 578 this.second = 0; 579 this.meridian = 'AM'; 580 } else { 581 this.setTime(defaultTime); 582 } 583 } else { 584 this.updateFromElementVal(); 585 } 586 }, 587 588 setTime: function(time) { 589 var arr, 590 timeArray; 591 592 if (this.showMeridian) { 593 arr = time.split(' '); 594 timeArray = arr[0].split(':'); 595 this.meridian = arr[1]; 596 } else { 597 timeArray = time.split(':'); 598 } 599 600 this.hour = parseInt(timeArray[0], 10); 601 this.minute = parseInt(timeArray[1], 10); 602 this.second = parseInt(timeArray[2], 10); 603 604 if (isNaN(this.hour)) { 605 this.hour = 0; 606 } 607 if (isNaN(this.minute)) { 608 this.minute = 0; 609 } 610 611 if (this.showMeridian) { 612 if (this.hour > 12) { 613 this.hour = 12; 614 } else if (this.hour < 1) { 615 this.hour = 12; 616 } 617 618 if (this.meridian === 'am' || this.meridian === 'a') { 619 this.meridian = 'AM'; 620 } else if (this.meridian === 'pm' || this.meridian === 'p') { 621 this.meridian = 'PM'; 622 } 623 624 if (this.meridian !== 'AM' && this.meridian !== 'PM') { 625 this.meridian = 'AM'; 626 } 627 } else { 628 if (this.hour >= 24) { 629 this.hour = 23; 630 } else if (this.hour < 0) { 631 this.hour = 0; 632 } 633 } 634 635 if (this.minute < 0) { 636 this.minute = 0; 637 } else if (this.minute >= 60) { 638 this.minute = 59; 639 } 640 641 if (this.showSeconds) { 642 if (isNaN(this.second)) { 643 this.second = 0; 644 } else if (this.second < 0) { 645 this.second = 0; 646 } else if (this.second >= 60) { 647 this.second = 59; 648 } 649 } 650 651 this.update(); 652 }, 653 654 showWidget: function() { 655 if (this.isOpen) { 656 return; 657 } 658 659 var self = this; 660 $(document).on('mousedown.timepicker', function (e) { 661 // Clicked outside the timepicker, hide it 662 if ($(e.target).closest('.bootstrap-timepicker-widget').length === 0) { 663 self.hideWidget(); 664 } 665 }); 666 667 this.$element.trigger({ 668 'type': 'show.timepicker', 669 'time': { 670 'value': this.getTime(), 671 'hours': this.hour, 672 'minutes': this.minute, 673 'seconds': this.second, 674 'meridian': this.meridian 675 } 676 }); 677 678 if (this.disableFocus) { 679 this.$element.blur(); 680 } 681 682 this.updateFromElementVal(); 683 684 if (this.template === 'modal') { 685 this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this)); 686 } else { 687 if (this.isOpen === false) { 688 this.$widget.addClass('open'); 689 } 690 } 691 692 this.isOpen = true; 693 }, 694 695 toggleMeridian: function() { 696 this.meridian = this.meridian === 'AM' ? 'PM' : 'AM'; 697 this.update(); 698 }, 699 700 update: function() { 701 this.$element.trigger({ 702 'type': 'changeTime.timepicker', 703 'time': { 704 'value': this.getTime(), 705 'hours': this.hour, 706 'minutes': this.minute, 707 'seconds': this.second, 708 'meridian': this.meridian 709 } 710 }); 711 712 this.updateElement(); 713 this.updateWidget(); 714 }, 715 716 updateElement: function() { 717 this.$element.val(this.getTime()).change(); 718 }, 719 720 updateFromElementVal: function() { 721 var val = this.$element.val(); 722 723 if (val) { 724 this.setTime(val); 725 } 726 }, 727 728 updateWidget: function() { 729 if (this.$widget === false) { 730 return; 731 } 732 733 var hour = this.hour < 10 ? '0' + this.hour : this.hour, 734 minute = this.minute < 10 ? '0' + this.minute : this.minute, 735 second = this.second < 10 ? '0' + this.second : this.second; 736 737 if (this.showInputs) { 738 this.$widget.find('input.bootstrap-timepicker-hour').val(hour); 739 this.$widget.find('input.bootstrap-timepicker-minute').val(minute); 740 741 if (this.showSeconds) { 742 this.$widget.find('input.bootstrap-timepicker-second').val(second); 743 } 744 if (this.showMeridian) { 745 this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian); 746 } 747 } else { 748 this.$widget.find('span.bootstrap-timepicker-hour').text(hour); 749 this.$widget.find('span.bootstrap-timepicker-minute').text(minute); 750 751 if (this.showSeconds) { 752 this.$widget.find('span.bootstrap-timepicker-second').text(second); 753 } 754 if (this.showMeridian) { 755 this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian); 756 } 757 } 758 }, 759
760 updateFromWidgetInputs: function() { 761 if (this.$widget === false) { 762 return; 763 } 764 var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' + 765 $('input.bootstrap-timepicker-minute', this.$widget).val() + 766 (this.showSeconds ? ':' + $('input.bootstrap-timepicker-second', this.$widget).val() : '') + 767 (this.showMeridian ? ' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val() : ''); 768 769 this.setTime(time); 770 }, 771 772 widgetClick: function(e) { 773 e.stopPropagation(); 774 e.preventDefault(); 775 776 var action = $(e.target).closest('a').data('action'); 777 if (action) { 778 this[action](); 779 } 780 }, 781 782 widgetKeydown: function(e) { 783 var $input = $(e.target).closest('input'), 784 name = $input.attr('name'); 785 786 switch (e.keyCode) { 787 case 9: //tab 788 if (this.showMeridian) { 789 if (name === 'meridian') { 790 return this.hideWidget(); 791 } 792 } else { 793 if (this.showSeconds) { 794 if (name === 'second') { 795 return this.hideWidget(); 796 } 797 } else { 798 if (name === 'minute') { 799 return this.hideWidget(); 800 } 801 } 802 } 803 804 this.updateFromWidgetInputs(); 805 break; 806 case 27: // escape 807 this.hideWidget(); 808 break; 809 case 38: // up arrow 810 e.preventDefault(); 811 switch (name) { 812 case 'hour': 813 this.incrementHour(); 814 break; 815 case 'minute': 816 this.incrementMinute(); 817 break; 818 case 'second': 819 this.incrementSecond(); 820 break; 821 case 'meridian': 822 this.toggleMeridian(); 823 break; 824 } 825 break; 826 case 40: // down arrow 827 e.preventDefault(); 828 switch (name) { 829 case 'hour': 830 this.decrementHour(); 831 break; 832 case 'minute': 833 this.decrementMinute(); 834 break; 835 case 'second': 836 this.decrementSecond(); 837 break; 838 case 'meridian': 839 this.toggleMeridian(); 840 break; 841 } 842 break; 843 } 844 } 845 }; 846 847 848 //TIMEPICKER PLUGIN DEFINITION 849 $.fn.timepicker = function(option) { 850 var args = Array.apply(null, arguments); 851 args.shift(); 852 return this.each(function() { 853 var $this = $(this), 854 data = $this.data('timepicker'), 855 options = typeof option === 'object' && option; 856 857 if (!data) { 858 $this.data('timepicker', (data = new Timepicker(this, $.extend({}, $.fn.timepicker.defaults, options, $(this).data())))); 859 } 860 861 if (typeof option === 'string') { 862 data[option].apply(data, args); 863 } 864 }); 865 }; 866 867 $.fn.timepicker.defaults = { 868 defaultTime: 'current', 869 disableFocus: false, 870 isOpen: false, 871 minuteStep: 15, 872 modalBackdrop: false, 873 secondStep: 15, 874 showSeconds: false, 875 showInputs: true, 876 showMeridian: true, 877 template: 'dropdown', 878 appendWidgetTo: '.bootstrap-timepicker' 879 }; 880 881 $.fn.timepicker.Constructor = Timepicker; 882 883})(jQuery, window, document);
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.