UNPKG

amazeui-datetimepicker-se

Version:
1,505 lines (1,350 loc) 86.8 kB
(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(_dereq_,module,exports){ (function (global){ /*! Amaze UI Plugin ~ datetimepicker-se */ 'use strict'; var $ = (typeof window !== "undefined" ? window['jQuery'] : typeof global !== "undefined" ? global['jQuery'] : null); var moment = (typeof window !== "undefined" ? window['moment'] : typeof global !== "undefined" ? global['moment'] : null); var dateTimePicker = _dereq_('../vendor/bootstrap-datetimepicker')($, moment); $.fn.datetimepicker = function(option) { var args = Array.prototype.slice.call(arguments, 1); var methodReturn; var $set = this.each(function() { var $this = $(this); var data = $this.data('DateTimePicker'); var options = typeof option === 'object' && option; if (!data) { $this.data('DateTimePicker', ( data = dateTimePicker( $this, $.extend(true, {}, $.fn.datetimepicker.defaults, options) ) ) ); } if (typeof option === 'string') { methodReturn = typeof data[option] === 'function' ? data[option].apply(data, args) : data[option]; } }); return (methodReturn === undefined) ? $set : methodReturn; }; $.fn.datetimepicker.defaults = { timeZone: 'Etc/UTC', format: 'YYYY-MM-DD HH:mm:ss', dayViewHeaderFormat: 'YYYY年MMM', extraFormats: false, stepping: 1, minDate: false, maxDate: false, useCurrent: true, collapse: true, // - locale: 'zh-cn', defaultDate: false, disabledDates: false, enabledDates: false, icons: { // - time: 'am-icon-clock-o', date: 'am-icon-calendar', up: 'am-icon-chevron-up', down: 'am-icon-chevron-down', previous: 'am-icon-chevron-left', next: 'am-icon-chevron-right', today: 'am-icon-undo', clear: 'am-icon-trash-o', close: 'am-icon-close' }, tooltips: { // - today: 'Go to today', clear: 'Clear selection', close: 'Close the picker', selectMonth: 'Select Month', prevMonth: 'Previous Month', nextMonth: 'Next Month', selectYear: 'Select Year', prevYear: 'Previous Year', nextYear: 'Next Year', selectDecade: 'Select Decade', prevDecade: 'Previous Decade', nextDecade: 'Next Decade', prevCentury: 'Previous Century', nextCentury: 'Next Century', pickHour: 'Pick Hour', incrementHour: 'Increment Hour', decrementHour: 'Decrement Hour', pickMinute: 'Pick Minute', incrementMinute: 'Increment Minute', decrementMinute: 'Decrement Minute', pickSecond: 'Pick Second', incrementSecond: 'Increment Second', decrementSecond: 'Decrement Second', togglePeriod: 'Toggle Period', selectTime: 'Select Time' }, useStrict: false, sideBySide: false, daysOfWeekDisabled: false, calendarWeeks: false, viewMode: 'days', toolbarPlacement: 'default', // - showTodayButton: false, // 显示返回今日按钮 showClear: false, // 显示清除日期按钮 showClose: false, // 显示关闭按钮日期选择器按钮 widgetPositioning: { horizontal: 'auto', vertical: 'auto' }, widgetParent: $(document.body), // widgetParent: null, // $(document.body), ignoreReadonly: false, keepOpen: false, focusOnShow: true, inline: false, keepInvalid: false, datepickerInput: '.datepickerinput', keyBinds: { up: function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().subtract(7, 'd')); } else { this.date(d.clone().add(this.stepping(), 'm')); } }, down: function (widget) { if (!widget) { this.show(); return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().add(7, 'd')); } else { this.date(d.clone().subtract(this.stepping(), 'm')); } }, 'control up': function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().subtract(1, 'y')); } else { this.date(d.clone().add(1, 'h')); } }, 'control down': function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().add(1, 'y')); } else { this.date(d.clone().subtract(1, 'h')); } }, left: function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().subtract(1, 'd')); } }, right: function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().add(1, 'd')); } }, pageUp: function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().subtract(1, 'M')); } }, pageDown: function (widget) { if (!widget) { return; } var d = this.date() || this.getMoment(); if (widget.find('.datepicker').is(':visible')) { this.date(d.clone().add(1, 'M')); } }, enter: function () { this.hide(); }, escape: function () { this.hide(); }, //tab: function (widget) { //this break the flow of the form. disabling for now // var toggle = widget.find('.picker-switch a[data-action="togglePicker"]'); // if(toggle.length > 0) toggle.click(); //}, 'control space': function (widget) { if (widget.find('.timepicker').is(':visible')) { widget.find('.btn[data-action="togglePeriod"]').click(); } }, t: function () { this.date(this.getMoment()); }, 'delete': function () { this.clear(); } }, debug: false, allowInputToggle: false, disabledTimeIntervals: false, disabledHours: false, enabledHours: false, viewDate: false }; }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) },{"../vendor/bootstrap-datetimepicker":2}],2:[function(_dereq_,module,exports){ /*! version : 4.17.37 ========================================================= bootstrap-datetimejs https://github.com/Eonasdan/bootstrap-datetimepicker The MIT License (MIT) Copyright (c) 2015 Jonathan Peterson ========================================================= */ 'use strict'; module.exports = function($, moment) { if (!moment) { throw new Error('bootstrap-datetimepicker requires Moment.js to be loaded first'); } var dateTimePicker = function(element, options) { var picker = {}, date, viewDate, unset = true, input, component = false, widget = false, use24Hours, minViewModeNumber = 0, actualFormat, parseFormats, currentViewMode, datePickerModes = [ { clsName: 'days', navFnc: 'M', navStep: 1 }, { clsName: 'months', navFnc: 'y', navStep: 1 }, { clsName: 'years', navFnc: 'y', navStep: 10 }, { clsName: 'decades', navFnc: 'y', navStep: 100 } ], viewModes = ['days', 'months', 'years', 'decades'], verticalModes = ['top', 'bottom', 'auto'], horizontalModes = ['left', 'right', 'auto'], toolbarPlacements = ['default', 'top', 'bottom'], keyMap = { 'up': 38, 38: 'up', 'down': 40, 40: 'down', 'left': 37, 37: 'left', 'right': 39, 39: 'right', 'tab': 9, 9: 'tab', 'escape': 27, 27: 'escape', 'enter': 13, 13: 'enter', 'pageUp': 33, 33: 'pageUp', 'pageDown': 34, 34: 'pageDown', 'shift': 16, 16: 'shift', 'control': 17, 17: 'control', 'space': 32, 32: 'space', 't': 84, 84: 't', 'delete': 46, 46: 'delete' }, keyState = {}, /******************************************************************************** * * Private functions * ********************************************************************************/ getMoment = function(d) { var tzEnabled = false, returnMoment, currentZoneOffset, incomingZoneOffset, timeZoneIndicator, dateWithTimeZoneInfo; if (moment.tz !== undefined && options.timeZone !== undefined && options.timeZone !== null && options.timeZone !== '') { tzEnabled = true; } if (d === undefined || d === null) { if (tzEnabled) { returnMoment = moment().tz(options.timeZone).startOf('d'); } else { returnMoment = moment().startOf('d'); } } else { if (tzEnabled) { currentZoneOffset = moment().tz(options.timeZone).utcOffset(); incomingZoneOffset = moment(d, parseFormats, options.useStrict) .utcOffset(); if (incomingZoneOffset !== currentZoneOffset) { timeZoneIndicator = moment().tz(options.timeZone).format('Z'); dateWithTimeZoneInfo = moment(d, parseFormats, options.useStrict) .format('YYYY-MM-DD[T]HH:mm:ss') + timeZoneIndicator; returnMoment = moment(dateWithTimeZoneInfo, parseFormats, options.useStrict) .tz(options.timeZone); } else { returnMoment = moment(d, parseFormats, options.useStrict) .tz(options.timeZone); } } else { returnMoment = moment(d, parseFormats, options.useStrict); } } return returnMoment; }, isEnabled = function(granularity) { if (typeof granularity !== 'string' || granularity.length > 1) { throw new TypeError('isEnabled expects a single character string parameter'); } switch (granularity) { case 'y': return actualFormat.indexOf('Y') !== -1; case 'M': return actualFormat.indexOf('M') !== -1; case 'd': return actualFormat.toLowerCase().indexOf('d') !== -1; case 'h': case 'H': return actualFormat.toLowerCase().indexOf('h') !== -1; case 'm': return actualFormat.indexOf('m') !== -1; case 's': return actualFormat.indexOf('s') !== -1; default: return false; } }, hasTime = function() { return (isEnabled('h') || isEnabled('m') || isEnabled('s')); }, hasDate = function() { return (isEnabled('y') || isEnabled('M') || isEnabled('d')); }, getDatePickerTemplate = function() { var headTemplate = $('<thead>') .append($('<tr>') .append($('<th>').addClass('prev').attr('data-action', 'previous') .append($('<span>').addClass(options.icons.previous)) ) .append($('<th>').addClass('picker-switch') .attr('data-action', 'pickerSwitch') .attr('colspan', (options.calendarWeeks ? '6' : '5'))) .append($('<th>').addClass('next').attr('data-action', 'next') .append($('<span>').addClass(options.icons.next)) ) ), contTemplate = $('<tbody>') .append($('<tr>') .append($('<td>') .attr('colspan', (options.calendarWeeks ? '8' : '7'))) ); return [ $('<div>').addClass('datepicker-days') .append($('<table>').addClass('table-condensed') .append(headTemplate) .append($('<tbody>')) ), $('<div>').addClass('datepicker-months') .append($('<table>').addClass('table-condensed') .append(headTemplate.clone()) .append(contTemplate.clone()) ), $('<div>').addClass('datepicker-years') .append($('<table>').addClass('table-condensed') .append(headTemplate.clone()) .append(contTemplate.clone()) ), $('<div>').addClass('datepicker-decades') .append($('<table>').addClass('table-condensed') .append(headTemplate.clone()) .append(contTemplate.clone()) ) ]; }, getTimePickerMainTemplate = function() { var topRow = $('<tr>'), middleRow = $('<tr>'), bottomRow = $('<tr>'); if (isEnabled('h')) { topRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementHour }).addClass('btn').attr('data-action', 'incrementHours') .append($('<span>').addClass(options.icons.up)))); middleRow.append($('<td>') .append($('<span>').addClass('timepicker-hour').attr({ 'data-time-component': 'hours', 'title': options.tooltips.pickHour }).attr('data-action', 'showHours'))); bottomRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementHour }).addClass('btn').attr('data-action', 'decrementHours') .append($('<span>').addClass(options.icons.down)))); } if (isEnabled('m')) { if (isEnabled('h')) { topRow.append($('<td>').addClass('separator')); middleRow.append($('<td>').addClass('separator').html(':')); bottomRow.append($('<td>').addClass('separator')); } topRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementMinute }).addClass('btn').attr('data-action', 'incrementMinutes') .append($('<span>').addClass(options.icons.up)))); middleRow.append($('<td>') .append($('<span>').addClass('timepicker-minute').attr({ 'data-time-component': 'minutes', 'title': options.tooltips.pickMinute }).attr('data-action', 'showMinutes'))); bottomRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementMinute }).addClass('btn').attr('data-action', 'decrementMinutes') .append($('<span>').addClass(options.icons.down)))); } if (isEnabled('s')) { if (isEnabled('m')) { topRow.append($('<td>').addClass('separator')); middleRow.append($('<td>').addClass('separator').html(':')); bottomRow.append($('<td>').addClass('separator')); } topRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.incrementSecond }).addClass('btn').attr('data-action', 'incrementSeconds') .append($('<span>').addClass(options.icons.up)))); middleRow.append($('<td>') .append($('<span>').addClass('timepicker-second').attr({ 'data-time-component': 'seconds', 'title': options.tooltips.pickSecond }).attr('data-action', 'showSeconds'))); bottomRow.append($('<td>') .append($('<a>').attr({ href: '#', tabindex: '-1', 'title': options.tooltips.decrementSecond }).addClass('btn').attr('data-action', 'decrementSeconds') .append($('<span>').addClass(options.icons.down)))); } if (!use24Hours) { topRow.append($('<td>').addClass('separator')); middleRow.append($('<td>') .append($('<button>').addClass('btn btn-primary').attr({ 'data-action': 'togglePeriod', tabindex: '-1', 'title': options.tooltips.togglePeriod }))); bottomRow.append($('<td>').addClass('separator')); } return $('<div>').addClass('timepicker-picker') .append($('<table>').addClass('table-condensed') .append([topRow, middleRow, bottomRow])); }, getTimePickerTemplate = function() { var hoursView = $('<div>').addClass('timepicker-hours') .append($('<table>').addClass('table-condensed')), minutesView = $('<div>').addClass('timepicker-minutes') .append($('<table>').addClass('table-condensed')), secondsView = $('<div>').addClass('timepicker-seconds') .append($('<table>').addClass('table-condensed')), ret = [getTimePickerMainTemplate()]; if (isEnabled('h')) { ret.push(hoursView); } if (isEnabled('m')) { ret.push(minutesView); } if (isEnabled('s')) { ret.push(secondsView); } return ret; }, getToolbar = function() { var row = []; if (options.showTodayButton) { row.push($('<td>').append($('<a>') .attr({'data-action': 'today', 'title': options.tooltips.today}) .append($('<span>').addClass(options.icons.today)))); } if (!options.sideBySide && hasDate() && hasTime()) { row.push($('<td>').append($('<a>').attr({ 'data-action': 'togglePicker', 'title': options.tooltips.selectTime }).append($('<span>').addClass(options.icons.time)))); } if (options.showClear) { row.push($('<td>').append($('<a>') .attr({'data-action': 'clear', 'title': options.tooltips.clear}) .append($('<span>').addClass(options.icons.clear)))); } if (options.showClose) { row.push($('<td>').append($('<a>') .attr({'data-action': 'close', 'title': options.tooltips.close}) .append($('<span>').addClass(options.icons.close)))); } return $('<table>').addClass('table-condensed') .append($('<tbody>').append($('<tr>').append(row))); }, getTemplate = function() { var template = $('<div>') .addClass('bootstrap-datetimepicker-widget dropdown-menu'), dateView = $('<div>').addClass('datepicker') .append(getDatePickerTemplate()), timeView = $('<div>').addClass('timepicker') .append(getTimePickerTemplate()), content = $('<ul>').addClass('list-unstyled'), toolbar = $('<li>') .addClass('picker-switch' + (options.collapse ? ' accordion-toggle' : '')) .append(getToolbar()); if (options.inline) { template.removeClass('dropdown-menu'); } if (use24Hours) { template.addClass('usetwentyfour'); } if (isEnabled('s') && !use24Hours) { template.addClass('wider'); } if (options.sideBySide && hasDate() && hasTime()) { template.addClass('timepicker-sbs'); if (options.toolbarPlacement === 'top') { template.append(toolbar); } template.append( $('<div class="am-g">') .append(dateView.addClass('am-fl')) .append(timeView.addClass('am-fl')) ); if (options.toolbarPlacement === 'bottom') { template.append(toolbar); } return template; } if (options.toolbarPlacement === 'top') { content.append(toolbar); } if (hasDate()) { content.append($('<li>') .addClass((options.collapse && hasTime() ? 'collapse in' : '')) .append(dateView)); } if (options.toolbarPlacement === 'default') { content.append(toolbar); } if (hasTime()) { content.append($('<li>') .addClass((options.collapse && hasDate() ? 'collapse' : '')) .append(timeView)); } if (options.toolbarPlacement === 'bottom') { content.append(toolbar); } return template.append(content); }, dataToOptions = function() { var eData, dataOptions = {}; if (element.is('input') || options.inline) { eData = element.data(); } else { eData = element.find('input').data(); } if (eData.dateOptions && eData.dateOptions instanceof Object) { dataOptions = $.extend(true, dataOptions, eData.dateOptions); } $.each(options, function(key) { var attributeName = 'date' + key.charAt(0) .toUpperCase() + key.slice(1); if (eData[attributeName] !== undefined) { dataOptions[key] = eData[attributeName]; } }); return dataOptions; }, place = function() { var $refer = component || element; var position = $refer.position(), offset = $refer.offset(), vertical = options.widgetPositioning.vertical, horizontal = options.widgetPositioning.horizontal, parent; var referHeight = $refer.outerHeight(); var referWidth = $refer.outerWidth(); var widgetWidth = 242; if (options.inline) { parent = element.append(widget); return; } else if (options.widgetParent) { parent = options.widgetParent.append(widget); } else if (element.is('input')) { parent = element.after(widget).parent(); } else { parent = element; element.children().first().after(widget); } // Top and bottom logic if (vertical === 'auto') { if (offset.top + widget.height() * 1.5 >= $(window) .height() + $(window).scrollTop() && widget.height() + element.outerHeight() < offset.top) { vertical = 'top'; } else { vertical = 'bottom'; } } // Left and right logic if (horizontal === 'auto') { if (parent.width() < offset.left + widget.outerWidth() / 2 && offset.left + widget.outerWidth() > $(window).width()) { horizontal = 'right'; } else { horizontal = 'left'; } } /*if (vertical === 'top') { widget.addClass('top').removeClass('bottom'); } else { widget.addClass('bottom').removeClass('top'); } if (horizontal === 'right') { widget.addClass('pull-right'); } else { widget.removeClass('pull-right'); }*/ // TODO: 完善定位逻辑 widget.addClass('bottom ' + horizontal); var style = { position: 'absolute', top: offset.top + element.outerHeight() }; widget.css($.extend({}, style, { left: horizontal === 'left' ? offset.left : offset.left + referWidth - widgetWidth // right: horizontal === 'left' ? 'auto' : offset.left /*top: vertical === 'top' ? 'auto' : position.top + element.outerHeight(), bottom: vertical === 'top' ? position.top + element.outerHeight() : 'auto', left: horizontal === 'left' ? (parent === element ? 0 : position.left) : 'auto', right: horizontal === 'left' ? 'auto' : parent.outerWidth() - element.outerWidth() - (parent === element ? 0 : position.left)*/ })); }, notifyEvent = function(e) { if (e.type === 'dp.change' && ((e.date && e.date.isSame(e.oldDate)) || (!e.date && !e.oldDate))) { return; } element.trigger(e); }, viewUpdate = function(e) { if (e === 'y') { e = 'YYYY'; } notifyEvent({ type: 'dp.update', change: e, viewDate: viewDate.clone() }); }, showMode = function(dir) { if (!widget) { return; } if (dir) { currentViewMode = Math.max(minViewModeNumber, Math.min(3, currentViewMode + dir)); } widget.find('.datepicker > div').hide() .filter('.datepicker-' + datePickerModes[currentViewMode].clsName) .show(); }, fillDow = function() { var row = $('<tr>'), currentDate = viewDate.clone().startOf('w').startOf('d'); if (options.calendarWeeks === true) { row.append($('<th>').addClass('cw').text('#')); } while (currentDate.isBefore(viewDate.clone().endOf('w'))) { row.append($('<th>').addClass('dow').text(currentDate.format('dd'))); currentDate.add(1, 'd'); } widget.find('.datepicker-days thead').append(row); }, isInDisabledDates = function(testDate) { return options.disabledDates[testDate.format('YYYY-MM-DD')] === true; }, isInEnabledDates = function(testDate) { return options.enabledDates[testDate.format('YYYY-MM-DD')] === true; }, isInDisabledHours = function(testDate) { return options.disabledHours[testDate.format('H')] === true; }, isInEnabledHours = function(testDate) { return options.enabledHours[testDate.format('H')] === true; }, isValid = function(targetMoment, granularity) { if (!targetMoment.isValid()) { return false; } if (options.disabledDates && granularity === 'd' && isInDisabledDates(targetMoment)) { return false; } if (options.enabledDates && granularity === 'd' && !isInEnabledDates(targetMoment)) { return false; } if (options.minDate && targetMoment.isBefore(options.minDate, granularity)) { return false; } if (options.maxDate && targetMoment.isAfter(options.maxDate, granularity)) { return false; } if (options.daysOfWeekDisabled && granularity === 'd' && options.daysOfWeekDisabled.indexOf(targetMoment.day()) !== -1) { return false; } if (options.disabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && isInDisabledHours(targetMoment)) { return false; } if (options.enabledHours && (granularity === 'h' || granularity === 'm' || granularity === 's') && !isInEnabledHours(targetMoment)) { return false; } if (options.disabledTimeIntervals && (granularity === 'h' || granularity === 'm' || granularity === 's')) { var found = false; $.each(options.disabledTimeIntervals, function() { if (targetMoment.isBetween(this[0], this[1])) { found = true; return false; } }); if (found) { return false; } } return true; }, fillMonths = function() { var spans = [], monthsShort = viewDate.clone().startOf('y').startOf('d'); while (monthsShort.isSame(viewDate, 'y')) { spans.push($('<span>').attr('data-action', 'selectMonth') .addClass('month').text(monthsShort.format('MMM'))); monthsShort.add(1, 'M'); } widget.find('.datepicker-months td').empty().append(spans); }, updateMonths = function() { var monthsView = widget.find('.datepicker-months'), monthsViewHeader = monthsView.find('th'), months = monthsView.find('tbody').find('span'); monthsViewHeader.eq(0).find('span') .attr('title', options.tooltips.prevYear); monthsViewHeader.eq(1).attr('title', options.tooltips.selectYear); monthsViewHeader.eq(2).find('span') .attr('title', options.tooltips.nextYear); monthsView.find('.disabled').removeClass('disabled'); if (!isValid(viewDate.clone().subtract(1, 'y'), 'y')) { monthsViewHeader.eq(0).addClass('disabled'); } monthsViewHeader.eq(1).text(viewDate.year()); if (!isValid(viewDate.clone().add(1, 'y'), 'y')) { monthsViewHeader.eq(2).addClass('disabled'); } months.removeClass('active'); if (date.isSame(viewDate, 'y') && !unset) { months.eq(date.month()).addClass('active'); } months.each(function(index) { if (!isValid(viewDate.clone().month(index), 'M')) { $(this).addClass('disabled'); } }); }, updateYears = function() { var yearsView = widget.find('.datepicker-years'), yearsViewHeader = yearsView.find('th'), startYear = viewDate.clone().subtract(5, 'y'), endYear = viewDate.clone().add(6, 'y'), html = ''; yearsViewHeader.eq(0).find('span') .attr('title', options.tooltips.prevDecade); yearsViewHeader.eq(1).attr('title', options.tooltips.selectDecade); yearsViewHeader.eq(2).find('span') .attr('title', options.tooltips.nextDecade); yearsView.find('.disabled').removeClass('disabled'); if (options.minDate && options.minDate.isAfter(startYear, 'y')) { yearsViewHeader.eq(0).addClass('disabled'); } yearsViewHeader.eq(1).text(startYear.year() + '-' + endYear.year()); if (options.maxDate && options.maxDate.isBefore(endYear, 'y')) { yearsViewHeader.eq(2).addClass('disabled'); } while (!startYear.isAfter(endYear, 'y')) { html += '<span data-action="selectYear" class="year' + (startYear.isSame(date, 'y') && !unset ? ' active' : '') + (!isValid(startYear, 'y') ? ' disabled' : '') + '">' + startYear.year() + '</span>'; startYear.add(1, 'y'); } yearsView.find('td').html(html); }, updateDecades = function() { var decadesView = widget.find('.datepicker-decades'), decadesViewHeader = decadesView.find('th'), startDecade = moment({y: viewDate.year() - (viewDate.year() % 100) - 1}), endDecade = startDecade.clone().add(100, 'y'), startedAt = startDecade.clone(), html = ''; decadesViewHeader.eq(0).find('span') .attr('title', options.tooltips.prevCentury); decadesViewHeader.eq(2).find('span') .attr('title', options.tooltips.nextCentury); decadesView.find('.disabled').removeClass('disabled'); if (startDecade.isSame(moment({y: 1900})) || (options.minDate && options.minDate.isAfter(startDecade, 'y'))) { decadesViewHeader.eq(0).addClass('disabled'); } decadesViewHeader.eq(1) .text(startDecade.year() + '-' + endDecade.year()); if (startDecade.isSame(moment({y: 2000})) || (options.maxDate && options.maxDate.isBefore(endDecade, 'y'))) { decadesViewHeader.eq(2).addClass('disabled'); } while (!startDecade.isAfter(endDecade, 'y')) { html += '<span data-action="selectDecade" class="decade' + (startDecade.isSame(date, 'y') ? ' active' : '') + (!isValid(startDecade, 'y') ? ' disabled' : '') + '" data-selection="' + (startDecade.year() + 6) + '">' + (startDecade.year() + 1) + ' - ' + (startDecade.year() + 12) + '</span>'; startDecade.add(12, 'y'); } html += '<span></span><span></span><span></span>'; //push the dangling block over, at least this way it's even decadesView.find('td').html(html); decadesViewHeader.eq(1) .text((startedAt.year() + 1) + '-' + (startDecade.year())); }, fillDate = function() { var daysView = widget.find('.datepicker-days'), daysViewHeader = daysView.find('th'), currentDate, html = [], row, clsName, i; if (!hasDate()) { return; } daysViewHeader.eq(0).find('span') .attr('title', options.tooltips.prevMonth); daysViewHeader.eq(1).attr('title', options.tooltips.selectMonth); daysViewHeader.eq(2).find('span') .attr('title', options.tooltips.nextMonth); daysView.find('.disabled').removeClass('disabled'); daysViewHeader.eq(1).text(viewDate.format(options.dayViewHeaderFormat)); if (!isValid(viewDate.clone().subtract(1, 'M'), 'M')) { daysViewHeader.eq(0).addClass('disabled'); } if (!isValid(viewDate.clone().add(1, 'M'), 'M')) { daysViewHeader.eq(2).addClass('disabled'); } currentDate = viewDate.clone().startOf('M').startOf('w').startOf('d'); for (i = 0; i < 42; i++) { //always display 42 days (should show 6 weeks) if (currentDate.weekday() === 0) { row = $('<tr>'); if (options.calendarWeeks) { row.append('<td class="cw">' + currentDate.week() + '</td>'); } html.push(row); } clsName = ''; if (currentDate.isBefore(viewDate, 'M')) { clsName += ' old'; } if (currentDate.isAfter(viewDate, 'M')) { clsName += ' new'; } if (currentDate.isSame(date, 'd') && !unset) { clsName += ' active'; } if (!isValid(currentDate, 'd')) { clsName += ' disabled'; } if (currentDate.isSame(getMoment(), 'd')) { clsName += ' today'; } if (currentDate.day() === 0 || currentDate.day() === 6) { clsName += ' weekend'; } row.append('<td data-action="selectDay" data-day="' + currentDate.format('L') + '" class="day' + clsName + '">' + currentDate.date() + '</td>'); currentDate.add(1, 'd'); } daysView.find('tbody').empty().append(html); updateMonths(); updateYears(); updateDecades(); }, fillHours = function() { var table = widget.find('.timepicker-hours table'), currentHour = viewDate.clone().startOf('d'), html = [], row = $('<tr>'); if (viewDate.hour() > 11 && !use24Hours) { currentHour.hour(12); } while (currentHour.isSame(viewDate, 'd') && (use24Hours || (viewDate.hour() < 12 && currentHour.hour() < 12) || viewDate.hour() > 11)) { if (currentHour.hour() % 4 === 0) { row = $('<tr>'); html.push(row); } row.append('<td data-action="selectHour" class="hour' + (!isValid(currentHour, 'h') ? ' disabled' : '') + '">' + currentHour.format(use24Hours ? 'HH' : 'hh') + '</td>'); currentHour.add(1, 'h'); } table.empty().append(html); }, fillMinutes = function() { var table = widget.find('.timepicker-minutes table'), currentMinute = viewDate.clone().startOf('h'), html = [], row = $('<tr>'), step = options.stepping === 1 ? 5 : options.stepping; while (viewDate.isSame(currentMinute, 'h')) { if (currentMinute.minute() % (step * 4) === 0) { row = $('<tr>'); html.push(row); } row.append('<td data-action="selectMinute" class="minute' + (!isValid(currentMinute, 'm') ? ' disabled' : '') + '">' + currentMinute.format('mm') + '</td>'); currentMinute.add(step, 'm'); } table.empty().append(html); }, fillSeconds = function() { var table = widget.find('.timepicker-seconds table'), currentSecond = viewDate.clone().startOf('m'), html = [], row = $('<tr>'); while (viewDate.isSame(currentSecond, 'm')) { if (currentSecond.second() % 20 === 0) { row = $('<tr>'); html.push(row); } row.append('<td data-action="selectSecond" class="second' + (!isValid(currentSecond, 's') ? ' disabled' : '') + '">' + currentSecond.format('ss') + '</td>'); currentSecond.add(5, 's'); } table.empty().append(html); }, fillTime = function() { var toggle, newDate, timeComponents = widget.find('.timepicker span[data-time-component]'); if (!use24Hours) { toggle = widget.find('.timepicker [data-action=togglePeriod]'); newDate = date.clone().add((date.hours() >= 12) ? -12 : 12, 'h'); toggle.text(date.format('A')); if (isValid(newDate, 'h')) { toggle.removeClass('disabled'); } else { toggle.addClass('disabled'); } } timeComponents.filter('[data-time-component=hours]') .text(date.format(use24Hours ? 'HH' : 'hh')); timeComponents.filter('[data-time-component=minutes]') .text(date.format('mm')); timeComponents.filter('[data-time-component=seconds]') .text(date.format('ss')); fillHours(); fillMinutes(); fillSeconds(); }, update = function() { if (!widget) { return; } fillDate(); fillTime(); }, setValue = function(targetMoment) { var oldDate = unset ? null : date; // case of calling setValue(null or false) if (!targetMoment) { unset = true; input.val(''); element.data('date', ''); notifyEvent({ type: 'dp.change', date: false, oldDate: oldDate }); update(); return; } targetMoment = targetMoment.clone().locale(options.locale); if (options.stepping !== 1) { targetMoment.minutes((Math.round(targetMoment.minutes() / options.stepping) * options.stepping) % 60) .seconds(0); } if (isValid(targetMoment)) { date = targetMoment; viewDate = date.clone(); input.val(date.format(actualFormat)); element.data('date', date.format(actualFormat)); unset = false; update(); notifyEvent({ type: 'dp.change', date: date.clone(), oldDate: oldDate }); } else { if (!options.keepInvalid) { input.val(unset ? '' : date.format(actualFormat)); } notifyEvent({ type: 'dp.error', date: targetMoment }); } }, hide = function() { ///<summary>Hides the widget. Possibly will emit dp.hide</summary> var transitioning = false; if (!widget) { return picker; } // Ignore event if in the middle of a picker transition widget.find('.collapse').each(function() { var collapseData = $(this).data('collapse'); if (collapseData && collapseData.transitioning) { transitioning = true; return false; } return true; }); if (transitioning) { return picker; } if (component && component.hasClass('btn')) { component.toggleClass('active'); } widget.hide(); $(window).off('resize', place); widget.off('click', '[data-action]'); widget.off('mousedown', false); widget.remove(); widget = false; notifyEvent({ type: 'dp.hide', date: date.clone() }); input.blur(); return picker; }, clear = function() { setValue(null); }, /******************************************************************************** * * Widget UI interaction functions * ********************************************************************************/ actions = { next: function() { var navFnc = datePickerModes[currentViewMode].navFnc; viewDate.add(datePickerModes[currentViewMode].navStep, navFnc); fillDate(); viewUpdate(navFnc); }, previous: function() { var navFnc = datePickerModes[currentViewMode].navFnc; viewDate.subtract(datePickerModes[currentViewMode].navStep, navFnc); fillDate(); viewUpdate(navFnc); }, pickerSwitch: function() { showMode(1); }, selectMonth: function(e) { var month = $(e.target).closest('tbody').find('span') .index($(e.target)); viewDate.month(month); if (currentViewMode === minViewModeNumber) { setValue(date.clone().year(viewDate.year()) .month(viewDate.month())); if (!options.inline) { hide(); } } else { showMode(-1); fillDate(); } viewUpdate('M'); }, selectYear: function(e) { var year = parseInt($(e.target).text(), 10) || 0; viewDate.year(year); if (currentViewMode === minViewModeNumber) { setValue(date.clone().year(viewDate.year())); if (!options.inline) { hide(); } } else { showMode(-1); fillDate(); } viewUpdate('YYYY'); }, selectDecade: function(e) { var year = parseInt($(e.target).data('selection'), 10) || 0; viewDate.year(year); if (currentViewMode === minViewModeNumber) { setValue(date.clone().year(viewDate.year())); if (!options.inline) { hide(); } } else { showMode(-1); fillDate(); } viewUpdate('YYYY'); }, selectDay: function(e) { var day = viewDate.clone(); if ($(e.target).is('.old')) { day.subtract(1, 'M'); } if ($(e.target).is('.new')) { day.add(1, 'M'); } setValue(day.date(parseInt($(e.target).text(), 10))); if (!hasTime() && !options.keepOpen && !options.inline) { hide(); } }, incrementHours: function() { var newDate = date.clone().add(1, 'h'); if (isValid(newDate, 'h')) { setValue(newDate); } }, incrementMinutes: function() { var newDate = date.clone().add(options.stepping, 'm'); if (isValid(newDate, 'm')) { setValue(newDate); } }, incrementSeconds: function() { var newDate = date.clone().add(1, 's'); if (isValid(newDate, 's')) { setValue(newDate); } }, decrementHours: function() { var newDate = date.clone().subtract(1, 'h'); if (isValid(newDate, 'h')) { setValue(newDate); } }, decrementMinutes: function() { var newDate = date.clone().subtract(options.stepping, 'm'); if (isValid(newDate, 'm')) { setValue(newDate); } }, decrementSeconds: function() { var newDate = date.clone().subtract(1, 's'); if (isValid(newDate, 's')) { setValue(newDate); } }, togglePeriod: function() { setValue(date.clone().add((date.hours() >= 12) ? -12 : 12, 'h')); }, togglePicker: function(e) { var $this = $(e.target), $parent = $this.closest('ul'), expanded = $parent.find('.in'), closed = $parent.find('.collapse:not(.in)'), collapseData; if (expanded && expanded.length) { collapseData = expanded.data('collapse'); if (collapseData && collapseData.transitioning) { return; } /*if (expanded.collapse) { // if collapse plugin is available through bootstrap.js then use it expanded.collapse('hide'); closed.collapse('show'); } else { */// otherwise just toggle in class on the two views expanded.removeClass('in'); closed.addClass('in'); //} if ($this.is('span')) { $this.toggleClass(options.icons.time + ' ' + options.icons.date); } else { $this.find('span') .toggleClass(options.icons.time + ' ' + options.icons.date); } // NOTE: uncomment if toggled state will be restored in show() //if (component) { // component.find('span').toggleClass(options.icons.time + ' ' + options.icons.date); //} } }, showPicker: function() { widget.find('.timepicker > div:not(.timepicker-picker)').hide(); widget.find('.timepicker .timepicker-picker').show(); }, showHours: function() { widget.find('.timepicker .timepicker-picker').hide(); widget.find('.timepicker .timepicker-hours').show(); }, showMinutes: function() { widget.find('.timepicker .timepicker-picker').hide(); widget.find('.timepicker .timepicker-minutes').show(); }, showSeconds: function() { widget.find('.timepicker .timepicker-picker').hide(); widget.find('.timepicker .timepicker-seconds').show(); }, selectHour: function(e) { var hour = parseInt($(e.target).text(), 10); if (!use24Hours) { if (date.hours() >= 12) { if (hour !== 12) { hour += 12; } } else { if (hour === 12) { hour = 0; } } } setValue(date.clone().hours(hour)); actions.showPicker.call(picker); }, selectMinute: function(e) { setValue(date.clone().minutes(parseInt($(e.target).text(), 10))); actions.showPicker.call(picker); }, selectSecond: function(e) { setValue(date.clone().seconds(parseInt($(e.target).text(), 10))); actions.showPicker.call(picker); }, clear: clear, today: function() { var todaysDate = getMoment(); if (isValid(todaysDate, 'd')) { setValue(todaysDate); } }, close: hide }, doAction = function(e) { if ($(e.currentTarget).is('.disabled')) { return false; } actions[$(e.currentTarget).data('action')].apply(picker, arguments); return false; }, show = function() { ///<summary>Shows the widget. Possibly will emit dp.show and dp.change</summary> var currentMoment, useCurrentGranularity = { 'year': function(m) { return m.month(0).date(1).hours(0).seconds(0).minutes(0); }, 'month': function(m) { return m.date(1).hours(0).seconds(0).minutes(0); }, 'day': function(m) { return m.hours(0).seconds(0).minutes(0); }, 'hour': function(m) { return m.seconds(0).minutes(0); }, 'minute': function(m) { return m.seconds(0); } }; if (input.prop('disabled') || (!options.ignoreReadonly && input.prop('readonly')) || widget) { return picker; } if (input.val() !== undefined && input.val().trim().length !== 0) { setValue(parseInputDate(input.val().trim())); } else if (options.useCurrent && unset && ((input.is('input') && input.val() .trim().length === 0) || options.inline)) { currentMoment = getMoment(); if (typeof options.useCurrent === 'string') { currentMoment = useCurrentGranularity[options.useCurrent](currentMoment); } setValue(currentMoment); } widget = getTemplate(); fillDow(); fillMonths(); widget.find('.timepicker-hours').hide(); widget.find('.timepicker-minutes').hide(); widget.find('.timepicker-seconds').hide(); update(); showMode(); $(window).on('resize', place); widget.on('click', '[data-action]', doAction); // this handles clicks on the widget widget.on('mousedown', false); if (component && component.hasClass('btn')) { component.toggleClass('active'); } widget.show(); place(); if (options.focusOnShow && !input.is(':focus')) { input.focus(); } notifyEvent({ type: 'dp.show' }); return picker; }, toggle = function() { /// <summary>Shows or hides the widget</summary> return (widget ? hide() : show()); }, parseInputDate = fun