]>
git.proxmox.com Git - ceph.git/blob - ceph/src/pybind/mgr/dashboard/static/AdminLTE-2.3.7/plugins/timepicker/bootstrap-timepicker.js
1 //TODO: move arrow styles and button click code into configurable items, with defaults matching the existing code
4 * Timepicker Component for Twitter Bootstrap
6 * Copyright 2013 Joris de Wit
8 * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors
10 * For the full copyright and license information, please view the LICENSE
11 * file that was distributed with this source code.
13 (function($, window
, document
, undefined) {
16 // TIMEPICKER PUBLIC CLASS DEFINITION
17 var Timepicker = function(element
, options
) {
19 this.$element
= $(element
);
20 this.defaultTime
= options
.defaultTime
;
21 this.disableFocus
= options
.disableFocus
;
22 this.isOpen
= options
.isOpen
;
23 this.minuteStep
= options
.minuteStep
;
24 this.modalBackdrop
= options
.modalBackdrop
;
25 this.secondStep
= options
.secondStep
;
26 this.showInputs
= options
.showInputs
;
27 this.showMeridian
= options
.showMeridian
;
28 this.showSeconds
= options
.showSeconds
;
29 this.template
= options
.template
;
30 this.appendWidgetTo
= options
.appendWidgetTo
;
31 this.upArrowStyle
= options
.upArrowStyle
;
32 this.downArrowStyle
= options
.downArrowStyle
;
33 this.containerClass
= options
.containerClass
;
38 Timepicker
.prototype = {
40 constructor: Timepicker
,
45 if (this.$element
.parent().hasClass('input-append') || this.$element
.parent().hasClass('input-prepend')) {
46 if (this.$element
.parent('.input-append, .input-prepend').find('.add-on').length
) {
47 this.$element
.parent('.input-append, .input-prepend').find('.add-on').on({
48 'click.timepicker': $.proxy(this.showWidget
, this)
51 this.$element
.closest(this.containerClass
).find('.add-on').on({
52 'click.timepicker': $.proxy(this.showWidget
, this)
57 'focus.timepicker': $.proxy(this.highlightUnit
, this),
58 'click.timepicker': $.proxy(this.highlightUnit
, this),
59 'keydown.timepicker': $.proxy(this.elementKeydown
, this),
60 'blur.timepicker': $.proxy(this.blurElement
, this)
65 'focus.timepicker': $.proxy(this.showWidget
, this),
66 'click.timepicker': $.proxy(this.showWidget
, this),
67 'blur.timepicker': $.proxy(this.blurElement
, this)
71 'focus.timepicker': $.proxy(this.highlightUnit
, this),
72 'click.timepicker': $.proxy(this.highlightUnit
, this),
73 'keydown.timepicker': $.proxy(this.elementKeydown
, this),
74 'blur.timepicker': $.proxy(this.blurElement
, this)
79 if (this.template
!== false) {
80 this.$widget
= $(this.getTemplate()).prependTo(this.$element
.parents(this.appendWidgetTo
)).on('click', $.proxy(this.widgetClick
, this));
85 if (this.showInputs
&& this.$widget
!== false) {
86 this.$widget
.find('input').each(function() {
88 'click.timepicker': function() { $(this).select(); },
89 'keydown.timepicker': $.proxy(self
.widgetKeydown
, self
)
94 this.setDefaultTime(this.defaultTime
);
97 blurElement: function() {
98 this.highlightedUnit
= undefined;
99 this.updateFromElementVal();
102 decrementHour: function() {
103 if (this.showMeridian
) {
104 if (this.hour
=== 1) {
106 } else if (this.hour
=== 12) {
109 return this.toggleMeridian();
110 } else if (this.hour
=== 0) {
113 return this.toggleMeridian();
118 if (this.hour
=== 0) {
127 decrementMinute: function(step
) {
131 newVal
= this.minute
- step
;
133 newVal
= this.minute
- this.minuteStep
;
137 this.decrementHour();
138 this.minute
= newVal
+ 60;
140 this.minute
= newVal
;
145 decrementSecond: function() {
146 var newVal
= this.second
- this.secondStep
;
149 this.decrementMinute(true);
150 this.second
= newVal
+ 60;
152 this.second
= newVal
;
157 elementKeydown: function(e
) {
160 this.updateFromElementVal();
162 switch (this.highlightedUnit
) {
165 this.highlightNextUnit();
168 if (this.showMeridian
|| this.showSeconds
) {
170 this.highlightNextUnit();
174 if (this.showMeridian
) {
176 this.highlightNextUnit();
182 this.updateFromElementVal();
184 case 37: // left arrow
186 this.highlightPrevUnit();
187 this.updateFromElementVal();
191 switch (this.highlightedUnit
) {
193 this.incrementHour();
194 this.highlightHour();
197 this.incrementMinute();
198 this.highlightMinute();
201 this.incrementSecond();
202 this.highlightSecond();
205 this.toggleMeridian();
206 this.highlightMeridian();
210 case 39: // right arrow
212 this.updateFromElementVal();
213 this.highlightNextUnit();
215 case 40: // down arrow
217 switch (this.highlightedUnit
) {
219 this.decrementHour();
220 this.highlightHour();
223 this.decrementMinute();
224 this.highlightMinute();
227 this.decrementSecond();
228 this.highlightSecond();
231 this.toggleMeridian();
232 this.highlightMeridian();
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
;
244 return hour
+ ':' + minute
+ (this.showSeconds
? ':' + second
: '') + (this.showMeridian
? ' ' + meridian
: '');
247 getCursorPosition: function() {
248 var input
= this.$element
.get(0);
250 if ('selectionStart' in input
) {// Standard-compliant browsers
252 return input
.selectionStart
;
253 } else if (document
.selection
) {// IE fix
255 var sel
= document
.selection
.createRange(),
256 selLen
= document
.selection
.createRange().text
.length
;
258 sel
.moveStart('character', - input
.value
.length
);
260 return sel
.text
.length
- selLen
;
264 getTemplate: function() {
272 if (this.showInputs
) {
273 hourTemplate
= '<input type="text" name="hour" class="bootstrap-timepicker-hour form-control" maxlength="2"/>';
274 minuteTemplate
= '<input type="text" name="minute" class="bootstrap-timepicker-minute form-control" maxlength="2"/>';
275 secondTemplate
= '<input type="text" name="second" class="bootstrap-timepicker-second form-control" maxlength="2"/>';
276 meridianTemplate
= '<input type="text" name="meridian" class="bootstrap-timepicker-meridian form-control" maxlength="2"/>';
278 hourTemplate
= '<span class="bootstrap-timepicker-hour"></span>';
279 minuteTemplate
= '<span class="bootstrap-timepicker-minute"></span>';
280 secondTemplate
= '<span class="bootstrap-timepicker-second"></span>';
281 meridianTemplate
= '<span class="bootstrap-timepicker-meridian"></span>';
284 templateContent
= '<table>'+
286 '<td><a href="#" data-action="incrementHour"><i class="' + this.upArrowStyle
+ '"></i></a></td>'+
287 '<td class="separator"> </td>'+
288 '<td><a href="#" data-action="incrementMinute"><i class="' + this.upArrowStyle
+ '"></i></a></td>'+
290 '<td class="separator"> </td>'+
291 '<td><a href="#" data-action="incrementSecond"><i class="' + this.upArrowStyle
+ '"></i></a></td>'
294 '<td class="separator"> </td>'+
295 '<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="' + this.upArrowStyle
+ '"></i></a></td>'
299 '<td>'+ hourTemplate
+'</td> '+
300 '<td class="separator">:</td>'+
301 '<td>'+ minuteTemplate
+'</td> '+
303 '<td class="separator">:</td>'+
304 '<td>'+ secondTemplate
+'</td>'
307 '<td class="separator"> </td>'+
308 '<td>'+ meridianTemplate
+'</td>'
312 '<td><a href="#" data-action="decrementHour"><i class="' + this.downArrowStyle
+ '"></i></a></td>'+
313 '<td class="separator"></td>'+
314 '<td><a href="#" data-action="decrementMinute"><i class="' + this.downArrowStyle
+ '"></i></a></td>'+
316 '<td class="separator"> </td>'+
317 '<td><a href="#" data-action="decrementSecond"><i class="' + this.downArrowStyle
+ '"></i></a></td>'
320 '<td class="separator"> </td>'+
321 '<td><a href="#" data-action="toggleMeridian"><i class="' + this.downArrowStyle
+ '"></i></a></td>'
326 switch(this.template
) {
328 template
= '<div class="bootstrap-timepicker-widget modal hide fade in" data-backdrop="'+ (this.modalBackdrop
? 'true' : 'false') +'">'+
329 '<div class="modal-header">'+
330 '<a href="#" class="close" data-dismiss="modal">×</a>'+
331 '<h3>Pick a Time</h3>'+
333 '<div class="modal-content">'+
336 '<div class="modal-footer">'+
337 '<a href="#" class="btn btn-primary" data-dismiss="modal">OK</a>'+
342 template
= '<div class="bootstrap-timepicker-widget dropdown-menu">'+ templateContent
+'</div>';
349 getTime: function() {
350 return this.formatTime(this.hour
, this.minute
, this.second
, this.meridian
);
353 hideWidget: function() {
354 if (this.isOpen
=== false) {
358 if (this.showInputs
) {
359 this.updateFromWidgetInputs();
362 this.$element
.trigger({
363 'type': 'hide.timepicker',
365 'value': this.getTime(),
367 'minutes': this.minute
,
368 'seconds': this.second
,
369 'meridian': this.meridian
373 if (this.template
=== 'modal' && this.$widget
.modal
) {
374 this.$widget
.modal('hide');
376 this.$widget
.removeClass('open');
379 $(document
).off('mousedown.timepicker');
384 highlightUnit: function() {
385 this.position
= this.getCursorPosition();
386 if (this.position
>= 0 && this.position
<= 2) {
387 this.highlightHour();
388 } else if (this.position
>= 3 && this.position
<= 5) {
389 this.highlightMinute();
390 } else if (this.position
>= 6 && this.position
<= 8) {
391 if (this.showSeconds
) {
392 this.highlightSecond();
394 this.highlightMeridian();
396 } else if (this.position
>= 9 && this.position
<= 11) {
397 this.highlightMeridian();
401 highlightNextUnit: function() {
402 switch (this.highlightedUnit
) {
404 this.highlightMinute();
407 if (this.showSeconds
) {
408 this.highlightSecond();
409 } else if (this.showMeridian
){
410 this.highlightMeridian();
412 this.highlightHour();
416 if (this.showMeridian
) {
417 this.highlightMeridian();
419 this.highlightHour();
423 this.highlightHour();
428 highlightPrevUnit: function() {
429 switch (this.highlightedUnit
) {
431 this.highlightMeridian();
434 this.highlightHour();
437 this.highlightMinute();
440 if (this.showSeconds
) {
441 this.highlightSecond();
443 this.highlightMinute();
449 highlightHour: function() {
450 var $element
= this.$element
.get(0);
452 this.highlightedUnit
= 'hour';
454 if ($element
.setSelectionRange
) {
455 setTimeout(function() {
456 $element
.setSelectionRange(0,2);
461 highlightMinute: function() {
462 var $element
= this.$element
.get(0);
464 this.highlightedUnit
= 'minute';
466 if ($element
.setSelectionRange
) {
467 setTimeout(function() {
468 $element
.setSelectionRange(3,5);
473 highlightSecond: function() {
474 var $element
= this.$element
.get(0);
476 this.highlightedUnit
= 'second';
478 if ($element
.setSelectionRange
) {
479 setTimeout(function() {
480 $element
.setSelectionRange(6,8);
485 highlightMeridian: function() {
486 var $element
= this.$element
.get(0);
488 this.highlightedUnit
= 'meridian';
490 if ($element
.setSelectionRange
) {
491 if (this.showSeconds
) {
492 setTimeout(function() {
493 $element
.setSelectionRange(9,11);
496 setTimeout(function() {
497 $element
.setSelectionRange(6,8);
503 incrementHour: function() {
504 if (this.showMeridian
) {
505 if (this.hour
=== 11) {
507 return this.toggleMeridian();
508 } else if (this.hour
=== 12) {
512 if (this.hour
=== 23) {
521 incrementMinute: function(step
) {
525 newVal
= this.minute
+ step
;
527 newVal
= this.minute
+ this.minuteStep
- (this.minute
% this.minuteStep
);
531 this.incrementHour();
532 this.minute
= newVal
- 60;
534 this.minute
= newVal
;
539 incrementSecond: function() {
540 var newVal
= this.second
+ this.secondStep
- (this.second
% this.secondStep
);
543 this.incrementMinute(true);
544 this.second
= newVal
- 60;
546 this.second
= newVal
;
552 $('document').off('.timepicker');
554 this.$widget
.remove();
556 delete this.$element
.data().timepicker
;
559 setDefaultTime: function(defaultTime
){
560 if (!this.$element
.val()) {
561 if (defaultTime
=== 'current') {
562 var dTime
= new Date(),
563 hours
= dTime
.getHours(),
564 minutes
= Math
.floor(dTime
.getMinutes() / this.minuteStep
) * this.minuteStep
,
565 seconds
= Math
.floor(dTime
.getSeconds() / this.secondStep
) * this.secondStep
,
568 if (this.showMeridian
) {
571 } else if (hours
>= 12) {
582 this.minute
= minutes
;
583 this.second
= seconds
;
584 this.meridian
= meridian
;
588 } else if (defaultTime
=== false) {
592 this.meridian
= 'AM';
594 this.setTime(defaultTime
);
597 this.updateFromElementVal();
601 setTime: function(time
) {
605 if (this.showMeridian
) {
606 arr
= time
.split(' ');
607 timeArray
= arr
[0].split(':');
608 this.meridian
= arr
[1];
610 timeArray
= time
.split(':');
613 this.hour
= parseInt(timeArray
[0], 10);
614 this.minute
= parseInt(timeArray
[1], 10);
615 this.second
= parseInt(timeArray
[2], 10);
617 if (isNaN(this.hour
)) {
620 if (isNaN(this.minute
)) {
624 if (this.showMeridian
) {
625 if (this.hour
> 12) {
627 } else if (this.hour
< 1) {
631 if (this.meridian
=== 'am' || this.meridian
=== 'a') {
632 this.meridian
= 'AM';
633 } else if (this.meridian
=== 'pm' || this.meridian
=== 'p') {
634 this.meridian
= 'PM';
637 if (this.meridian
!== 'AM' && this.meridian
!== 'PM') {
638 this.meridian
= 'AM';
641 if (this.hour
>= 24) {
643 } else if (this.hour
< 0) {
648 if (this.minute
< 0) {
650 } else if (this.minute
>= 60) {
654 if (this.showSeconds
) {
655 if (isNaN(this.second
)) {
657 } else if (this.second
< 0) {
659 } else if (this.second
>= 60) {
667 showWidget: function() {
672 if (this.$element
.is(':disabled')) {
677 $(document
).on('mousedown.timepicker', function (e
) {
678 // Clicked outside the timepicker, hide it
679 if ($(e
.target
).closest('.bootstrap-timepicker-widget').length
=== 0) {
684 this.$element
.trigger({
685 'type': 'show.timepicker',
687 'value': this.getTime(),
689 'minutes': this.minute
,
690 'seconds': this.second
,
691 'meridian': this.meridian
695 if (this.disableFocus
) {
696 this.$element
.blur();
699 this.updateFromElementVal();
701 if (this.template
=== 'modal' && this.$widget
.modal
) {
702 this.$widget
.modal('show').on('hidden', $.proxy(this.hideWidget
, this));
704 if (this.isOpen
=== false) {
705 this.$widget
.addClass('open');
712 toggleMeridian: function() {
713 this.meridian
= this.meridian
=== 'AM' ? 'PM' : 'AM';
718 this.$element
.trigger({
719 'type': 'changeTime.timepicker',
721 'value': this.getTime(),
723 'minutes': this.minute
,
724 'seconds': this.second
,
725 'meridian': this.meridian
729 this.updateElement();
733 updateElement: function() {
734 this.$element
.val(this.getTime()).change();
737 updateFromElementVal: function() {
738 var val
= this.$element
.val();
745 updateWidget: function() {
746 if (this.$widget
=== false) {
750 var hour
= this.hour
< 10 ? '0' + this.hour
: this.hour
,
751 minute
= this.minute
< 10 ? '0' + this.minute
: this.minute
,
752 second
= this.second
< 10 ? '0' + this.second
: this.second
;
754 if (this.showInputs
) {
755 this.$widget
.find('input.bootstrap-timepicker-hour').val(hour
);
756 this.$widget
.find('input.bootstrap-timepicker-minute').val(minute
);
758 if (this.showSeconds
) {
759 this.$widget
.find('input.bootstrap-timepicker-second').val(second
);
761 if (this.showMeridian
) {
762 this.$widget
.find('input.bootstrap-timepicker-meridian').val(this.meridian
);
765 this.$widget
.find('span.bootstrap-timepicker-hour').text(hour
);
766 this.$widget
.find('span.bootstrap-timepicker-minute').text(minute
);
768 if (this.showSeconds
) {
769 this.$widget
.find('span.bootstrap-timepicker-second').text(second
);
771 if (this.showMeridian
) {
772 this.$widget
.find('span.bootstrap-timepicker-meridian').text(this.meridian
);
777 updateFromWidgetInputs: function() {
778 if (this.$widget
=== false) {
781 var time
= $('input.bootstrap-timepicker-hour', this.$widget
).val() + ':' +
782 $('input.bootstrap-timepicker-minute', this.$widget
).val() +
783 (this.showSeconds
? ':' + $('input.bootstrap-timepicker-second', this.$widget
).val() : '') +
784 (this.showMeridian
? ' ' + $('input.bootstrap-timepicker-meridian', this.$widget
).val() : '');
789 widgetClick: function(e
) {
793 var action
= $(e
.target
).closest('a').data('action');
799 widgetKeydown: function(e
) {
800 var $input
= $(e
.target
).closest('input'),
801 name
= $input
.attr('name');
805 if (this.showMeridian
) {
806 if (name
=== 'meridian') {
807 return this.hideWidget();
810 if (this.showSeconds
) {
811 if (name
=== 'second') {
812 return this.hideWidget();
815 if (name
=== 'minute') {
816 return this.hideWidget();
821 this.updateFromWidgetInputs();
830 this.incrementHour();
833 this.incrementMinute();
836 this.incrementSecond();
839 this.toggleMeridian();
843 case 40: // down arrow
847 this.decrementHour();
850 this.decrementMinute();
853 this.decrementSecond();
856 this.toggleMeridian();
865 //TIMEPICKER PLUGIN DEFINITION
866 $.fn
.timepicker = function(option
) {
867 var args
= Array
.apply(null, arguments
);
869 return this.each(function() {
871 data
= $this.data('timepicker'),
872 options
= typeof option
=== 'object' && option
;
875 $this.data('timepicker', (data
= new Timepicker(this, $.extend({}, $.fn
.timepicker
.defaults
, options
, $(this).data()))));
878 if (typeof option
=== 'string') {
879 data
[option
].apply(data
, args
);
884 $.fn
.timepicker
.defaults
= {
885 defaultTime
: 'current',
889 modalBackdrop
: false,
894 template
: 'dropdown',
895 appendWidgetTo
: '.bootstrap-timepicker',
896 upArrowStyle
: 'glyphicon glyphicon-chevron-up',
897 downArrowStyle
: 'glyphicon glyphicon-chevron-down',
898 containerClass
: 'bootstrap-timepicker'
901 $.fn
.timepicker
.Constructor
= Timepicker
;
903 })(jQuery
, window
, document
);