/************************ jquery-timepicker http://jonthornton.github.com/jquery-timepicker/ requires jQuery 1.7+ ************************/ (function (factory) { if (typeof define === 'function' && define.amd) { // AMD. Register as an anonymous module. define(['jquery'], factory); } else { // Browser globals factory(jQuery); } }(function ($) { var _baseDate = _generateBaseDate(); var _ONE_DAY = 86400; var _closeEvent = 'ontouchstart' in document ? 'touchstart' : 'mousedown'; var _defaults = { className: null, minTime: null, maxTime: null, durationTime: null, step: 30, showDuration: false, timeFormat: 'g:ia', scrollDefaultNow: false, scrollDefaultTime: false, selectOnBlur: false, appendTo: 'body' }; var _lang = { decimal: '.', mins: 'mins', hr: 'hr', hrs: 'hrs' }; var globalInit = false; var methods = { init: function(options) { return this.each(function() { var self = $(this); // convert dropdowns to text input if (self[0].tagName == 'SELECT') { var input = $(''); var attrs = { 'type': 'text', 'value': self.val() }; var raw_attrs = self[0].attributes; for (var i=0; i < raw_attrs.length; i++) { attrs[raw_attrs[i].nodeName] = raw_attrs[i].nodeValue; } input.attr(attrs); self.replaceWith(input); self = input; } var settings = $.extend({}, _defaults); if (options) { settings = $.extend(settings, options); } if (settings.minTime) { settings.minTime = _time2int(settings.minTime); } if (settings.maxTime) { settings.maxTime = _time2int(settings.maxTime); } if (settings.durationTime) { settings.durationTime = _time2int(settings.durationTime); } if (settings.lang) { _lang = $.extend(_lang, settings.lang); } self.data('timepicker-settings', settings); self.attr('autocomplete', 'off'); self.on('click.timepicker focus.timepicker', methods.show); self.on('blur.timepicker', _formatValue); self.on('keydown.timepicker', _keyhandler); self.addClass('ui-timepicker-input'); _formatValue.call(self.get(0)); if (!globalInit) { // close the dropdown when container loses focus $('body').on(_closeEvent, function(e) { var target = $(e.target); var input = target.closest('.ui-timepicker-input'); if (input.length === 0 && target.closest('.ui-timepicker-list').length === 0) { methods.hide(); } }); globalInit = true; } }); }, show: function(e) { var self = $(this); if ('ontouchstart' in document) { // block the keyboard on mobile devices self.blur(); } var list = self.data('timepicker-list'); // check if input is readonly if (self.attr('readonly')) { return; } // check if list needs to be rendered if (!list || list.length === 0) { _render(self); list = self.data('timepicker-list'); } // check if a flag was set to close this picker if (self.hasClass('ui-timepicker-hideme')) { self.removeClass('ui-timepicker-hideme'); list.hide(); return; } if (list.is(':visible')) { return; } // make sure other pickers are hidden methods.hide(); if ((self.offset().top + self.outerHeight(true) + list.outerHeight()) > $(window).height() + $(window).scrollTop()) { // position the dropdown on top list.css({ 'left':(self.offset().left), 'top': self.offset().top - list.outerHeight() }); } else { // put it under the input list.css({ 'left':(self.offset().left), 'top': self.offset().top + self.outerHeight() }); } list.show(); var settings = self.data('timepicker-settings'); // position scrolling var selected = list.find('.ui-timepicker-selected'); if (!selected.length) { if (self.val()) { selected = _findRow(self, list, _time2int(self.val())); } else if (settings.scrollDefaultNow) { selected = _findRow(self, list, _time2int(new Date())); } else if (settings.scrollDefaultTime !== false) { selected = _findRow(self, list, _time2int(settings.scrollDefaultTime)); } } if (selected && selected.length) { var topOffset = list.scrollTop() + selected.position().top - selected.outerHeight(); list.scrollTop(topOffset); } else { list.scrollTop(0); } self.trigger('showTimepicker'); }, hide: function(e) { $('.ui-timepicker-list:visible').each(function() { var list = $(this); var self = list.data('timepicker-input'); var settings = self.data('timepicker-settings'); if (settings && settings.selectOnBlur) { _selectValue(self); } list.hide(); self.trigger('hideTimepicker'); }); }, option: function(key, value) { var self = $(this); var settings = self.data('timepicker-settings'); var list = self.data('timepicker-list'); if (typeof key == 'object') { settings = $.extend(settings, key); } else if (typeof key == 'string' && typeof value != 'undefined') { settings[key] = value; } else if (typeof key == 'string') { return settings[key]; } if (settings.minTime) { settings.minTime = _time2int(settings.minTime); } if (settings.maxTime) { settings.maxTime = _time2int(settings.maxTime); } if (settings.durationTime) { settings.durationTime = _time2int(settings.durationTime); } self.data('timepicker-settings', settings); if (list) { list.remove(); self.data('timepicker-list', false); } }, getSecondsFromMidnight: function() { return _time2int($(this).val()); }, getTime: function() { return new Date(_baseDate.valueOf() + (_time2int($(this).val())*1000)); }, setTime: function(value) { var self = $(this); var prettyTime = _int2time(_time2int(value), self.data('timepicker-settings').timeFormat); self.val(prettyTime); }, remove: function() { var self = $(this); // check if this element is a timepicker if (!self.hasClass('ui-timepicker-input')) { return; } self.removeAttr('autocomplete', 'off'); self.removeClass('ui-timepicker-input'); self.removeData('timepicker-settings'); self.off('.timepicker'); // timepicker-list won't be present unless the user has interacted with this timepicker if (self.data('timepicker-list')) { self.data('timepicker-list').remove(); } self.removeData('timepicker-list'); } }; // private methods function _render(self) { var settings = self.data('timepicker-settings'); var list = self.data('timepicker-list'); if (list && list.length) { list.remove(); self.data('timepicker-list', false); } list = $('