diff --git a/common/css/timepicker.css b/common/css/timepicker.css index 8166d4da0e9..7cac8b02dcb 100644 --- a/common/css/timepicker.css +++ b/common/css/timepicker.css @@ -1,91 +1,423 @@ -/* - 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; } +/*! + * Datepicker for Bootstrap + * + * Copyright 2012 Stefan Petre + * Improvements by Andrew Rowls + * Licensed under the Apache License v2.0 + * http://www.apache.org/licenses/LICENSE-2.0 + * + */ +.datepicker { + padding: 4px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + direction: ltr; + /*.dow { + border-top: 1px solid #ddd !important; + }*/ -.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; +.datepicker-inline { + width: 220px; } -.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; +.datepicker.datepicker-rtl { + direction: rtl; } -.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; +.datepicker.datepicker-rtl table tr td span { + float: right; } -.bootstrap-timepicker.modal { - margin-left: -100px; - margin-top: 0; - top: 30%; +.datepicker-dropdown { + top: 0; + left: 0; +} +.datepicker-dropdown: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-dropdown: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.days div.datepicker-days { + display: block; +} +.datepicker.months div.datepicker-months { + display: block; +} +.datepicker.years div.datepicker-years { + display: block; +} +.datepicker table { + margin: 0; +} +.datepicker td, +.datepicker th { + text-align: center; + width: 20px; + height: 20px; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border: none; +} +.table-striped .datepicker table tr td, +.table-striped .datepicker table tr th { + background-color: transparent; +} +.datepicker table tr td.day:hover { + background: #eeeeee; + cursor: pointer; +} +.datepicker table tr td.old, +.datepicker table tr td.new { + color: #999999; +} +.datepicker table tr td.disabled, +.datepicker table tr td.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td.today, +.datepicker table tr td.today:hover, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today.disabled:hover { + background-color: #fde19a; + background-image: -moz-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -ms-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -webkit-gradient(linear, 0 0, 0 100%, from(#fdd49a), to(#fdf59a)); + background-image: -webkit-linear-gradient(top, #fdd49a, #fdf59a); + background-image: -o-linear-gradient(top, #fdd49a, #fdf59a); + background-image: linear-gradient(top, #fdd49a, #fdf59a); + background-repeat: repeat-x; + filter: progid:DXImageTransform.Microsoft.gradient(startColorstr='#fdd49a', endColorstr='#fdf59a', GradientType=0); + border-color: #fdf59a #fdf59a #fbed50; + 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: #000 !important; +} +.datepicker table tr td.today:hover, +.datepicker table tr td.today:hover:hover, +.datepicker table tr td.today.disabled:hover, +.datepicker table tr td.today.disabled:hover:hover, +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active, +.datepicker table tr td.today.disabled, +.datepicker table tr td.today:hover.disabled, +.datepicker table tr td.today.disabled.disabled, +.datepicker table tr td.today.disabled:hover.disabled, +.datepicker table tr td.today[disabled], +.datepicker table tr td.today:hover[disabled], +.datepicker table tr td.today.disabled[disabled], +.datepicker table tr td.today.disabled:hover[disabled] { + background-color: #fdf59a; +} +.datepicker table tr td.today:active, +.datepicker table tr td.today:hover:active, +.datepicker table tr td.today.disabled:active, +.datepicker table tr td.today.disabled:hover:active, +.datepicker table tr td.today.active, +.datepicker table tr td.today:hover.active, +.datepicker table tr td.today.disabled.active, +.datepicker table tr td.today.disabled:hover.active { + background-color: #fbf069 \9; +} +.datepicker table tr td.active, +.datepicker table tr td.active:hover, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active.disabled: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 table tr td.active:hover, +.datepicker table tr td.active:hover:hover, +.datepicker table tr td.active.disabled:hover, +.datepicker table tr td.active.disabled:hover:hover, +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active, +.datepicker table tr td.active.disabled, +.datepicker table tr td.active:hover.disabled, +.datepicker table tr td.active.disabled.disabled, +.datepicker table tr td.active.disabled:hover.disabled, +.datepicker table tr td.active[disabled], +.datepicker table tr td.active:hover[disabled], +.datepicker table tr td.active.disabled[disabled], +.datepicker table tr td.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td.active:active, +.datepicker table tr td.active:hover:active, +.datepicker table tr td.active.disabled:active, +.datepicker table tr td.active.disabled:hover:active, +.datepicker table tr td.active.active, +.datepicker table tr td.active:hover.active, +.datepicker table tr td.active.disabled.active, +.datepicker table tr td.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span { + display: block; + width: 23%; + height: 54px; + line-height: 54px; + float: left; + margin: 1%; + cursor: pointer; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; +} +.datepicker table tr td span:hover { + background: #eeeeee; +} +.datepicker table tr td span.disabled, +.datepicker table tr td span.disabled:hover { + background: none; + color: #999999; + cursor: default; +} +.datepicker table tr td span.active, +.datepicker table tr td span.active:hover, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active.disabled: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 table tr td span.active:hover, +.datepicker table tr td span.active:hover:hover, +.datepicker table tr td span.active.disabled:hover, +.datepicker table tr td span.active.disabled:hover:hover, +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active, +.datepicker table tr td span.active.disabled, +.datepicker table tr td span.active:hover.disabled, +.datepicker table tr td span.active.disabled.disabled, +.datepicker table tr td span.active.disabled:hover.disabled, +.datepicker table tr td span.active[disabled], +.datepicker table tr td span.active:hover[disabled], +.datepicker table tr td span.active.disabled[disabled], +.datepicker table tr td span.active.disabled:hover[disabled] { + background-color: #0044cc; +} +.datepicker table tr td span.active:active, +.datepicker table tr td span.active:hover:active, +.datepicker table tr td span.active.disabled:active, +.datepicker table tr td span.active.disabled:hover:active, +.datepicker table tr td span.active.active, +.datepicker table tr td span.active:hover.active, +.datepicker table tr td span.active.disabled.active, +.datepicker table tr td span.active.disabled:hover.active { + background-color: #003399 \9; +} +.datepicker table tr td span.old { + color: #999999; +} +.datepicker th.switch { + width: 145px; +} +.datepicker thead tr:first-child th, +.datepicker tfoot tr:first-child th { + cursor: pointer; +} +.datepicker thead tr:first-child th:hover, +.datepicker tfoot tr:first-child th:hover { + background: #eeeeee; +} +.datepicker .cw { + font-size: 10px; + width: 12px; + padding: 0 2px 0 5px; + vertical-align: middle; +} +.datepicker thead tr:first-child th.cw { + cursor: default; + background-color: transparent; +} +.input-append.date .add-on i, +.input-prepend.date .add-on i { + display: block; + cursor: pointer; + width: 16px; + height: 16px; +} +/*! + * Timepicker Component for Twitter Bootstrap + * + * Copyright 2013 Joris de Wit + * + * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors + * + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +.bootstrap-timepicker { + position: relative; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu { + left: auto; + right: 0; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:before { + left: auto; + right: 12px; +} +.bootstrap-timepicker.pull-right .bootstrap-timepicker-widget.dropdown-menu:after { + left: auto; + right: 13px; +} +.bootstrap-timepicker .add-on { + cursor: pointer; +} +.bootstrap-timepicker .add-on i { + display: inline-block; + width: 16px; + height: 16px; +} +.bootstrap-timepicker-widget.dropdown-menu { + padding: 2px 3px 2px 2px; +} +.bootstrap-timepicker-widget.dropdown-menu.open { + display: inline-block; +} +.bootstrap-timepicker-widget.dropdown-menu:before { + border-bottom: 7px solid rgba(0, 0, 0, 0.2); + border-left: 7px solid transparent; + border-right: 7px solid transparent; + content: ""; + display: inline-block; + left: 9px; + position: absolute; + top: -7px; +} +.bootstrap-timepicker-widget.dropdown-menu:after { + border-bottom: 6px solid #FFFFFF; + border-left: 6px solid transparent; + border-right: 6px solid transparent; + content: ""; + display: inline-block; + left: 10px; + position: absolute; + top: -6px; +} +.bootstrap-timepicker-widget a.btn, +.bootstrap-timepicker-widget input { + border-radius: 4px; +} +.bootstrap-timepicker-widget table { + width: 100%; + margin: 0; +} +.bootstrap-timepicker-widget table td { + text-align: center; + height: 30px; + margin: 0; + padding: 2px; +} +.bootstrap-timepicker-widget table td:not(.separator) { + min-width: 30px; +} +.bootstrap-timepicker-widget table td span { + width: 100%; +} +.bootstrap-timepicker-widget table td a { + border: 1px transparent solid; + width: 100%; + display: inline-block; + margin: 0; + padding: 8px 0; + outline: 0; + color: #333; +} +.bootstrap-timepicker-widget table td a:hover { + text-decoration: none; + background-color: #eee; + -webkit-border-radius: 4px; + -moz-border-radius: 4px; + border-radius: 4px; + border-color: #ddd; +} +.bootstrap-timepicker-widget table td a i { + margin-top: 2px; +} +.bootstrap-timepicker-widget table td input { + width: 25px; + margin: 0; + text-align: center; +} +.bootstrap-timepicker-widget .modal-content { + padding: 4px; +} +@media (min-width: 767px) { + .bootstrap-timepicker-widget.modal { width: 200px; + margin-left: -100px; + } } -.bootstrap-timepicker.modal .modal-content { - padding: 0; -} -.bootstrap-timepicker table { - margin: 0; +@media (max-width: 767px) { + .bootstrap-timepicker { width: 100%; -} -.bootstrap-timepicker table td { - height: 30px; - margin: 0; - padding: 2px; - text-align: center; -} -.bootstrap-timepicker table td span { + } + .bootstrap-timepicker .dropdown-menu { 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; -} + } +} \ No newline at end of file diff --git a/common/lib/timepicker.js b/common/lib/timepicker.js index 9cce032c003..e0d9f51b33a 100644 --- a/common/lib/timepicker.js +++ b/common/lib/timepicker.js @@ -1,806 +1,888 @@ -/* ========================================================= - * bootstrap-timepicker.js - * http://www.github.com/jdewit/bootstrap-timepicker - * ========================================================= - * Copyright 2012 +/*! + * Timepicker Component for Twitter Bootstrap * - * Created By: - * Joris de Wit @joris_dewit + * Copyright 2013 Joris de Wit * - * Contributions By: - * Gilbert @mindeavor - * Koen Punt info@koenpunt.nl - * Nek - * Chris Martin - * Dominic Barnes contact@dominicbarnes.us - * Olivier Louvignes @olouv + * Contributors https://github.com/jdewit/bootstrap-timepicker/graphs/contributors * - * 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. - * ========================================================= */ + * For the full copyright and license information, please view the LICENSE + * file that was distributed with this source code. + */ +(function($, window, document, undefined) { + 'use strict'; -!function($) { + // TIMEPICKER PUBLIC CLASS DEFINITION + var Timepicker = function(element, options) { + this.widget = ''; + this.$element = $(element); + this.defaultTime = options.defaultTime; + this.disableFocus = options.disableFocus; + this.isOpen = options.isOpen; + this.minuteStep = options.minuteStep; + this.modalBackdrop = options.modalBackdrop; + this.secondStep = options.secondStep; + this.showInputs = options.showInputs; + this.showMeridian = options.showMeridian; + this.showSeconds = options.showSeconds; + this.template = options.template; + this.appendWidgetTo = options.appendWidgetTo; - "use strict"; // jshint ;_; + this._init(); + }; - var isTouch = 'ontouchstart' in window; + Timepicker.prototype = { - /* 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(); - }; + constructor: Timepicker, - Timepicker.prototype = { + _init: function() { + var self = this; - 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); + if (this.$element.parent().hasClass('input-append') || this.$element.parent().hasClass('input-prepend')) { + this.$element.parent('.input-append, .input-prepend').find('.add-on').on({ + 'click.timepicker': $.proxy(this.showWidget, this) + }); + this.$element.on({ + 'focus.timepicker': $.proxy(this.highlightUnit, this), + 'click.timepicker': $.proxy(this.highlightUnit, this), + 'keydown.timepicker': $.proxy(this.elementKeydown, this), + 'blur.timepicker': $.proxy(this.blurElement, this) + }); + } else { + if (this.template) { + this.$element.on({ + 'focus.timepicker': $.proxy(this.showWidget, this), + 'click.timepicker': $.proxy(this.showWidget, this), + 'blur.timepicker': $.proxy(this.blurElement, this) + }); + } else { + this.$element.on({ + 'focus.timepicker': $.proxy(this.highlightUnit, this), + 'click.timepicker': $.proxy(this.highlightUnit, this), + 'keydown.timepicker': $.proxy(this.elementKeydown, this), + 'blur.timepicker': $.proxy(this.blurElement, this) + }); } + } - , showWidget: function(e) { - e.stopPropagation(); + if (this.template !== false) { + this.$widget = $(this.getTemplate()).prependTo(this.$element.parents(this.appendWidgetTo)).on('click', $.proxy(this.widgetClick, this)); + } else { + this.$widget = false; + } + + if (this.showInputs && this.$widget !== false) { + this.$widget.find('input').each(function() { + $(this).on({ + 'click.timepicker': function() { $(this).select(); }, + 'keydown.timepicker': $.proxy(self.widgetKeydown, self) + }); + }); + } + + this.setDefaultTime(this.defaultTime); + }, + + blurElement: function() { + this.highlightedUnit = undefined; + this.updateFromElementVal(); + }, + + decrementHour: function() { + if (this.showMeridian) { + if (this.hour === 1) { + this.hour = 12; + } else if (this.hour === 12) { + this.hour--; + + return this.toggleMeridian(); + } else if (this.hour === 0) { + this.hour = 11; + + return this.toggleMeridian(); + } else { + this.hour--; + } + } else { + if (this.hour === 0) { + this.hour = 23; + } else { + this.hour--; + } + } + this.update(); + }, + + decrementMinute: function(step) { + var newVal; + + if (step) { + newVal = this.minute - step; + } else { + newVal = this.minute - this.minuteStep; + } + + if (newVal < 0) { + this.decrementHour(); + this.minute = newVal + 60; + } else { + this.minute = newVal; + } + this.update(); + }, + + decrementSecond: function() { + var newVal = this.second - this.secondStep; + + if (newVal < 0) { + this.decrementMinute(true); + this.second = newVal + 60; + } else { + this.second = newVal; + } + this.update(); + }, + + elementKeydown: function(e) { + switch (e.keyCode) { + case 9: //tab + this.updateFromElementVal(); + + switch (this.highlightedUnit) { + case 'hour': + e.preventDefault(); + this.highlightNextUnit(); + break; + case 'minute': + if (this.showMeridian || this.showSeconds) { 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(); + this.highlightNextUnit(); + } + break; + case 'second': + if (this.showMeridian) { e.preventDefault(); - - var action = $(e.target).closest('a').data('action'); - if (action) { - this[action](); - this.update(); - } + this.highlightNextUnit(); + } + break; } - - , 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; - } + break; + case 27: // escape + this.updateFromElementVal(); + break; + case 37: // left arrow + e.preventDefault(); + this.highlightPrevUnit(); + this.updateFromElementVal(); + break; + case 38: // up arrow + e.preventDefault(); + switch (this.highlightedUnit) { + case 'hour': + this.incrementHour(); + this.highlightHour(); + break; + case 'minute': + this.incrementMinute(); + this.highlightMinute(); + break; + case 'second': + this.incrementSecond(); + this.highlightSecond(); + break; + case 'meridian': + this.toggleMeridian(); + this.highlightMeridian(); + 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(); - } + break; + case 39: // right arrow + e.preventDefault(); + this.updateFromElementVal(); + this.highlightNextUnit(); + break; + case 40: // down arrow + e.preventDefault(); + switch (this.highlightedUnit) { + case 'hour': + this.decrementHour(); + this.highlightHour(); + break; + case 'minute': + this.decrementMinute(); + this.highlightMinute(); + break; + case 'second': + this.decrementSecond(); + this.highlightSecond(); + break; + case 'meridian': + this.toggleMeridian(); + this.highlightMeridian(); + break; } + break; + } + }, - , setValues: function(time) { - if (this.showMeridian) { - var arr = time.split(' '); - var timeArray = arr[0].split(':'); - this.meridian = arr[1]; + 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 : ''); + }, + + 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(), + selLen = document.selection.createRange().text.length; + + sel.moveStart('character', - input.value.length); + + return sel.text.length - selLen; + } + }, + + getTemplate: function() { + var template, + hourTemplate, + minuteTemplate, + secondTemplate, + meridianTemplate, + templateContent; + + if (this.showInputs) { + hourTemplate = ''; + minuteTemplate = ''; + secondTemplate = ''; + meridianTemplate = ''; + } else { + hourTemplate = ''; + minuteTemplate = ''; + secondTemplate = ''; + meridianTemplate = ''; + } + + templateContent = '