/* //! version : 3.1.3 ========================================================= bootstrap-datetimepicker.js https://github.com/eonasdan/bootstrap-datetimepicker ========================================================= the mit license (mit) copyright (c) 2014 jonathan peterson permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "software"), to deal in the software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the software, and to permit persons to whom the software is furnished to do so, subject to the following conditions: the above copyright notice and this permission notice shall be included in all copies or substantial portions of the software. the software is provided "as is", without warranty of any kind, express or implied, including but not limited to the warranties of merchantability, fitness for a particular purpose and noninfringement. in no event shall the authors or copyright holders be liable for any claim, damages or other liability, whether in an action of contract, tort or otherwise, arising from, out of or in connection with the software or the use or other dealings in the software. */ ;(function (root, factory) { 'use strict'; if (typeof define === 'function' && define.amd) { // amd is used - register as an anonymous module. define(['jquery', 'moment'], factory); } else if (typeof exports === 'object') { factory(require('jquery'), require('moment')); } else { // neither amd or commonjs used. use global variables. if (!jquery) { throw new error('bootstrap-datetimepicker requires jquery to be loaded first'); } if (!moment) { throw new error('bootstrap-datetimepicker requires moment.js to be loaded first'); } factory(root.jquery, moment); } }(this, function ($, moment) { 'use strict'; if (typeof moment === 'undefined') { throw new error('momentjs is required'); } var dpgid = 0, datetimepicker = function (element, options) { var defaults = $.fn.datetimepicker.defaults, icons = { time: 'glyphicon glyphicon-time', date: 'glyphicon glyphicon-calendar', up: 'glyphicon glyphicon-chevron-up', down: 'glyphicon glyphicon-chevron-down' }, picker = this, errored = false, ddate, init = function () { var icon = false, localedata, rinterval; picker.options = $.extend({}, defaults, options); picker.options.icons = $.extend({}, icons, picker.options.icons); picker.element = $(element); datatooptions(); if (!(picker.options.picktime || picker.options.pickdate)) { throw new error('must choose at least one picker'); } picker.id = dpgid++; moment.locale(picker.options.language); picker.date = moment(); picker.unset = false; picker.isinput = picker.element.is('input'); picker.component = false; if (picker.element.hasclass('input-group')) { if (picker.element.find('.datepickerbutton').size() === 0) {//in case there is more then one 'input-group-addon' issue #48 picker.component = picker.element.find('[class^="input-group-"]'); } else { picker.component = picker.element.find('.datepickerbutton'); } } picker.format = picker.options.format; localedata = moment().localedata(); if (!picker.format) { picker.format = (picker.options.pickdate ? localedata.longdateformat('l') : ''); if (picker.options.pickdate && picker.options.picktime) { picker.format += ' '; } picker.format += (picker.options.picktime ? localedata.longdateformat('lt') : ''); if (picker.options.useseconds) { if (localedata.longdateformat('lt').indexof(' a') !== -1) { picker.format = picker.format.split(' a')[0] + ':ss a'; } else { picker.format += ':ss'; } } } picker.use24hours = (picker.format.tolowercase().indexof('a') < 0 && picker.format.indexof('h') < 0); if (picker.component) { icon = picker.component.find('span'); } if (picker.options.picktime) { if (icon) { icon.addclass(picker.options.icons.time); } } if (picker.options.pickdate) { if (icon) { icon.removeclass(picker.options.icons.time); icon.addclass(picker.options.icons.date); } } picker.options.widgetparent = typeof picker.options.widgetparent === 'string' && picker.options.widgetparent || picker.element.parents().filter(function () { return 'scroll' === $(this).css('overflow-y'); }).get(0) || 'body'; picker.widget = $(gettemplate()).appendto(picker.options.widgetparent); picker.minviewmode = picker.options.minviewmode || 0; if (typeof picker.minviewmode === 'string') { switch (picker.minviewmode) { case 'months': picker.minviewmode = 1; break; case 'years': picker.minviewmode = 2; break; default: picker.minviewmode = 0; break; } } picker.viewmode = picker.options.viewmode || 0; if (typeof picker.viewmode === 'string') { switch (picker.viewmode) { case 'months': picker.viewmode = 1; break; case 'years': picker.viewmode = 2; break; default: picker.viewmode = 0; break; } } picker.viewmode = math.max(picker.viewmode, picker.minviewmode); picker.options.disableddates = indexgivendates(picker.options.disableddates); picker.options.enableddates = indexgivendates(picker.options.enableddates); picker.startviewmode = picker.viewmode; picker.setmindate(picker.options.mindate); picker.setmaxdate(picker.options.maxdate); filldow(); fillmonths(); fillhours(); fillminutes(); fillseconds(); update(); showmode(); if (!getpickerinput().prop('disabled')) { attachdatepickerevents(); } if (picker.options.defaultdate !== '' && getpickerinput().val() === '') { picker.setvalue(picker.options.defaultdate); } if (picker.options.minutestepping !== 1) { rinterval = picker.options.minutestepping; picker.date.minutes((math.round(picker.date.minutes() / rinterval) * rinterval) % 60).seconds(0); } }, getpickerinput = function () { var input; if (picker.isinput) { return picker.element; } input = picker.element.find('.datepickerinput'); if (input.size() === 0) { input = picker.element.find('input'); } else if (!input.is('input')) { throw new error('css class "datepickerinput" cannot be applied to non input element'); } return input; }, datatooptions = function () { var edata; if (picker.element.is('input')) { edata = picker.element.data(); } else { edata = picker.element.find('input').data(); } if (edata.dateformat !== undefined) { picker.options.format = edata.dateformat; } if (edata.datepickdate !== undefined) { picker.options.pickdate = edata.datepickdate; } if (edata.datepicktime !== undefined) { picker.options.picktime = edata.datepicktime; } if (edata.dateuseminutes !== undefined) { picker.options.useminutes = edata.dateuseminutes; } if (edata.dateuseseconds !== undefined) { picker.options.useseconds = edata.dateuseseconds; } if (edata.dateusecurrent !== undefined) { picker.options.usecurrent = edata.dateusecurrent; } if (edata.calendarweeks !== undefined) { picker.options.calendarweeks = edata.calendarweeks; } if (edata.dateminutestepping !== undefined) { picker.options.minutestepping = edata.dateminutestepping; } if (edata.datemindate !== undefined) { picker.options.mindate = edata.datemindate; } if (edata.datemaxdate !== undefined) { picker.options.maxdate = edata.datemaxdate; } if (edata.dateshowtoday !== undefined) { picker.options.showtoday = edata.dateshowtoday; } if (edata.datecollapse !== undefined) { picker.options.collapse = edata.datecollapse; } if (edata.datelanguage !== undefined) { picker.options.language = edata.datelanguage; } if (edata.datedefaultdate !== undefined) { picker.options.defaultdate = edata.datedefaultdate; } if (edata.datedisableddates !== undefined) { picker.options.disableddates = edata.datedisableddates; } if (edata.dateenableddates !== undefined) { picker.options.enableddates = edata.dateenableddates; } if (edata.dateicons !== undefined) { picker.options.icons = edata.dateicons; } if (edata.dateusestrict !== undefined) { picker.options.usestrict = edata.dateusestrict; } if (edata.datedirection !== undefined) { picker.options.direction = edata.datedirection; } if (edata.datesidebyside !== undefined) { picker.options.sidebyside = edata.datesidebyside; } if (edata.datedaysofweekdisabled !== undefined) { picker.options.daysofweekdisabled = edata.datedaysofweekdisabled; } }, place = function () { var position = 'absolute', offset = picker.component ? picker.component.offset() : picker.element.offset(), $window = $(window), placeposition; picker.width = picker.component ? picker.component.outerwidth() : picker.element.outerwidth(); offset.top = offset.top + picker.element.outerheight(); if (picker.options.direction === 'up') { placeposition = 'top'; } else if (picker.options.direction === 'bottom') { placeposition = 'bottom'; } else if (picker.options.direction === 'auto') { if (offset.top + picker.widget.height() > $window.height() + $window.scrolltop() && picker.widget.height() + picker.element.outerheight() < offset.top) { placeposition = 'top'; } else { placeposition = 'bottom'; } } if (placeposition === 'top') { //ace offset.bottom = math.max($window.height() , document.documentelement.scrollheight || document.body.scrollheight) - offset.top + picker.element.outerheight() + 3; picker.widget.addclass('top').removeclass('bottom'); } else { offset.top += 1; picker.widget.addclass('bottom').removeclass('top'); } if (picker.options.width !== undefined) { picker.widget.width(picker.options.width); } if (picker.options.orientation === 'left') { picker.widget.addclass('left-oriented'); offset.left = offset.left - picker.widget.width() + 20; } if (isinfixed()) { position = 'fixed'; offset.top -= $window.scrolltop(); offset.left -= $window.scrollleft(); } if ($window.width() < offset.left + picker.widget.outerwidth()) { offset.right = $window.width() - offset.left - picker.width; offset.left = 'auto'; picker.widget.addclass('pull-right'); } else { offset.right = 'auto'; picker.widget.removeclass('pull-right'); } if (placeposition === 'top') { picker.widget.css({ position: position, bottom: offset.bottom, top: 'auto', left: offset.left, right: offset.right }); } else { picker.widget.css({ position: position, top: offset.top, bottom: 'auto', left: offset.left, right: offset.right }); } }, notifychange = function (olddate, eventtype) { if (moment(picker.date).issame(moment(olddate)) && !errored) { return; } errored = false; picker.element.trigger({ type: 'dp.change', date: moment(picker.date), olddate: moment(olddate) }); if (eventtype !== 'change') { picker.element.change(); } }, notifyerror = function (date) { errored = true; picker.element.trigger({ type: 'dp.error', date: moment(date, picker.format, picker.options.usestrict) }); }, update = function (newdate) { moment.locale(picker.options.language); var datestr = newdate; if (!datestr) { datestr = getpickerinput().val(); if (datestr) { picker.date = moment(datestr, picker.format, picker.options.usestrict); } if (!picker.date) { picker.date = moment(); } } picker.viewdate = moment(picker.date).startof('month'); filldate(); filltime(); }, filldow = function () { moment.locale(picker.options.language); var html = $(''), weekdaysmin = moment.weekdaysmin(), i; if (picker.options.calendarweeks === true) { html.append('#'); } if (moment().localedata()._week.dow === 0) { // starts on sunday for (i = 0; i < 7; i++) { html.append('' + weekdaysmin[i] + ''); } } else { for (i = 1; i < 8; i++) { if (i === 7) { html.append('' + weekdaysmin[0] + ''); } else { html.append('' + weekdaysmin[i] + ''); } } } picker.widget.find('.datepicker-days thead').append(html); }, fillmonths = function () { moment.locale(picker.options.language); var html = '', i, monthsshort = moment.monthsshort(); for (i = 0; i < 12; i++) { html += '' + monthsshort[i] + ''; } picker.widget.find('.datepicker-months td').append(html); }, filldate = function () { if (!picker.options.pickdate) { return; } moment.locale(picker.options.language); var year = picker.viewdate.year(), month = picker.viewdate.month(), startyear = picker.options.mindate.year(), startmonth = picker.options.mindate.month(), endyear = picker.options.maxdate.year(), endmonth = picker.options.maxdate.month(), currentdate, prevmonth, nextmonth, html = [], row, clsname, i, days, yearcont, currentyear, months = moment.months(); picker.widget.find('.datepicker-days').find('.disabled').removeclass('disabled'); picker.widget.find('.datepicker-months').find('.disabled').removeclass('disabled'); picker.widget.find('.datepicker-years').find('.disabled').removeclass('disabled'); picker.widget.find('.datepicker-days th:eq(1)').text( months[month] + ' ' + year); prevmonth = moment(picker.viewdate, picker.format, picker.options.usestrict).subtract(1, 'months'); days = prevmonth.daysinmonth(); prevmonth.date(days).startof('week'); if ((year === startyear && month <= startmonth) || year < startyear) { picker.widget.find('.datepicker-days th:eq(0)').addclass('disabled'); } if ((year === endyear && month >= endmonth) || year > endyear) { picker.widget.find('.datepicker-days th:eq(2)').addclass('disabled'); } nextmonth = moment(prevmonth).add(42, 'd'); while (prevmonth.isbefore(nextmonth)) { if (prevmonth.weekday() === moment().startof('week').weekday()) { row = $(''); html.push(row); if (picker.options.calendarweeks === true) { row.append('' + prevmonth.week() + ''); } } clsname = ''; if (prevmonth.year() < year || (prevmonth.year() === year && prevmonth.month() < month)) { clsname += ' old'; } else if (prevmonth.year() > year || (prevmonth.year() === year && prevmonth.month() > month)) { clsname += ' new'; } if (prevmonth.issame(moment({y: picker.date.year(), m: picker.date.month(), d: picker.date.date()}))) { clsname += ' active'; } if (isindisabledates(prevmonth, 'day') || !isinenabledates(prevmonth)) { clsname += ' disabled'; } if (picker.options.showtoday === true) { if (prevmonth.issame(moment(), 'day')) { clsname += ' today'; } } if (picker.options.daysofweekdisabled) { for (i = 0; i < picker.options.daysofweekdisabled.length; i++) { if (prevmonth.day() === picker.options.daysofweekdisabled[i]) { clsname += ' disabled'; break; } } } row.append('' + prevmonth.date() + ''); currentdate = prevmonth.date(); prevmonth.add(1, 'd'); if (currentdate === prevmonth.date()) { prevmonth.add(1, 'd'); } } picker.widget.find('.datepicker-days tbody').empty().append(html); currentyear = picker.date.year(); months = picker.widget.find('.datepicker-months').find('th:eq(1)').text(year).end().find('span').removeclass('active'); if (currentyear === year) { months.eq(picker.date.month()).addclass('active'); } if (year - 1 < startyear) { picker.widget.find('.datepicker-months th:eq(0)').addclass('disabled'); } if (year + 1 > endyear) { picker.widget.find('.datepicker-months th:eq(2)').addclass('disabled'); } for (i = 0; i < 12; i++) { if ((year === startyear && startmonth > i) || (year < startyear)) { $(months[i]).addclass('disabled'); } else if ((year === endyear && endmonth < i) || (year > endyear)) { $(months[i]).addclass('disabled'); } } html = ''; year = parseint(year / 10, 10) * 10; yearcont = picker.widget.find('.datepicker-years').find( 'th:eq(1)').text(year + '-' + (year + 9)).parents('table').find('td'); picker.widget.find('.datepicker-years').find('th').removeclass('disabled'); if (startyear > year) { picker.widget.find('.datepicker-years').find('th:eq(0)').addclass('disabled'); } if (endyear < year + 9) { picker.widget.find('.datepicker-years').find('th:eq(2)').addclass('disabled'); } year -= 1; for (i = -1; i < 11; i++) { html += '' + year + ''; year += 1; } yearcont.html(html); }, fillhours = function () { moment.locale(picker.options.language); var table = picker.widget.find('.timepicker .timepicker-hours table'), html = '', current, i, j; table.parent().hide(); if (picker.use24hours) { current = 0; for (i = 0; i < 6; i += 1) { html += ''; for (j = 0; j < 4; j += 1) { html += '' + padleft(current.tostring()) + ''; current++; } html += ''; } } else { current = 1; for (i = 0; i < 3; i += 1) { html += ''; for (j = 0; j < 4; j += 1) { html += '' + padleft(current.tostring()) + ''; current++; } html += ''; } } table.html(html); }, fillminutes = function () { var table = picker.widget.find('.timepicker .timepicker-minutes table'), html = '', current = 0, i, j, step = picker.options.minutestepping; table.parent().hide(); if (step === 1) { step = 5; } for (i = 0; i < math.ceil(60 / step / 4) ; i++) { html += ''; for (j = 0; j < 4; j += 1) { if (current < 60) { html += '' + padleft(current.tostring()) + ''; current += step; } else { html += ''; } } html += ''; } table.html(html); }, fillseconds = function () { var table = picker.widget.find('.timepicker .timepicker-seconds table'), html = '', current = 0, i, j; table.parent().hide(); for (i = 0; i < 3; i++) { html += ''; for (j = 0; j < 4; j += 1) { html += '' + padleft(current.tostring()) + ''; current += 5; } html += ''; } table.html(html); }, filltime = function () { if (!picker.date) { return; } var timecomponents = picker.widget.find('.timepicker span[data-time-component]'), hour = picker.date.hours(), period = picker.date.format('a'); if (!picker.use24hours) { if (hour === 0) { hour = 12; } else if (hour !== 12) { hour = hour % 12; } picker.widget.find('.timepicker [data-action=toggleperiod]').text(period); } timecomponents.filter('[data-time-component=hours]').text(padleft(hour)); timecomponents.filter('[data-time-component=minutes]').text(padleft(picker.date.minutes())); timecomponents.filter('[data-time-component=seconds]').text(padleft(picker.date.second())); }, click = function (e) { e.stoppropagation(); e.preventdefault(); picker.unset = false; var target = $(e.target).closest('span, td, th'), month, year, step, day, olddate = moment(picker.date); if (target.length === 1) { if (!target.is('.disabled')) { switch (target[0].nodename.tolowercase()) { case 'th': switch (target[0].classname) { case 'picker-switch': showmode(1); break; case 'prev': case 'next': step = dpglobal.modes[picker.viewmode].navstep; if (target[0].classname === 'prev') { step = step * -1; } picker.viewdate.add(step, dpglobal.modes[picker.viewmode].navfnc); filldate(); break; } break; case 'span': if (target.is('.month')) { month = target.parent().find('span').index(target); picker.viewdate.month(month); } else { year = parseint(target.text(), 10) || 0; picker.viewdate.year(year); } if (picker.viewmode === picker.minviewmode) { picker.date = moment({ y: picker.viewdate.year(), m: picker.viewdate.month(), d: picker.viewdate.date(), h: picker.date.hours(), m: picker.date.minutes(), s: picker.date.seconds() }); set(); notifychange(olddate, e.type); } showmode(-1); filldate(); break; case 'td': if (target.is('.day')) { day = parseint(target.text(), 10) || 1; month = picker.viewdate.month(); year = picker.viewdate.year(); if (target.is('.old')) { if (month === 0) { month = 11; year -= 1; } else { month -= 1; } } else if (target.is('.new')) { if (month === 11) { month = 0; year += 1; } else { month += 1; } } picker.date = moment({ y: year, m: month, d: day, h: picker.date.hours(), m: picker.date.minutes(), s: picker.date.seconds() } ); picker.viewdate = moment({ y: year, m: month, d: math.min(28, day) }); filldate(); set(); notifychange(olddate, e.type); } break; } } } }, actions = { incrementhours: function () { checkdate('add', 'hours', 1); }, incrementminutes: function () { checkdate('add', 'minutes', picker.options.minutestepping); }, incrementseconds: function () { checkdate('add', 'seconds', 1); }, decrementhours: function () { checkdate('subtract', 'hours', 1); }, decrementminutes: function () { checkdate('subtract', 'minutes', picker.options.minutestepping); }, decrementseconds: function () { checkdate('subtract', 'seconds', 1); }, toggleperiod: function () { var hour = picker.date.hours(); if (hour >= 12) { hour -= 12; } else { hour += 12; } picker.date.hours(hour); }, showpicker: function () { picker.widget.find('.timepicker > div:not(.timepicker-picker)').hide(); picker.widget.find('.timepicker .timepicker-picker').show(); }, showhours: function () { picker.widget.find('.timepicker .timepicker-picker').hide(); picker.widget.find('.timepicker .timepicker-hours').show(); }, showminutes: function () { picker.widget.find('.timepicker .timepicker-picker').hide(); picker.widget.find('.timepicker .timepicker-minutes').show(); }, showseconds: function () { picker.widget.find('.timepicker .timepicker-picker').hide(); picker.widget.find('.timepicker .timepicker-seconds').show(); }, selecthour: function (e) { var hour = parseint($(e.target).text(), 10); if (!picker.use24hours) { if (picker.date.hours() >= 12) { if (hour !== 12) { hour += 12; } } else { if (hour === 12) { hour = 0; } } } picker.date.hours(hour); actions.showpicker.call(picker); }, selectminute: function (e) { picker.date.minutes(parseint($(e.target).text(), 10)); actions.showpicker.call(picker); }, selectsecond: function (e) { picker.date.seconds(parseint($(e.target).text(), 10)); actions.showpicker.call(picker); } }, doaction = function (e) { var olddate = moment(picker.date), action = $(e.currenttarget).data('action'), rv = actions[action].apply(picker, arguments); stopevent(e); if (!picker.date) { picker.date = moment({y: 1970}); } set(); filltime(); notifychange(olddate, e.type); return rv; }, stopevent = function (e) { e.stoppropagation(); e.preventdefault(); }, keydown = function (e) { if (e.keycode === 27) { // allow escape to hide picker picker.hide(); } }, change = function (e) { moment.locale(picker.options.language); var input = $(e.target), olddate = moment(picker.date), newdate = moment(input.val(), picker.format, picker.options.usestrict); if (newdate.isvalid() && !isindisabledates(newdate) && isinenabledates(newdate)) { update(); picker.setvalue(newdate); notifychange(olddate, e.type); set(); } else { picker.viewdate = olddate; picker.unset = true; notifychange(olddate, e.type); notifyerror(newdate); } }, showmode = function (dir) { if (dir) { picker.viewmode = math.max(picker.minviewmode, math.min(2, picker.viewmode + dir)); } picker.widget.find('.datepicker > div').hide().filter('.datepicker-' + dpglobal.modes[picker.viewmode].clsname).show(); }, attachdatepickerevents = function () { var $this, $parent, expanded, closed, collapsedata; picker.widget.on('click', '.datepicker *', $.proxy(click, this)); // this handles date picker clicks picker.widget.on('click', '[data-action]', $.proxy(doaction, this)); // this handles time picker clicks picker.widget.on('mousedown', $.proxy(stopevent, this)); picker.element.on('keydown', $.proxy(keydown, this)); if (picker.options.pickdate && picker.options.picktime) { picker.widget.on('click.togglepicker', '.accordion-toggle', function (e) { e.stoppropagation(); $this = $(this); $parent = $this.closest('ul'); expanded = $parent.find('.in'); closed = $parent.find('.collapse:not(.in)'); if (expanded && expanded.length) { collapsedata = expanded.data('collapse'); if (collapsedata && collapsedata.transitioning) { return; } expanded.collapse('hide'); closed.collapse('show'); $this.find('span').toggleclass(picker.options.icons.time + ' ' + picker.options.icons.date); if (picker.component) { picker.component.find('span').toggleclass(picker.options.icons.time + ' ' + picker.options.icons.date); } } }); } if (picker.isinput) { picker.element.on({ 'click': $.proxy(picker.show, this), 'focus': $.proxy(picker.show, this), 'change': $.proxy(change, this), 'blur': $.proxy(picker.hide, this) }); } else { picker.element.on({ 'change': $.proxy(change, this) }, 'input'); if (picker.component) { picker.component.on('click', $.proxy(picker.show, this)); picker.component.on('mousedown', $.proxy(stopevent, this)); } else { picker.element.on('click', $.proxy(picker.show, this)); } } }, attachdatepickerglobalevents = function () { $(window).on( 'resize.datetimepicker' + picker.id, $.proxy(place, this)); if (!picker.isinput) { $(document).on( 'mousedown.datetimepicker' + picker.id, $.proxy(picker.hide, this)); } }, detachdatepickerevents = function () { picker.widget.off('click', '.datepicker *', picker.click); picker.widget.off('click', '[data-action]'); picker.widget.off('mousedown', picker.stopevent); if (picker.options.pickdate && picker.options.picktime) { picker.widget.off('click.togglepicker'); } if (picker.isinput) { picker.element.off({ 'focus': picker.show, 'change': change, 'click': picker.show, 'blur' : picker.hide }); } else { picker.element.off({ 'change': change }, 'input'); if (picker.component) { picker.component.off('click', picker.show); picker.component.off('mousedown', picker.stopevent); } else { picker.element.off('click', picker.show); } } }, detachdatepickerglobalevents = function () { $(window).off('resize.datetimepicker' + picker.id); if (!picker.isinput) { $(document).off('mousedown.datetimepicker' + picker.id); } }, isinfixed = function () { if (picker.element) { var parents = picker.element.parents(), infixed = false, i; for (i = 0; i < parents.length; i++) { if ($(parents[i]).css('position') === 'fixed') { infixed = true; break; } } return infixed; } else { return false; } }, set = function () { moment.locale(picker.options.language); var formatted = ''; if (!picker.unset) { formatted = moment(picker.date).format(picker.format); } getpickerinput().val(formatted); picker.element.data('date', formatted); if (!picker.options.picktime) { picker.hide(); } }, checkdate = function (direction, unit, amount) { moment.locale(picker.options.language); var newdate; if (direction === 'add') { newdate = moment(picker.date); if (newdate.hours() === 23) { newdate.add(amount, unit); } newdate.add(amount, unit); } else { newdate = moment(picker.date).subtract(amount, unit); } if (isindisabledates(moment(newdate.subtract(amount, unit))) || isindisabledates(newdate)) { notifyerror(newdate.format(picker.format)); return; } if (direction === 'add') { picker.date.add(amount, unit); } else { picker.date.subtract(amount, unit); } picker.unset = false; }, isindisabledates = function (date, timeunit) { moment.locale(picker.options.language); var maxdate = moment(picker.options.maxdate, picker.format, picker.options.usestrict), mindate = moment(picker.options.mindate, picker.format, picker.options.usestrict); if (timeunit) { maxdate = maxdate.endof(timeunit); mindate = mindate.startof(timeunit); } if (date.isafter(maxdate) || date.isbefore(mindate)) { return true; } if (picker.options.disableddates === false) { return false; } return picker.options.disableddates[date.format('yyyy-mm-dd')] === true; }, isinenabledates = function (date) { moment.locale(picker.options.language); if (picker.options.enableddates === false) { return true; } return picker.options.enableddates[date.format('yyyy-mm-dd')] === true; }, indexgivendates = function (givendatesarray) { // store given enableddates and disableddates as keys. // this way we can check their existence in o(1) time instead of looping through whole array. // (for example: picker.options.enableddates['2014-02-27'] === true) var givendatesindexed = {}, givendatescount = 0, i; for (i = 0; i < givendatesarray.length; i++) { if (moment.ismoment(givendatesarray[i]) || givendatesarray[i] instanceof date) { ddate = moment(givendatesarray[i]); } else { ddate = moment(givendatesarray[i], picker.format, picker.options.usestrict); } if (ddate.isvalid()) { givendatesindexed[ddate.format('yyyy-mm-dd')] = true; givendatescount++; } } if (givendatescount > 0) { return givendatesindexed; } return false; }, padleft = function (string) { string = string.tostring(); if (string.length >= 2) { return string; } return '0' + string; }, gettemplate = function () { var headtemplate = '' + '' + '‹›' + '' + '', conttemplate = '', template = '
' + '' + headtemplate + '
' + '
' + '
' + '' + headtemplate + conttemplate + '
' + '
' + '
' + '' + headtemplate + conttemplate + '
' + '
', ret = ''; if (picker.options.pickdate && picker.options.picktime) { ret = ''; return ret; } if (picker.options.picktime) { return ( '' ); } return ( '' ); }, dpglobal = { modes: [ { clsname: 'days', navfnc: 'month', navstep: 1 }, { clsname: 'months', navfnc: 'year', navstep: 1 }, { clsname: 'years', navfnc: 'year', navstep: 10 } ] }, tpglobal = { hourtemplate: '', minutetemplate: '', secondtemplate: '' }; tpglobal.gettemplate = function () { return ( '
' + '' + '' + '' + '' + '' + (picker.options.useseconds ? '' : '') + (picker.use24hours ? '' : '') + '' + '' + ' ' + '' + ' ' + (picker.options.useseconds ? '' : '') + (picker.use24hours ? '' : '' + '') + '' + '' + '' + '' + '' + (picker.options.useseconds ? '' : '') + (picker.use24hours ? '' : '') + '' + '
' + (picker.options.useminutes ? '' : '') + '
' + tpglobal.hourtemplate + ':' + (picker.options.useminutes ? tpglobal.minutetemplate : '00') + ':' + tpglobal.secondtemplate + '
' + (picker.options.useminutes ? '' : '') + '
' + '
' + '
' + '
' + '
' + '
' + '
' + '
' + (picker.options.useseconds ? '
' : '') ); }; picker.destroy = function () { detachdatepickerevents(); detachdatepickerglobalevents(); picker.widget.remove(); picker.element.removedata('datetimepicker'); if (picker.component) { picker.component.removedata('datetimepicker'); } }; picker.show = function (e) { if (getpickerinput().prop('disabled')) { return; } if (picker.options.usecurrent) { if (getpickerinput().val() === '') { if (picker.options.minutestepping !== 1) { var mdate = moment(), rinterval = picker.options.minutestepping; mdate.minutes((math.round(mdate.minutes() / rinterval) * rinterval) % 60).seconds(0); picker.setvalue(mdate.format(picker.format)); } else { picker.setvalue(moment().format(picker.format)); } notifychange('', e.type); } } // if this is a click event on the input field and picker is already open don't hide it if (e && e.type === 'click' && picker.isinput && picker.widget.hasclass('picker-open')) { return; } if (picker.widget.hasclass('picker-open')) { picker.widget.hide(); picker.widget.removeclass('picker-open'); } else { picker.widget.show(); picker.widget.addclass('picker-open'); } picker.height = picker.component ? picker.component.outerheight() : picker.element.outerheight(); place(); picker.element.trigger({ type: 'dp.show', date: moment(picker.date) }); attachdatepickerglobalevents(); if (e) { stopevent(e); } }; picker.disable = function () { var input = getpickerinput(); if (input.prop('disabled')) { return; } input.prop('disabled', true); detachdatepickerevents(); }; picker.enable = function () { var input = getpickerinput(); if (!input.prop('disabled')) { return; } input.prop('disabled', false); attachdatepickerevents(); }; picker.hide = function () { // ignore event if in the middle of a picker transition var collapse = picker.widget.find('.collapse'), i, collapsedata; for (i = 0; i < collapse.length; i++) { collapsedata = collapse.eq(i).data('collapse'); if (collapsedata && collapsedata.transitioning) { return; } } picker.widget.hide(); picker.widget.removeclass('picker-open'); picker.viewmode = picker.startviewmode; showmode(); picker.element.trigger({ type: 'dp.hide', date: moment(picker.date) }); detachdatepickerglobalevents(); }; picker.setvalue = function (newdate) { moment.locale(picker.options.language); if (!newdate) { picker.unset = true; set(); } else { picker.unset = false; } if (!moment.ismoment(newdate)) { newdate = (newdate instanceof date) ? moment(newdate) : moment(newdate, picker.format, picker.options.usestrict); } else { newdate = newdate.locale(picker.options.language); } if (newdate.isvalid()) { picker.date = newdate; set(); picker.viewdate = moment({y: picker.date.year(), m: picker.date.month()}); filldate(); filltime(); } else { notifyerror(newdate); } }; picker.getdate = function () { if (picker.unset) { return null; } return moment(picker.date); }; picker.setdate = function (date) { var olddate = moment(picker.date); if (!date) { picker.setvalue(null); } else { picker.setvalue(date); } notifychange(olddate, 'function'); }; picker.setdisableddates = function (dates) { picker.options.disableddates = indexgivendates(dates); if (picker.viewdate) { update(); } }; picker.setenableddates = function (dates) { picker.options.enableddates = indexgivendates(dates); if (picker.viewdate) { update(); } }; picker.setmaxdate = function (date) { if (date === undefined) { return; } if (moment.ismoment(date) || date instanceof date) { picker.options.maxdate = moment(date); } else { picker.options.maxdate = moment(date, picker.format, picker.options.usestrict); } if (picker.viewdate) { update(); } }; picker.setmindate = function (date) { if (date === undefined) { return; } if (moment.ismoment(date) || date instanceof date) { picker.options.mindate = moment(date); } else { picker.options.mindate = moment(date, picker.format, picker.options.usestrict); } if (picker.viewdate) { update(); } }; init(); }; $.fn.datetimepicker = function (options) { return this.each(function () { var $this = $(this), data = $this.data('datetimepicker'); if (!data) { $this.data('datetimepicker', new datetimepicker(this, options)); } }); }; $.fn.datetimepicker.defaults = { format: false, pickdate: true, picktime: true, useminutes: true, useseconds: false, usecurrent: true, calendarweeks: false, minutestepping: 1, mindate: moment({y: 1900}), maxdate: moment().add(100, 'y'), showtoday: true, collapse: true, language: moment.locale(), defaultdate: '', disableddates: false, enableddates: false, icons: {}, usestrict: false, direction: 'auto', sidebyside: false, daysofweekdisabled: [], widgetparent: false }; }));