mirror of https://github.com/grafana/grafana
parent
a73242cae5
commit
834e63a123
@ -1,156 +0,0 @@ |
|||||||
/* ========================================================= |
|
||||||
* bootstrap-datepicker.js |
|
||||||
* original by Stefan Petre |
|
||||||
* tweaked by gus |
|
||||||
* ========================================================= */ |
|
||||||
|
|
||||||
.bs-sc-datepicker.dropdown-menu { |
|
||||||
max-width: inherit; |
|
||||||
} |
|
||||||
.bs-sc-datepicker { |
|
||||||
top: 0; |
|
||||||
left: 0; |
|
||||||
padding: 4px; |
|
||||||
margin-top: 1px; |
|
||||||
-webkit-border-radius: 4px; |
|
||||||
-moz-border-radius: 4px; |
|
||||||
border-radius: 4px; |
|
||||||
z-index: 1051; |
|
||||||
} |
|
||||||
.bs-sc-datepicker:before { |
|
||||||
content: ''; |
|
||||||
display: inline-block; |
|
||||||
border-left: 7px solid transparent; |
|
||||||
border-right: 7px solid transparent; |
|
||||||
border-bottom: 7px solid #ccc; |
|
||||||
border-bottom-color: rgba(0, 0, 0, 0.2); |
|
||||||
position: absolute; |
|
||||||
top: -7px; |
|
||||||
left: 6px; |
|
||||||
} |
|
||||||
.bs-sc-datepicker:after { |
|
||||||
content: ''; |
|
||||||
display: inline-block; |
|
||||||
border-left: 6px solid transparent; |
|
||||||
border-right: 6px solid transparent; |
|
||||||
border-bottom: 6px solid #ffffff; |
|
||||||
position: absolute; |
|
||||||
top: -6px; |
|
||||||
left: 7px; |
|
||||||
} |
|
||||||
.bs-sc-datepicker table { |
|
||||||
width: 100%; |
|
||||||
margin: 0; |
|
||||||
} |
|
||||||
.bs-sc-datepicker th { |
|
||||||
border-bottom: 1px solid #efefef; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td, .bs-sc-datepicker th { |
|
||||||
text-align: center; |
|
||||||
width: 20px; |
|
||||||
height: 20px; |
|
||||||
-webkit-border-radius: 4px; |
|
||||||
-moz-border-radius: 4px; |
|
||||||
border-radius: 4px; |
|
||||||
padding: 5px !important; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td.day:hover { |
|
||||||
background: #eeeeee; |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td.old, .bs-sc-datepicker td.new { |
|
||||||
color: #DDDDDD; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td.active, .bs-sc-datepicker td.active:hover { |
|
||||||
background-color: #006dcc; |
|
||||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); |
|
||||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-repeat: repeat-x; |
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); |
|
||||||
border-color: #0044cc #0044cc #002a80; |
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||||
color: #fff; |
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); |
|
||||||
} |
|
||||||
.bs-sc-datepicker td.active:hover, |
|
||||||
.bs-sc-datepicker td.active:hover:hover, |
|
||||||
.bs-sc-datepicker td.active:active, |
|
||||||
.bs-sc-datepicker td.active:hover:active, |
|
||||||
.bs-sc-datepicker td.active.active, |
|
||||||
.bs-sc-datepicker td.active:hover.active, |
|
||||||
.bs-sc-datepicker td.active.disabled, |
|
||||||
.bs-sc-datepicker td.active:hover.disabled, |
|
||||||
.bs-sc-datepicker td.active[disabled], |
|
||||||
.bs-sc-datepicker td.active:hover[disabled] { |
|
||||||
background-color: #0044cc; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td.active:active, |
|
||||||
.bs-sc-datepicker td.active:hover:active, |
|
||||||
.bs-sc-datepicker td.active.active, |
|
||||||
.bs-sc-datepicker td.active:hover.active { |
|
||||||
background-color: #003399 \9; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span { |
|
||||||
display: block; |
|
||||||
width: 47px; |
|
||||||
height: 54px; |
|
||||||
line-height: 54px; |
|
||||||
float: left; |
|
||||||
margin: 2px; |
|
||||||
cursor: pointer; |
|
||||||
-webkit-border-radius: 4px; |
|
||||||
-moz-border-radius: 4px; |
|
||||||
border-radius: 4px; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span:hover { |
|
||||||
background: #eeeeee; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span.active { |
|
||||||
background-color: #006dcc; |
|
||||||
background-image: -moz-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -ms-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); |
|
||||||
background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: -o-linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-image: linear-gradient(top, #0088cc, #0044cc); |
|
||||||
background-repeat: repeat-x; |
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); |
|
||||||
border-color: #0044cc #0044cc #002a80; |
|
||||||
border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); |
|
||||||
filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); |
|
||||||
color: #fff; |
|
||||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span.active:hover, |
|
||||||
.bs-sc-datepicker td span.active:active, |
|
||||||
.bs-sc-datepicker td span.active.active, |
|
||||||
.bs-sc-datepicker td span.active.disabled, |
|
||||||
.bs-sc-datepicker td span.active[disabled] { |
|
||||||
background-color: #0044cc; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span.active:active, .bs-sc-datepicker td span.active.active { |
|
||||||
background-color: #003399 \9; |
|
||||||
} |
|
||||||
.bs-sc-datepicker td span.old { |
|
||||||
color: #999999; |
|
||||||
} |
|
||||||
.bs-sc-datepicker th.switch { |
|
||||||
width: 145px; |
|
||||||
} |
|
||||||
.bs-sc-datepicker thead tr:first-child th { |
|
||||||
cursor: pointer; |
|
||||||
} |
|
||||||
.bs-sc-datepicker thead tr:first-child th:hover { |
|
||||||
background: #eeeeee; |
|
||||||
} |
|
||||||
.input-append.date .add-on i, .input-prepend.date .add-on i { |
|
||||||
display: block; |
|
||||||
cursor: pointer; |
|
||||||
width: 16px; |
|
||||||
height: 16px; |
|
||||||
} |
|
@ -0,0 +1,91 @@ |
|||||||
|
|
||||||
|
/* |
||||||
|
Datepicker for Bootstrap |
||||||
|
Copyright 2012 Stefan Petre |
||||||
|
Licensed under the Apache License v2.0 |
||||||
|
http://www.apache.org/licenses/LICENSE-2.0 |
||||||
|
*/ |
||||||
|
input[type="date"] { -webkit-appearance: none; } .datepicker { top: 0; left: 0; padding: 4px; margin-top: 1px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; /*.dow { border-top: 1px solid #ddd !important; }*/ } .datepicker:before { content: ''; display: inline-block; border-left: 7px solid transparent; border-right: 7px solid transparent; border-bottom: 7px solid #ccc; border-bottom-color: rgba(0, 0, 0, 0.2); position: absolute; top: -7px; left: 6px; } .datepicker:after { content: ''; display: inline-block; border-left: 6px solid transparent; border-right: 6px solid transparent; border-bottom: 6px solid #ffffff; position: absolute; top: -6px; left: 7px; } .datepicker > div { display: none; } .datepicker table { width: 100%; margin: 0; } .datepicker td, .datepicker th { text-align: center; width: 20px; height: 20px; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td.day:hover { background: #eeeeee; cursor: pointer; } .datepicker td.old, .datepicker td.new { color: #999999; } .datepicker td.active, .datepicker td.active:hover { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td.active:hover, .datepicker td.active:hover:hover, .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active, .datepicker td.active.disabled, .datepicker td.active:hover.disabled, .datepicker td.active[disabled], .datepicker td.active:hover[disabled] { background-color: #0044cc; } .datepicker td.active:active, .datepicker td.active:hover:active, .datepicker td.active.active, .datepicker td.active:hover.active { background-color: #003399 \9; } .datepicker td span { display: block; width: 47px; height: 54px; line-height: 54px; float: left; margin: 2px; cursor: pointer; -webkit-border-radius: 4px; -moz-border-radius: 4px; border-radius: 4px; } .datepicker td span:hover { background: #eeeeee; } .datepicker td span.active { background-color: #006dcc; background-image: -moz-linear-gradient(top, #0088cc, #0044cc); background-image: -ms-linear-gradient(top, #0088cc, #0044cc); background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#0088cc), to(#0044cc)); background-image: -webkit-linear-gradient(top, #0088cc, #0044cc); background-image: -o-linear-gradient(top, #0088cc, #0044cc); background-image: linear-gradient(top, #0088cc, #0044cc); background-repeat: repeat-x; filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#0088cc', endColorstr='#0044cc', GradientType=0); border-color: #0044cc #0044cc #002a80; border-color: rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.1) rgba(0, 0, 0, 0.25); filter: progid:DXImageTransform.Microsoft.gradient(enabled = false); color: #fff; text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.25); } .datepicker td span.active:hover, .datepicker td span.active:active, .datepicker td span.active.active, .datepicker td span.active.disabled, .datepicker td span.active[disabled] { background-color: #0044cc; } .datepicker td span.active:active, .datepicker td span.active.active { background-color: #003399 \9; } .datepicker td span.old { color: #999999; } .datepicker th.switch { width: 145px; } .datepicker th.next, .datepicker th.prev { font-size: 19.5px; } .datepicker thead tr:first-child th { cursor: pointer; } .datepicker thead tr:first-child th:hover { background: #eeeeee; } .input-append.date .add-on i, .input-prepend.date .add-on i { display: block; cursor: pointer; width: 16px; height: 16px; } |
||||||
|
|
||||||
|
.bootstrap-timepicker.dropdown-menu { |
||||||
|
border-radius: 4px 4px 4px 4px; |
||||||
|
display: none; |
||||||
|
left: 0; |
||||||
|
margin-top: 1px; |
||||||
|
padding: 4px; |
||||||
|
top: 0; |
||||||
|
min-width: 10px; |
||||||
|
z-index: 99999; |
||||||
|
} |
||||||
|
.bootstrap-timepicker.dropdown-menu.open { |
||||||
|
display: inline-block; |
||||||
|
} |
||||||
|
.bootstrap-timepicker.dropdown-menu:before { |
||||||
|
border-bottom: 7px solid rgba(0, 0, 0, 0.2); |
||||||
|
border-left: 7px solid transparent; |
||||||
|
border-right: 7px solid transparent; |
||||||
|
content: ""; |
||||||
|
left: 6px; |
||||||
|
position: absolute; |
||||||
|
top: -7px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker.dropdown-menu:after { |
||||||
|
border-bottom: 6px solid #FFFFFF; |
||||||
|
border-left: 6px solid transparent; |
||||||
|
border-right: 6px solid transparent; |
||||||
|
content: ""; |
||||||
|
left: 7px; |
||||||
|
position: absolute; |
||||||
|
top: -6px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker.modal { |
||||||
|
margin-left: -100px; |
||||||
|
margin-top: 0; |
||||||
|
top: 30%; |
||||||
|
width: 200px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker.modal .modal-content { |
||||||
|
padding: 0; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table { |
||||||
|
margin: 0; |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td { |
||||||
|
height: 30px; |
||||||
|
margin: 0; |
||||||
|
padding: 2px; |
||||||
|
text-align: center; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td span { |
||||||
|
width: 100%; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td a { |
||||||
|
border: 1px solid transparent; |
||||||
|
display: inline-block; |
||||||
|
margin: 0; |
||||||
|
outline: 0 none; |
||||||
|
padding: 8px 0; |
||||||
|
width: 3em; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td a:hover { |
||||||
|
background-color: #EEEEEE; |
||||||
|
border-color: #DDDDDD; |
||||||
|
border-radius: 4px 4px 4px 4px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td a i { |
||||||
|
margin-top: 2px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker table td input { |
||||||
|
margin: 0; |
||||||
|
text-align: center; |
||||||
|
width: 25px; |
||||||
|
} |
||||||
|
.bootstrap-timepicker-component .add-on { |
||||||
|
cursor: pointer; |
||||||
|
} |
||||||
|
.bootstrap-timepicker-component .add-on i { |
||||||
|
display: block; |
||||||
|
height: 16px; |
||||||
|
width: 16px; |
||||||
|
} |
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,806 @@ |
|||||||
|
/* ========================================================= |
||||||
|
* bootstrap-timepicker.js |
||||||
|
* http://www.github.com/jdewit/bootstrap-timepicker
|
||||||
|
* ========================================================= |
||||||
|
* Copyright 2012 |
||||||
|
* |
||||||
|
* Created By: |
||||||
|
* Joris de Wit @joris_dewit |
||||||
|
* |
||||||
|
* Contributions By: |
||||||
|
* Gilbert @mindeavor |
||||||
|
* Koen Punt info@koenpunt.nl |
||||||
|
* Nek |
||||||
|
* Chris Martin |
||||||
|
* Dominic Barnes contact@dominicbarnes.us |
||||||
|
* Olivier Louvignes @olouv |
||||||
|
* |
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License"); |
||||||
|
* you may not use this file except in compliance with the License. |
||||||
|
* You may obtain a copy of the License at |
||||||
|
* |
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
* |
||||||
|
* Unless required by applicable law or agreed to in writing, software |
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS, |
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
||||||
|
* See the License for the specific language governing permissions and |
||||||
|
* limitations under the License. |
||||||
|
* ========================================================= */ |
||||||
|
|
||||||
|
!function($) { |
||||||
|
|
||||||
|
"use strict"; // jshint ;_;
|
||||||
|
|
||||||
|
var isTouch = 'ontouchstart' in window; |
||||||
|
|
||||||
|
/* TIMEPICKER PUBLIC CLASS DEFINITION |
||||||
|
* ================================== */ |
||||||
|
var Timepicker = function(element, options) { |
||||||
|
this.$element = $(element); |
||||||
|
this.options = $.extend({}, $.fn.timepicker.defaults, options, this.$element.data()); |
||||||
|
this.minuteStep = this.options.minuteStep || this.minuteStep; |
||||||
|
this.secondStep = this.options.secondStep || this.secondStep; |
||||||
|
this.showMeridian = this.options.showMeridian || this.showMeridian; |
||||||
|
this.showSeconds = this.options.showSeconds || this.showSeconds; |
||||||
|
this.showInputs = this.options.showInputs || this.showInputs; |
||||||
|
this.disableFocus = this.options.disableFocus || this.disableFocus; |
||||||
|
this.template = this.options.template || this.template; |
||||||
|
this.modalBackdrop = this.options.modalBackdrop || this.modalBackdrop; |
||||||
|
this.defaultTime = this.options.defaultTime || this.defaultTime; |
||||||
|
this.open = false; |
||||||
|
this.init(); |
||||||
|
}; |
||||||
|
|
||||||
|
Timepicker.prototype = { |
||||||
|
|
||||||
|
constructor: Timepicker |
||||||
|
|
||||||
|
, init: function () { |
||||||
|
if (this.$element.parent().hasClass('input-append')) { |
||||||
|
this.$element.parent('.input-append').find('.add-on').on('click', $.proxy(this.showWidget, this)); |
||||||
|
this.$element.on({ |
||||||
|
focus: $.proxy(this.highlightUnit, this), |
||||||
|
click: $.proxy(this.highlightUnit, this), |
||||||
|
keydown: $.proxy(this.elementKeydown, this), |
||||||
|
blur: $.proxy(this.blurElement, this) |
||||||
|
}); |
||||||
|
|
||||||
|
} else { |
||||||
|
if (this.template) { |
||||||
|
this.$element.on({ |
||||||
|
focus: $.proxy(this.showWidget, this), |
||||||
|
click: $.proxy(this.showWidget, this), |
||||||
|
blur: $.proxy(this.blurElement, this) |
||||||
|
}); |
||||||
|
} else { |
||||||
|
this.$element.on({ |
||||||
|
focus: $.proxy(this.highlightUnit, this), |
||||||
|
click: $.proxy(this.highlightUnit, this), |
||||||
|
keydown: $.proxy(this.elementKeydown, this), |
||||||
|
blur: $.proxy(this.blurElement, this) |
||||||
|
}); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
|
||||||
|
this.$widget = $(this.getTemplate()).appendTo('body'); |
||||||
|
|
||||||
|
this.$widget.on('click', $.proxy(this.widgetClick, this)); |
||||||
|
|
||||||
|
if (this.showInputs) { |
||||||
|
this.$widget.find('input').on({ |
||||||
|
click: function() { this.select(); }, |
||||||
|
keydown: $.proxy(this.widgetKeydown, this), |
||||||
|
change: $.proxy(this.updateFromWidgetInputs, this) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
this.setDefaultTime(this.defaultTime); |
||||||
|
} |
||||||
|
|
||||||
|
, showWidget: function(e) { |
||||||
|
e.stopPropagation(); |
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
if (this.open) { |
||||||
|
return; |
||||||
|
} |
||||||
|
|
||||||
|
this.$element.trigger('show'); |
||||||
|
|
||||||
|
if (isTouch || this.disableFocus) { |
||||||
|
this.$element.blur(); |
||||||
|
} |
||||||
|
|
||||||
|
var pos = $.extend({}, this.$element.offset(), { |
||||||
|
height: this.$element[0].offsetHeight |
||||||
|
}); |
||||||
|
|
||||||
|
this.updateFromElementVal(); |
||||||
|
|
||||||
|
$('html') |
||||||
|
.one(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', $.proxy(this.hideWidget, this)) |
||||||
|
.on(isTouch ? 'touchstart.timepicker.data-api' : 'click.timepicker.data-api', '.bootstrap-timepicker', function (e) { e.stopPropagation() }); |
||||||
|
|
||||||
|
if (this.template === 'modal') { |
||||||
|
this.$widget.modal('show').on('hidden', $.proxy(this.hideWidget, this)); |
||||||
|
} else { |
||||||
|
this.$widget.css({ |
||||||
|
top: pos.top + pos.height |
||||||
|
, left: pos.left |
||||||
|
}) |
||||||
|
|
||||||
|
if (!this.open) { |
||||||
|
this.$widget.addClass('open'); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
this.open = true; |
||||||
|
this.$element.trigger('shown'); |
||||||
|
} |
||||||
|
|
||||||
|
, hideWidget: function(){ |
||||||
|
this.$element.trigger('hide'); |
||||||
|
|
||||||
|
if (this.template === 'modal') { |
||||||
|
this.$widget.modal('hide'); |
||||||
|
} else { |
||||||
|
this.$widget.removeClass('open'); |
||||||
|
} |
||||||
|
this.open = false; |
||||||
|
this.$element.trigger('hidden'); |
||||||
|
} |
||||||
|
|
||||||
|
, widgetClick: function(e) { |
||||||
|
e.stopPropagation(); |
||||||
|
e.preventDefault(); |
||||||
|
|
||||||
|
var action = $(e.target).closest('a').data('action'); |
||||||
|
if (action) { |
||||||
|
this[action](); |
||||||
|
this.update(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, widgetKeydown: function(e) { |
||||||
|
var input = $(e.target).closest('input').attr('name'); |
||||||
|
|
||||||
|
switch (e.keyCode) { |
||||||
|
case 9: //tab
|
||||||
|
if (this.showMeridian) { |
||||||
|
if (input == 'meridian') { |
||||||
|
this.hideWidget(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (this.showSeconds) { |
||||||
|
if (input == 'second') { |
||||||
|
this.hideWidget(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (input == 'minute') { |
||||||
|
this.hideWidget(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case 27: // escape
|
||||||
|
this.hideWidget(); |
||||||
|
break; |
||||||
|
case 38: // up arrow
|
||||||
|
switch (input) { |
||||||
|
case 'hour': |
||||||
|
this.incrementHour(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.incrementMinute(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.incrementSecond(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.toggleMeridian(); |
||||||
|
break; |
||||||
|
} |
||||||
|
this.update(); |
||||||
|
break; |
||||||
|
case 40: // down arrow
|
||||||
|
switch (input) { |
||||||
|
case 'hour': |
||||||
|
this.decrementHour(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.decrementMinute(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.decrementSecond(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.toggleMeridian(); |
||||||
|
break; |
||||||
|
} |
||||||
|
this.update(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, elementKeydown: function(e) { |
||||||
|
var input = this.$element.get(0); |
||||||
|
switch (e.keyCode) { |
||||||
|
case 0: //input
|
||||||
|
break; |
||||||
|
case 9: //tab
|
||||||
|
this.updateFromElementVal(); |
||||||
|
if (this.showMeridian) { |
||||||
|
if (this.highlightedUnit != 'meridian') { |
||||||
|
e.preventDefault(); |
||||||
|
this.highlightNextUnit(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (this.showSeconds) { |
||||||
|
if (this.highlightedUnit != 'second') { |
||||||
|
e.preventDefault(); |
||||||
|
this.highlightNextUnit(); |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (this.highlightedUnit != 'minute') { |
||||||
|
e.preventDefault(); |
||||||
|
this.highlightNextUnit(); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
break; |
||||||
|
case 27: // escape
|
||||||
|
this.updateFromElementVal(); |
||||||
|
break; |
||||||
|
case 37: // left arrow
|
||||||
|
this.updateFromElementVal(); |
||||||
|
this.highlightPrevUnit(); |
||||||
|
break; |
||||||
|
case 38: // up arrow
|
||||||
|
switch (this.highlightedUnit) { |
||||||
|
case 'hour': |
||||||
|
this.incrementHour(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.incrementMinute(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.incrementSecond(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.toggleMeridian(); |
||||||
|
break; |
||||||
|
} |
||||||
|
this.updateElement(); |
||||||
|
break; |
||||||
|
case 39: // right arrow
|
||||||
|
this.updateFromElementVal(); |
||||||
|
this.highlightNextUnit(); |
||||||
|
break; |
||||||
|
case 40: // down arrow
|
||||||
|
switch (this.highlightedUnit) { |
||||||
|
case 'hour': |
||||||
|
this.decrementHour(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.decrementMinute(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.decrementSecond(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.toggleMeridian(); |
||||||
|
break; |
||||||
|
} |
||||||
|
this.updateElement(); |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
if (e.keyCode !== 0 && e.keyCode !== 8 && e.keyCode !== 9 && e.keyCode !== 46) { |
||||||
|
e.preventDefault(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, setValues: function(time) { |
||||||
|
if (this.showMeridian) { |
||||||
|
var arr = time.split(' '); |
||||||
|
var timeArray = arr[0].split(':'); |
||||||
|
this.meridian = arr[1]; |
||||||
|
} else { |
||||||
|
var timeArray = time.split(':'); |
||||||
|
} |
||||||
|
|
||||||
|
this.hour = parseInt(timeArray[0], 10); |
||||||
|
this.minute = parseInt(timeArray[1], 10); |
||||||
|
this.second = parseInt(timeArray[2], 10); |
||||||
|
|
||||||
|
if (isNaN(this.hour)) { |
||||||
|
this.hour = 0; |
||||||
|
} |
||||||
|
if (isNaN(this.minute)) { |
||||||
|
this.minute = 0; |
||||||
|
} |
||||||
|
|
||||||
|
if (this.showMeridian) { |
||||||
|
if (this.hour > 12) { |
||||||
|
this.hour = 12; |
||||||
|
} else if (this.hour < 1) { |
||||||
|
this.hour = 1; |
||||||
|
} |
||||||
|
|
||||||
|
if (this.meridian == 'am' || this.meridian == 'a') { |
||||||
|
this.meridian = 'AM'; |
||||||
|
} else if (this.meridian == 'pm' || this.meridian == 'p') { |
||||||
|
this.meridian = 'PM'; |
||||||
|
} |
||||||
|
|
||||||
|
if (this.meridian != 'AM' && this.meridian != 'PM') { |
||||||
|
this.meridian = 'AM'; |
||||||
|
} |
||||||
|
} else { |
||||||
|
if (this.hour >= 24) { |
||||||
|
this.hour = 23; |
||||||
|
} else if (this.hour < 0) { |
||||||
|
this.hour = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if (this.minute < 0) { |
||||||
|
this.minute = 0; |
||||||
|
} else if (this.minute >= 60) { |
||||||
|
this.minute = 59; |
||||||
|
} |
||||||
|
|
||||||
|
if (this.showSeconds) { |
||||||
|
if (isNaN(this.second)) { |
||||||
|
this.second = 0; |
||||||
|
} else if (this.second < 0) { |
||||||
|
this.second = 0; |
||||||
|
} else if (this.second >= 60) { |
||||||
|
this.second = 59; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
if ( this.$element.val() != '' ) |
||||||
|
this.updateElement(); |
||||||
|
this.updateWidget(); |
||||||
|
} |
||||||
|
|
||||||
|
, setMeridian: function(meridian) { |
||||||
|
if (meridian == 'a' || meridian == 'am' || meridian == 'AM' ) { |
||||||
|
this.meridian = 'AM'; |
||||||
|
} else if (meridian == 'p' || meridian == 'pm' || meridian == 'PM' ) { |
||||||
|
this.meridian = 'PM'; |
||||||
|
} else { |
||||||
|
this.updateWidget(); |
||||||
|
} |
||||||
|
|
||||||
|
this.updateElement(); |
||||||
|
} |
||||||
|
|
||||||
|
, setDefaultTime: function(defaultTime){ |
||||||
|
if (defaultTime) { |
||||||
|
if (defaultTime === 'current') { |
||||||
|
var dTime = new Date(); |
||||||
|
var hours = dTime.getHours(); |
||||||
|
var minutes = Math.floor(dTime.getMinutes() / this.minuteStep) * this.minuteStep; |
||||||
|
var seconds = Math.floor(dTime.getSeconds() / this.secondStep) * this.secondStep; |
||||||
|
var meridian = "AM"; |
||||||
|
if (this.showMeridian) { |
||||||
|
if (hours === 0) { |
||||||
|
hours = 12; |
||||||
|
} else if (hours >= 12) { |
||||||
|
if (hours > 12) { |
||||||
|
hours = hours - 12; |
||||||
|
} |
||||||
|
meridian = "PM"; |
||||||
|
} else { |
||||||
|
meridian = "AM"; |
||||||
|
} |
||||||
|
} |
||||||
|
this.hour = hours; |
||||||
|
this.minute = minutes; |
||||||
|
this.second = seconds; |
||||||
|
this.meridian = meridian; |
||||||
|
} else if (defaultTime === 'value') { |
||||||
|
this.setValues(this.$element.val()); |
||||||
|
} else { |
||||||
|
this.setValues(defaultTime); |
||||||
|
} |
||||||
|
if ( this.$element.val() != '' ) |
||||||
|
this.updateElement(); |
||||||
|
this.updateWidget(); |
||||||
|
} else { |
||||||
|
this.hour = 0; |
||||||
|
this.minute = 0; |
||||||
|
this.second = 0; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, formatTime: function(hour, minute, second, meridian) { |
||||||
|
hour = hour < 10 ? '0' + hour : hour; |
||||||
|
minute = minute < 10 ? '0' + minute : minute; |
||||||
|
second = second < 10 ? '0' + second : second; |
||||||
|
|
||||||
|
return hour + ':' + minute + (this.showSeconds ? ':' + second : '') + (this.showMeridian ? ' ' + meridian : ''); |
||||||
|
} |
||||||
|
|
||||||
|
, getTime: function() { |
||||||
|
return this.formatTime(this.hour, this.minute, this.second, this.meridian); |
||||||
|
} |
||||||
|
|
||||||
|
, setTime: function(time) { |
||||||
|
this.setValues(time); |
||||||
|
this.update(); |
||||||
|
} |
||||||
|
|
||||||
|
, update: function() { |
||||||
|
this.updateElement(); |
||||||
|
this.updateWidget(); |
||||||
|
} |
||||||
|
|
||||||
|
, blurElement: function() { |
||||||
|
this.highlightedUnit = undefined; |
||||||
|
this.updateFromElementVal(); |
||||||
|
} |
||||||
|
|
||||||
|
, updateElement: function() { |
||||||
|
var time = this.getTime(); |
||||||
|
|
||||||
|
this.$element.val(time).change(); |
||||||
|
|
||||||
|
switch (this.highlightedUnit) { |
||||||
|
case 'hour': |
||||||
|
this.highlightHour(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.highlightMinute(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.highlightSecond(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.highlightMeridian(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, updateWidget: function() { |
||||||
|
if (this.showInputs) { |
||||||
|
this.$widget.find('input.bootstrap-timepicker-hour').val(this.hour < 10 ? '0' + this.hour : this.hour); |
||||||
|
this.$widget.find('input.bootstrap-timepicker-minute').val(this.minute < 10 ? '0' + this.minute : this.minute); |
||||||
|
if (this.showSeconds) { |
||||||
|
this.$widget.find('input.bootstrap-timepicker-second').val(this.second < 10 ? '0' + this.second : this.second); |
||||||
|
} |
||||||
|
if (this.showMeridian) { |
||||||
|
this.$widget.find('input.bootstrap-timepicker-meridian').val(this.meridian); |
||||||
|
} |
||||||
|
} else { |
||||||
|
this.$widget.find('span.bootstrap-timepicker-hour').text(this.hour); |
||||||
|
this.$widget.find('span.bootstrap-timepicker-minute').text(this.minute < 10 ? '0' + this.minute : this.minute); |
||||||
|
if (this.showSeconds) { |
||||||
|
this.$widget.find('span.bootstrap-timepicker-second').text(this.second < 10 ? '0' + this.second : this.second); |
||||||
|
} |
||||||
|
if (this.showMeridian) { |
||||||
|
this.$widget.find('span.bootstrap-timepicker-meridian').text(this.meridian); |
||||||
|
} |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, updateFromElementVal: function (e) { |
||||||
|
var time = this.$element.val(); |
||||||
|
if (time) { |
||||||
|
this.setValues(time); |
||||||
|
this.updateWidget(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, updateFromWidgetInputs: function () { |
||||||
|
var time = $('input.bootstrap-timepicker-hour', this.$widget).val() + ':' + |
||||||
|
$('input.bootstrap-timepicker-minute', this.$widget).val() + |
||||||
|
(this.showSeconds ? |
||||||
|
':' + $('input.bootstrap-timepicker-second', this.$widget).val() |
||||||
|
: '') + |
||||||
|
(this.showMeridian ? |
||||||
|
' ' + $('input.bootstrap-timepicker-meridian', this.$widget).val() |
||||||
|
: ''); |
||||||
|
|
||||||
|
this.setValues(time); |
||||||
|
} |
||||||
|
|
||||||
|
, getCursorPosition: function() { |
||||||
|
var input = this.$element.get(0); |
||||||
|
|
||||||
|
if ('selectionStart' in input) { |
||||||
|
// Standard-compliant browsers
|
||||||
|
return input.selectionStart; |
||||||
|
} else if (document.selection) { |
||||||
|
// IE fix
|
||||||
|
input.focus(); |
||||||
|
var sel = document.selection.createRange(); |
||||||
|
var selLen = document.selection.createRange().text.length; |
||||||
|
sel.moveStart('character', - input.value.length); |
||||||
|
|
||||||
|
return sel.text.length - selLen; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, highlightUnit: function () { |
||||||
|
var input = this.$element.get(0); |
||||||
|
|
||||||
|
this.position = this.getCursorPosition(); |
||||||
|
if (this.position >= 0 && this.position <= 2) { |
||||||
|
this.highlightHour(); |
||||||
|
} else if (this.position >= 3 && this.position <= 5) { |
||||||
|
this.highlightMinute(); |
||||||
|
} else if (this.position >= 6 && this.position <= 8) { |
||||||
|
if (this.showSeconds) { |
||||||
|
this.highlightSecond(); |
||||||
|
} else { |
||||||
|
this.highlightMeridian(); |
||||||
|
} |
||||||
|
} else if (this.position >= 9 && this.position <= 11) { |
||||||
|
this.highlightMeridian(); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, highlightNextUnit: function() { |
||||||
|
switch (this.highlightedUnit) { |
||||||
|
case 'hour': |
||||||
|
this.highlightMinute(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
if (this.showSeconds) { |
||||||
|
this.highlightSecond(); |
||||||
|
} else { |
||||||
|
this.highlightMeridian(); |
||||||
|
} |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.highlightMeridian(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
this.highlightHour(); |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, highlightPrevUnit: function() { |
||||||
|
switch (this.highlightedUnit) { |
||||||
|
case 'hour': |
||||||
|
this.highlightMeridian(); |
||||||
|
break; |
||||||
|
case 'minute': |
||||||
|
this.highlightHour(); |
||||||
|
break; |
||||||
|
case 'second': |
||||||
|
this.highlightMinute(); |
||||||
|
break; |
||||||
|
case 'meridian': |
||||||
|
if (this.showSeconds) { |
||||||
|
this.highlightSecond(); |
||||||
|
} else { |
||||||
|
this.highlightMinute(); |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, highlightHour: function() { |
||||||
|
this.highlightedUnit = 'hour'; |
||||||
|
this.$element.get(0).setSelectionRange(0,2); |
||||||
|
} |
||||||
|
|
||||||
|
, highlightMinute: function() { |
||||||
|
this.highlightedUnit = 'minute'; |
||||||
|
this.$element.get(0).setSelectionRange(3,5); |
||||||
|
} |
||||||
|
|
||||||
|
, highlightSecond: function() { |
||||||
|
this.highlightedUnit = 'second'; |
||||||
|
this.$element.get(0).setSelectionRange(6,8); |
||||||
|
} |
||||||
|
|
||||||
|
, highlightMeridian: function() { |
||||||
|
this.highlightedUnit = 'meridian'; |
||||||
|
if (this.showSeconds) { |
||||||
|
this.$element.get(0).setSelectionRange(9,11); |
||||||
|
} else { |
||||||
|
this.$element.get(0).setSelectionRange(6,8); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, incrementHour: function() { |
||||||
|
if (this.showMeridian) { |
||||||
|
if (this.hour === 11) { |
||||||
|
this.toggleMeridian(); |
||||||
|
} else if (this.hour === 12) { |
||||||
|
return this.hour = 1; |
||||||
|
} |
||||||
|
} |
||||||
|
if (this.hour === 23) { |
||||||
|
return this.hour = 0; |
||||||
|
} |
||||||
|
this.hour = this.hour + 1; |
||||||
|
} |
||||||
|
|
||||||
|
, decrementHour: function() { |
||||||
|
if (this.showMeridian) { |
||||||
|
if (this.hour === 1) { |
||||||
|
return this.hour = 12; |
||||||
|
} |
||||||
|
else if (this.hour === 12) { |
||||||
|
this.toggleMeridian(); |
||||||
|
} |
||||||
|
} |
||||||
|
if (this.hour === 0) { |
||||||
|
return this.hour = 23; |
||||||
|
} |
||||||
|
this.hour = this.hour - 1; |
||||||
|
} |
||||||
|
|
||||||
|
, incrementMinute: function() { |
||||||
|
var newVal = this.minute + this.minuteStep - (this.minute % this.minuteStep); |
||||||
|
if (newVal > 59) { |
||||||
|
this.incrementHour(); |
||||||
|
this.minute = newVal - 60; |
||||||
|
} else { |
||||||
|
this.minute = newVal; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, decrementMinute: function() { |
||||||
|
var newVal = this.minute - this.minuteStep; |
||||||
|
if (newVal < 0) { |
||||||
|
this.decrementHour(); |
||||||
|
this.minute = newVal + 60; |
||||||
|
} else { |
||||||
|
this.minute = newVal; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, incrementSecond: function() { |
||||||
|
var newVal = this.second + this.secondStep - (this.second % this.secondStep); |
||||||
|
if (newVal > 59) { |
||||||
|
this.incrementMinute(); |
||||||
|
this.second = newVal - 60; |
||||||
|
} else { |
||||||
|
this.second = newVal; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, decrementSecond: function() { |
||||||
|
var newVal = this.second - this.secondStep; |
||||||
|
if (newVal < 0) { |
||||||
|
this.decrementMinute(); |
||||||
|
this.second = newVal + 60; |
||||||
|
} else { |
||||||
|
this.second = newVal; |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
, toggleMeridian: function() { |
||||||
|
this.meridian = this.meridian === 'AM' ? 'PM' : 'AM'; |
||||||
|
|
||||||
|
this.update(); |
||||||
|
} |
||||||
|
|
||||||
|
, getTemplate: function() { |
||||||
|
if (this.options.templates[this.options.template]) { |
||||||
|
return this.options.templates[this.options.template]; |
||||||
|
} |
||||||
|
if (this.showInputs) { |
||||||
|
var hourTemplate = '<input type="text" name="hour" class="bootstrap-timepicker-hour" maxlength="2"/>'; |
||||||
|
var minuteTemplate = '<input type="text" name="minute" class="bootstrap-timepicker-minute" maxlength="2"/>'; |
||||||
|
var secondTemplate = '<input type="text" name="second" class="bootstrap-timepicker-second" maxlength="2"/>'; |
||||||
|
var meridianTemplate = '<input type="text" name="meridian" class="bootstrap-timepicker-meridian" maxlength="2"/>'; |
||||||
|
} else { |
||||||
|
var hourTemplate = '<span class="bootstrap-timepicker-hour"></span>'; |
||||||
|
var minuteTemplate = '<span class="bootstrap-timepicker-minute"></span>'; |
||||||
|
var secondTemplate = '<span class="bootstrap-timepicker-second"></span>'; |
||||||
|
var meridianTemplate = '<span class="bootstrap-timepicker-meridian"></span>'; |
||||||
|
} |
||||||
|
var templateContent = '<table class="'+ (this.showSeconds ? 'show-seconds' : '') +' '+ (this.showMeridian ? 'show-meridian' : '') +'">'+ |
||||||
|
'<tr>'+ |
||||||
|
'<td><a href="#" data-action="incrementHour"><i class="icon-chevron-up"></i></a></td>'+ |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td><a href="#" data-action="incrementMinute"><i class="icon-chevron-up"></i></a></td>'+ |
||||||
|
(this.showSeconds ? |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td><a href="#" data-action="incrementSecond"><i class="icon-chevron-up"></i></a></td>' |
||||||
|
: '') + |
||||||
|
(this.showMeridian ? |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td class="meridian-column"><a href="#" data-action="toggleMeridian"><i class="icon-chevron-up"></i></a></td>' |
||||||
|
: '') + |
||||||
|
'</tr>'+ |
||||||
|
'<tr>'+ |
||||||
|
'<td>'+ hourTemplate +'</td> '+ |
||||||
|
'<td class="separator">:</td>'+ |
||||||
|
'<td>'+ minuteTemplate +'</td> '+ |
||||||
|
(this.showSeconds ? |
||||||
|
'<td class="separator">:</td>'+ |
||||||
|
'<td>'+ secondTemplate +'</td>' |
||||||
|
: '') + |
||||||
|
(this.showMeridian ? |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td>'+ meridianTemplate +'</td>' |
||||||
|
: '') + |
||||||
|
'</tr>'+ |
||||||
|
'<tr>'+ |
||||||
|
'<td><a href="#" data-action="decrementHour"><i class="icon-chevron-down"></i></a></td>'+ |
||||||
|
'<td class="separator"></td>'+ |
||||||
|
'<td><a href="#" data-action="decrementMinute"><i class="icon-chevron-down"></i></a></td>'+ |
||||||
|
(this.showSeconds ? |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td><a href="#" data-action="decrementSecond"><i class="icon-chevron-down"></i></a></td>' |
||||||
|
: '') + |
||||||
|
(this.showMeridian ? |
||||||
|
'<td class="separator"> </td>'+ |
||||||
|
'<td><a href="#" data-action="toggleMeridian"><i class="icon-chevron-down"></i></a></td>' |
||||||
|
: '') + |
||||||
|
'</tr>'+ |
||||||
|
'</table>'; |
||||||
|
|
||||||
|
var template; |
||||||
|
switch(this.options.template) { |
||||||
|
case 'modal': |
||||||
|
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') +'">'+ |
||||||
|
'<div class="modal-header">'+ |
||||||
|
'<a href="#" class="close" data-dismiss="modal">×</a>'+ |
||||||
|
'<h3>Pick a Time</h3>'+ |
||||||
|
'</div>'+ |
||||||
|
'<div class="modal-content">'+ |
||||||
|
templateContent + |
||||||
|
'</div>'+ |
||||||
|
'<div class="modal-footer">'+ |
||||||
|
'<a href="#" class="btn btn-primary" data-dismiss="modal">Ok</a>'+ |
||||||
|
'</div>'+ |
||||||
|
'</div>'; |
||||||
|
|
||||||
|
break; |
||||||
|
case 'dropdown': |
||||||
|
template = '<div class="bootstrap-timepicker dropdown-menu">'+ |
||||||
|
templateContent + |
||||||
|
'</div>'; |
||||||
|
break; |
||||||
|
|
||||||
|
} |
||||||
|
return template; |
||||||
|
} |
||||||
|
}; |
||||||
|
|
||||||
|
|
||||||
|
/* TIMEPICKER PLUGIN DEFINITION |
||||||
|
* =========================== */ |
||||||
|
|
||||||
|
$.fn.timepicker = function (option) { |
||||||
|
return this.each(function () { |
||||||
|
var $this = $(this) |
||||||
|
, data = $this.data('timepicker') |
||||||
|
, options = typeof option == 'object' && option; |
||||||
|
if (!data) { |
||||||
|
$this.data('timepicker', (data = new Timepicker(this, options))); |
||||||
|
} |
||||||
|
if (typeof option == 'string') { |
||||||
|
data[option](); |
||||||
|
} |
||||||
|
}) |
||||||
|
} |
||||||
|
|
||||||
|
$.fn.timepicker.defaults = { |
||||||
|
minuteStep: 15 |
||||||
|
, secondStep: 15 |
||||||
|
, disableFocus: false |
||||||
|
, defaultTime: 'current' |
||||||
|
, showSeconds: false |
||||||
|
, showInputs: true |
||||||
|
, showMeridian: true |
||||||
|
, template: 'dropdown' |
||||||
|
, modalBackdrop: false |
||||||
|
, templates: {} // set custom templates
|
||||||
|
} |
||||||
|
|
||||||
|
$.fn.timepicker.Constructor = Timepicker |
||||||
|
}(window.jQuery); |
@ -1,5 +1,6 @@ |
|||||||
<div ng-controller='sort' style="white-space: nowrap;"> |
<div ng-controller='sort' style="white-space: nowrap;"> |
||||||
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> |
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> |
||||||
|
<label><small>{{panel.label}}</small></label> |
||||||
|
<select style="width:85%" ng-model="panel.sort[0]" ng-options="f for f in fields"></select> |
||||||
<i ng-click="toggle_sort()" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i> |
<i ng-click="toggle_sort()" ng-class="{'icon-chevron-up': panel.sort[1] == 'asc','icon-chevron-down': panel.sort[1] == 'desc'}"></i> |
||||||
<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select> |
|
||||||
</div> |
</div> |
@ -1,7 +1,8 @@ |
|||||||
<div ng-controller='stringquery'> |
<div ng-controller='stringquery'> |
||||||
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> |
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> |
||||||
<form class="form-search" style="margin-bottom:0px"> |
<form class="input-append" style="margin-bottom:0px; white-space:nowrap;"> |
||||||
<input type="text" class="input-medium search-query" ng-model="query" style="width:85%"> |
<label><small>{{panel.label}}</small></label> |
||||||
<button type="submit" class="btn" ng-click="send_query(query)">Search</button> |
<input type="text" ng-model="panel.query" style="width:90%"> |
||||||
|
<button type="submit" class="btn" ng-click="send_query(panel.query)"><i class="icon-search"></i></button> |
||||||
</form> |
</form> |
||||||
</div> |
</div> |
@ -0,0 +1,64 @@ |
|||||||
|
<div ng-controller='timepicker' style="white-space: nowrap;"> |
||||||
|
<h4 ng-class="{'ng-cloak': !panel.title}">{{panel.title}}</h4> |
||||||
|
<div class="row-fluid" ng-switch="panel.mode"> |
||||||
|
<div ng-switch-when="absolute"> |
||||||
|
<div class="span5"> |
||||||
|
<form class="nomargin"> |
||||||
|
<label><small>From</small></label> |
||||||
|
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker> |
||||||
|
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="span5" style="margin-left:10px"> |
||||||
|
<form class="nomargin"> |
||||||
|
<label style="margin-left:5px"><small>To (<a ng-click="to_now()">now</a>)</small></label> |
||||||
|
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.to.date" data-date-format="mm/dd/yyyy" bs-datepicker> |
||||||
|
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.to.time" bs-timepicker> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="span1"> |
||||||
|
<form class="nomargin"> |
||||||
|
<label><small><br></small></label> |
||||||
|
<button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div ng-switch-when="since"> |
||||||
|
<div class="span5"> |
||||||
|
<form class="nomargin"> |
||||||
|
<label><small>Since</small></label> |
||||||
|
<input type="text" class="input-smaller" ng-change="time_check()" ng-model="timepicker.from.date" data-date-format="mm/dd/yyyy" bs-datepicker> |
||||||
|
<input type="text" class="input-mini" ng-change="time_check()" data-show-meridian="false" data-show-seconds="true" ng-model="timepicker.from.time" bs-timepicker> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
<div class="span1" style="margin-left:10px"> |
||||||
|
<form class="nomargin"> |
||||||
|
<label><small><br></small></label> |
||||||
|
<button class="btn" ng-click="time_apply()" ><i class="icon-check"></i></button> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div ng-switch-when="relative"> |
||||||
|
<div class="span11"> |
||||||
|
<form class="nomargin input-append"> |
||||||
|
<label><small>The last</small></label> |
||||||
|
<button class="btn btn" ng-repeat='timespan in panel.time_options' ng-class="{'btn-success': (panel.timespan == timespan)}" ng-click="set_timespan(timespan)">{{timespan}}</button> |
||||||
|
<!--<select ng-model="panel.sort[0]" ng-options="f for f in fields"></select>--> |
||||||
|
</form> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
<div class="row-fluid nomargin"> |
||||||
|
<div class="span12 small"> |
||||||
|
<a ng-click="set_mode('relative')" ng-class="{'strong': (panel.mode == 'relative')}">Relative</a> | |
||||||
|
<a ng-click="set_mode('absolute')" ng-class="{'strong': (panel.mode == 'absolute')}">Absolute</a> | |
||||||
|
<a ng-click="set_mode('since')" ng-class="{'strong': (panel.mode == 'since')}">Since</a> |
||||||
|
<span ng-hide="panel.mode == 'absolute'"> | |
||||||
|
<input type="checkbox" ng-model="panel.refresh.enable"> Auto-refresh |
||||||
|
<span ng-class="{'ng-cloak': !panel.refresh.enable}"> |
||||||
|
every <a data-title="<small>Auto-refresh Settings</small>" data-placement="bottom" bs-popover="'panels/timepicker/refreshctrl.html'">{{panel.refresh.interval}}s</a>. |
||||||
|
</span> |
||||||
|
</span> |
||||||
|
</div> |
||||||
|
</div> |
||||||
|
</div> |
@ -0,0 +1,168 @@ |
|||||||
|
angular.module('kibana.timepicker', []) |
||||||
|
.controller('timepicker', function($scope, $rootScope, $timeout) { |
||||||
|
|
||||||
|
// Set and populate defaults
|
||||||
|
var _d = { |
||||||
|
mode : "relative", |
||||||
|
time_options : ['5m','15m','1h','6h','12h','24h','2d','7d','30d'], |
||||||
|
timespan : '15m', |
||||||
|
refresh : { |
||||||
|
enable: false,
|
||||||
|
interval: 3, |
||||||
|
min: 3 |
||||||
|
}, |
||||||
|
time : { |
||||||
|
from : $scope.time.from, |
||||||
|
to : $scope.time.to |
||||||
|
} |
||||||
|
} |
||||||
|
_.each(_d, function(v, k) { |
||||||
|
$scope.panel[k] = _.isUndefined($scope.panel[k])
|
||||||
|
? _d[k] : $scope.panel[k]; |
||||||
|
}); |
||||||
|
|
||||||
|
// Private refresh interval that we can use for view display without causing
|
||||||
|
// unnecessary refreshes during changes
|
||||||
|
$scope.refresh_interval = $scope.panel.refresh.interval |
||||||
|
|
||||||
|
// Init a private time object with Date() objects depending on mode
|
||||||
|
switch($scope.panel.mode) { |
||||||
|
case 'absolute': |
||||||
|
$scope.time = { |
||||||
|
from : Date.parse($scope.panel.time.from), |
||||||
|
to : Date.parse($scope.panel.time.to) |
||||||
|
} |
||||||
|
break; |
||||||
|
case 'since': |
||||||
|
$scope.time = { |
||||||
|
from : Date.parse($scope.panel.time.from), |
||||||
|
to : new Date() |
||||||
|
} |
||||||
|
break; |
||||||
|
case 'relative': |
||||||
|
$scope.time = { |
||||||
|
from : time_ago($scope.panel.timespan), |
||||||
|
to : new Date() |
||||||
|
} |
||||||
|
break; |
||||||
|
} |
||||||
|
|
||||||
|
// Init the values for the time/date pickers
|
||||||
|
$scope.timepicker = { |
||||||
|
from : { |
||||||
|
time : $scope.time.from.format("HH:MM:ss"), |
||||||
|
date : $scope.time.from.format("mm/dd/yyyy") |
||||||
|
}, |
||||||
|
to : { |
||||||
|
time : $scope.time.to.format("HH:MM:ss"), |
||||||
|
date : $scope.time.to.format("mm/dd/yyyy") |
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// In the case that a panel is not ready to receive a time event, it may
|
||||||
|
// request one be sent by broadcasting a 'get_time' even to its group
|
||||||
|
if (!(_.isUndefined($scope.panel.group))) { |
||||||
|
// Broadcast time when initializing
|
||||||
|
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time) |
||||||
|
|
||||||
|
// And whenever it is requested
|
||||||
|
$scope.$on($scope.panel.group+"-get_time", function(event) { |
||||||
|
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time) |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.$watch('panel.refresh.enable', function() {$scope.refresh()}); |
||||||
|
$scope.$watch('panel.refresh.interval', function() { |
||||||
|
$timeout(function(){ |
||||||
|
if(_.isNumber($scope.panel.refresh.interval)) { |
||||||
|
if($scope.panel.refresh.interval < $scope.panel.refresh.min) { |
||||||
|
$scope.panel.refresh.interval = $scope.panel.refresh.min
|
||||||
|
$timeout.cancel($scope.panel.refresh.timer) |
||||||
|
return; |
||||||
|
} |
||||||
|
$timeout.cancel($scope.panel.refresh.timer) |
||||||
|
$scope.refresh() |
||||||
|
} else { |
||||||
|
$timeout.cancel($scope.panel.refresh.timer) |
||||||
|
} |
||||||
|
}); |
||||||
|
}); |
||||||
|
|
||||||
|
|
||||||
|
$scope.refresh = function() { |
||||||
|
if ($scope.panel.refresh.enable) { |
||||||
|
$scope.time_apply(); |
||||||
|
$scope.panel.refresh.timer = $timeout( |
||||||
|
$scope.refresh, |
||||||
|
$scope.panel.refresh.interval*1000 |
||||||
|
); |
||||||
|
} else { |
||||||
|
$timeout.cancel($scope.panel.refresh.timer) |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$scope.set_mode = function(mode) { |
||||||
|
$scope.panel.mode = mode; |
||||||
|
$scope.panel.refresh.enable = mode === 'absolute' ?
|
||||||
|
false : $scope.panel.refresh.enable |
||||||
|
} |
||||||
|
|
||||||
|
$scope.to_now = function() { |
||||||
|
$scope.timepicker.to = { |
||||||
|
time : new Date().format("HH:MM:ss"), |
||||||
|
date : new Date().format("mm/dd/yyyy") |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
$scope.set_timespan = function(timespan) { |
||||||
|
$scope.panel.timespan = timespan; |
||||||
|
$scope.timepicker.from = { |
||||||
|
time : time_ago(timespan).format("HH:MM:ss"), |
||||||
|
date : time_ago(timespan).format("mm/dd/yyyy") |
||||||
|
} |
||||||
|
$scope.time_apply(); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.time_check = function(){ |
||||||
|
var from = $scope.panel.mode === 'relative' ? time_ago($scope.panel.timespan) : |
||||||
|
Date.parse($scope.timepicker.from.date + " " + $scope.timepicker.from.time) |
||||||
|
var to = $scope.panel.mode !== 'absolute' ? new Date() : |
||||||
|
Date.parse($scope.timepicker.to.date + " " + $scope.timepicker.to.time) |
||||||
|
|
||||||
|
if (from.getTime() >= to.getTime()) |
||||||
|
from = new Date(to.getTime() - 1000) |
||||||
|
|
||||||
|
// Janky 0s timeout to get around $scope queue processing view issue
|
||||||
|
$timeout(function(){ |
||||||
|
$scope.timepicker = { |
||||||
|
from : { |
||||||
|
time : from.format("HH:MM:ss"), |
||||||
|
date : from.format("mm/dd/yyyy") |
||||||
|
}, |
||||||
|
to : { |
||||||
|
time : to.format("HH:MM:ss"), |
||||||
|
date : to.format("mm/dd/yyyy") |
||||||
|
}
|
||||||
|
} |
||||||
|
}); |
||||||
|
} |
||||||
|
|
||||||
|
$scope.time_apply = function() {
|
||||||
|
$scope.time_check(); |
||||||
|
// Update internal time object
|
||||||
|
$scope.time = {
|
||||||
|
from : Date.parse($scope.timepicker.from.date + " " + $scope.timepicker.from.time),
|
||||||
|
to : Date.parse($scope.timepicker.to.date + " " + $scope.timepicker.to.time) |
||||||
|
}; |
||||||
|
|
||||||
|
// Broadcast time
|
||||||
|
$rootScope.$broadcast($scope.panel.group+"-time", $scope.time) |
||||||
|
|
||||||
|
// Update panel's string representation of the time object
|
||||||
|
$scope.panel.time = {
|
||||||
|
from : $scope.time.from.format("mm/dd/yyyy HH:MM:ss"), |
||||||
|
to : $scope.time.to.format("mm/dd/yyyy HH:MM:ss")
|
||||||
|
}; |
||||||
|
}; |
||||||
|
|
||||||
|
}) |
@ -0,0 +1,5 @@ |
|||||||
|
<form name="refreshPopover" class='form-inline' style="margin:0px"> |
||||||
|
<label><small>Interval (seconds)</small></label> |
||||||
|
<input type="number" class="input-mini" ng-model="refresh_interval"> |
||||||
|
<button type="button" class="btn" ng-click="panel.refresh.interval=refresh_interval;dismiss()"><i class="icon-check"></i></button> |
||||||
|
</form> |
Loading…
Reference in new issue