diff --git a/src/js/tempusdominus-bootstrap-4.js b/src/js/tempusdominus-bootstrap-4.js index 641168c..e3bc760 100644 --- a/src/js/tempusdominus-bootstrap-4.js +++ b/src/js/tempusdominus-bootstrap-4.js @@ -2,1286 +2,1287 @@ /* global DateTimePicker */ /* global feather */ const TempusDominusBootstrap4 = ($ => { // eslint-disable-line no-unused-vars - // ReSharper disable once InconsistentNaming - const JQUERY_NO_CONFLICT = $.fn[DateTimePicker.NAME], - verticalModes = ['top', 'bottom', 'auto'], - horizontalModes = ['left', 'right', 'auto'], - toolbarPlacements = ['default', 'top', 'bottom'], - getSelectorFromElement = function ($element) { - let selector = $element.data('target'), - $selector; - - if (!selector) { - selector = $element.attr('href') || ''; - selector = /^#[a-z]/i.test(selector) ? selector : null; - } - $selector = $(selector); - if ($selector.length === 0) { - return $element; - } - - if (!$selector.data(DateTimePicker.DATA_KEY)) { - $.extend({}, $selector.data(), $(this).data()); - } - - return $selector; - }; - - // ReSharper disable once InconsistentNaming - class TempusDominusBootstrap4 extends DateTimePicker { - constructor(element, options) { - super(element, options); - this._init(); - } - - _init() { - if (this._element.hasClass('input-group')) { - const datepickerButton = this._element.find('.datepickerbutton'); - if (datepickerButton.length === 0) { - this.component = this._element.find('[data-toggle="datetimepicker"]'); - } else { - this.component = datepickerButton; - } - } - } - - _iconTag(iconName) { - if (typeof feather !== 'undefined' && this._useFeatherIcons() && feather.icons[iconName]) { - return $('').html(feather.icons[iconName].toSvg()); - } - else { - return $('').addClass(iconName); - } - } - - _getDatePickerTemplate() { - const headTemplate = $('').append($('').append($('').addClass('prev').attr('data-action', 'previous').append(this._iconTag(this._options.icons.previous))).append($('').addClass('picker-switch').attr('data-action', 'pickerSwitch').attr('colspan', `${this._options.calendarWeeks ? '6' : '5'}`)).append($('').addClass('next').attr('data-action', 'next').append(this._iconTag(this._options.icons.next)))), - contTemplate = $('').append($('').append($('').attr('colspan', `${this._options.calendarWeeks ? '8' : '7'}`))); - - return [$('
').addClass('datepicker-days').append($('').addClass('table table-sm').append(headTemplate).append($(''))), $('
').addClass('datepicker-months').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('
').addClass('datepicker-years').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('
').addClass('datepicker-decades').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone()))]; - } - - _getTimePickerMainTemplate() { - const topRow = $(''), - middleRow = $(''), - bottomRow = $(''); - - if (this._isEnabled('h')) { - topRow.append($('
').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.incrementHour - }).addClass('btn').attr('data-action', 'incrementHours').append(this._iconTag(this._options.icons.up)))); - middleRow.append($('').append($('').addClass('timepicker-hour').attr({ - 'data-time-component': 'hours', - 'title': this._options.tooltips.pickHour - }).attr('data-action', 'showHours'))); - bottomRow.append($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.decrementHour - }).addClass('btn').attr('data-action', 'decrementHours').append(this._iconTag(this._options.icons.down)))); - } - if (this._isEnabled('m')) { - if (this._isEnabled('h')) { - topRow.append($('').addClass('separator')); - middleRow.append($('').addClass('separator').html(':')); - bottomRow.append($('').addClass('separator')); - } - topRow.append($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.incrementMinute - }).addClass('btn').attr('data-action', 'incrementMinutes').append(this._iconTag(this._options.icons.up)))); - middleRow.append($('').append($('').addClass('timepicker-minute').attr({ - 'data-time-component': 'minutes', - 'title': this._options.tooltips.pickMinute - }).attr('data-action', 'showMinutes'))); - bottomRow.append($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.decrementMinute - }).addClass('btn').attr('data-action', 'decrementMinutes').append(this._iconTag(this._options.icons.down)))); - } - if (this._isEnabled('s')) { - if (this._isEnabled('m')) { - topRow.append($('').addClass('separator')); - middleRow.append($('').addClass('separator').html(':')); - bottomRow.append($('').addClass('separator')); - } - topRow.append($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.incrementSecond - }).addClass('btn').attr('data-action', 'incrementSeconds').append(this._iconTag(this._options.icons.up)))); - middleRow.append($('').append($('').addClass('timepicker-second').attr({ - 'data-time-component': 'seconds', - 'title': this._options.tooltips.pickSecond - }).attr('data-action', 'showSeconds'))); - bottomRow.append($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'title': this._options.tooltips.decrementSecond - }).addClass('btn').attr('data-action', 'decrementSeconds').append(this._iconTag(this._options.icons.down)))); - } - - if (!this.use24Hours) { - topRow.append($('').addClass('separator')); - middleRow.append($('').append($('').addClass('separator')); - } - - return $('
').addClass('timepicker-picker').append($('').addClass('table-condensed').append([topRow, middleRow, bottomRow])); - } - - _getTimePickerTemplate() { - const hoursView = $('
').addClass('timepicker-hours').append($('
').addClass('table-condensed')), - minutesView = $('
').addClass('timepicker-minutes').append($('
').addClass('table-condensed')), - secondsView = $('
').addClass('timepicker-seconds').append($('
').addClass('table-condensed')), - ret = [this._getTimePickerMainTemplate()]; - - if (this._isEnabled('h')) { - ret.push(hoursView); - } - if (this._isEnabled('m')) { - ret.push(minutesView); - } - if (this._isEnabled('s')) { - ret.push(secondsView); - } - - return ret; - } - - _getToolbar() { - const row = []; - if (this._options.buttons.showToday) { - row.push($('
').append($('').attr({ - href: '#', - tabindex: '-1', - 'data-action': 'today', - 'title': this._options.tooltips.today - }).append(this._iconTag(this._options.icons.today)))); - } - if (!this._options.sideBySide && this._options.collapse && this._hasDate() && this._hasTime()) { - let title, icon; - if (this._options.viewMode === 'times') { - title = this._options.tooltips.selectDate; - icon = this._options.icons.date; - } else { - title = this._options.tooltips.selectTime; - icon = this._options.icons.time; - } - row.push($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'data-action': 'togglePicker', - 'title': title - }).append(this._iconTag(icon)))); - } - if (this._options.buttons.showClear) { - row.push($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'data-action': 'clear', - 'title': this._options.tooltips.clear - }).append(this._iconTag(this._options.icons.clear)))); - } - if (this._options.buttons.showClose) { - row.push($('').append($('').attr({ - href: '#', - tabindex: '-1', - 'data-action': 'close', - 'title': this._options.tooltips.close - }).append(this._iconTag(this._options.icons.close)))); - } - return row.length === 0 ? '' : $('').addClass('table-condensed').append($('').append($('').append(row))); - } - - _getTemplate() { - const template = $('
').addClass(( - `bootstrap-datetimepicker-widget dropdown-menu ${this._options.calendarWeeks ? 'tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks' : ''} ` - + - `${this._useFeatherIcons() ? 'tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons' : ''} ` - ).trim()), - dateView = $('
').addClass('datepicker').append(this._getDatePickerTemplate()), - timeView = $('
').addClass('timepicker').append(this._getTimePickerTemplate()), - content = $('
    ').addClass('list-unstyled'), - toolbar = $('
  • ').addClass(( - `picker-switch${this._options.collapse ? ' accordion-toggle' : ''} ` + - `${this._useFeatherIcons() ? 'picker-switch-with-feathers-icons' : ''}` - ).trim()).append(this._getToolbar()); - - if (this._options.inline) { - template.removeClass('dropdown-menu'); - } - - if (this.use24Hours) { - template.addClass('usetwentyfour'); - } - if ((this.input !== undefined && this.input.prop('readonly')) || this._options.readonly) { - template.addClass('bootstrap-datetimepicker-widget-readonly'); - } - if (this._isEnabled('s') && !this.use24Hours) { - template.addClass('wider'); - } - - if (this._options.sideBySide && this._hasDate() && this._hasTime()) { - template.addClass('timepicker-sbs'); - if (this._options.toolbarPlacement === 'top') { - template.append(toolbar); - } - template.append($('
    ').addClass('row').append(dateView.addClass('col-md-6')).append(timeView.addClass('col-md-6'))); - if (this._options.toolbarPlacement === 'bottom' || this._options.toolbarPlacement === 'default') { - template.append(toolbar); - } - return template; - } - - if (this._options.toolbarPlacement === 'top') { - content.append(toolbar); - } - if (this._hasDate()) { - content.append($('
  • ').addClass(this._options.collapse && this._hasTime() ? 'collapse' : '') - .addClass((this._options.collapse && this._hasTime() && this._options.viewMode === 'times' ? '' : 'show')) - .append(dateView)); - } - if (this._options.toolbarPlacement === 'default') { - content.append(toolbar); - } - if (this._hasTime()) { - content.append($('
  • ').addClass(this._options.collapse && this._hasDate() ? 'collapse' : '') - .addClass((this._options.collapse && this._hasDate() && this._options.viewMode === 'times' ? 'show' : '')) - .append(timeView)); - } - if (this._options.toolbarPlacement === 'bottom') { - content.append(toolbar); - } - return template.append(content); - } - - _place(e) { - let self = (e && e.data && e.data.picker) || this, vertical = self._options.widgetPositioning.vertical, - horizontal = self._options.widgetPositioning.horizontal, - parent; - const position = (self.component && self.component.length ? self.component : self._element).position(), - offset = (self.component && self.component.length ? self.component : self._element).offset(); - if (self._options.widgetParent) { - parent = self._options.widgetParent.append(self.widget); - } else if (self._element.is('input')) { - parent = self._element.after(self.widget).parent(); - } else if (self._options.inline) { - parent = self._element.append(self.widget); - return; - } else { - parent = self._element; - self._element.children().first().after(self.widget); - } - - // Top and bottom logic - if (vertical === 'auto') { - //noinspection JSValidateTypes - if (offset.top + self.widget.height() * 1.5 >= $(window).height() + $(window).scrollTop() && self.widget.height() + self._element.outerHeight() < offset.top) { - vertical = 'top'; - } else { - vertical = 'bottom'; - } - } - - // Left and right logic - if (horizontal === 'auto') { - if (parent.width() < offset.left + self.widget.outerWidth() / 2 && offset.left + self.widget.outerWidth() > $(window).width()) { - horizontal = 'right'; - } else { - horizontal = 'left'; - } - } - - if (vertical === 'top') { - self.widget.addClass('top').removeClass('bottom'); - } else { - self.widget.addClass('bottom').removeClass('top'); - } - - if (horizontal === 'right') { - self.widget.addClass('float-right'); - } else { - self.widget.removeClass('float-right'); - } - - // find the first parent element that has a relative css positioning - if (parent.css('position') !== 'relative') { - parent = parent.parents().filter(function () { - return $(this).css('position') === 'relative'; - }).first(); - } - - if (parent.length === 0) { - throw new Error('datetimepicker component should be placed within a relative positioned container'); - } - - self.widget.css({ - top: vertical === 'top' ? 'auto' : position.top + self._element.outerHeight() + 'px', - bottom: vertical === 'top' ? parent.outerHeight() - (parent === self._element ? 0 : position.top) + 'px' : 'auto', - left: horizontal === 'left' ? (parent === self._element ? 0 : position.left) + 'px' : 'auto', - right: horizontal === 'left' ? 'auto' : parent.outerWidth() - self._element.outerWidth() - (parent === self._element ? 0 : position.left) + 'px' - }); - } - - _fillDow() { - const row = $('
'), - currentDate = this._viewDate.clone().startOf('w').startOf('d'); - - if (this._options.calendarWeeks === true) { - row.append($(''); - if (this._options.calendarWeeks) { - row.append(``); - } - html.push(row); - } - clsName = ''; - if (currentDate.isBefore(this._viewDate, 'M')) { - clsName += ' old'; - } - if (currentDate.isAfter(this._viewDate, 'M')) { - clsName += ' new'; - } - if (this._options.allowMultidate) { - var index = this._datesFormatted.indexOf(currentDate.format('YYYY-MM-DD')); - if (index !== -1) { - if (currentDate.isSame(this._datesFormatted[index], 'd') && !this.unset) { - clsName += ' active'; - } - } - } else { - if (currentDate.isSame(this._getLastPickedDate(), 'd') && !this.unset) { - clsName += ' active'; - } - } - if (!this._isValid(currentDate, 'd')) { - clsName += ' disabled'; - } - if (currentDate.isSame(this.getMoment(), 'd')) { - clsName += ' today'; - } - if (currentDate.day() === 0 || currentDate.day() === 6) { - clsName += ' weekend'; - } - row.append(``); - currentDate.add(1, 'd'); - } - - $('body').addClass('tempusdominus-bootstrap-datetimepicker-widget-day-click'); - $('body').append('
'); - daysView.find('tbody').empty().append(html); - $('body').find('.tempusdominus-bootstrap-datetimepicker-widget-day-click-glass-panel').remove(); - $('body').removeClass('tempusdominus-bootstrap-datetimepicker-widget-day-click'); - - this._updateMonths(); - - this._updateYears(); - - this._updateDecades(); - } - - _fillHours() { - const table = this.widget.find('.timepicker-hours table'), - currentHour = this._viewDate.clone().startOf('d'), - html = []; - let row = $(''); - - if (this._viewDate.hour() > 11 && !this.use24Hours) { - currentHour.hour(12); - } - while (currentHour.isSame(this._viewDate, 'd') && (this.use24Hours || this._viewDate.hour() < 12 && currentHour.hour() < 12 || this._viewDate.hour() > 11)) { - if (currentHour.hour() % 4 === 0) { - row = $(''); - html.push(row); - } - row.append(``); - currentHour.add(1, 'h'); - } - table.empty().append(html); - } - - _fillMinutes() { - const table = this.widget.find('.timepicker-minutes table'), - currentMinute = this._viewDate.clone().startOf('h'), - html = [], - step = this._options.stepping === 1 ? 5 : this._options.stepping; - let row = $(''); - - while (this._viewDate.isSame(currentMinute, 'h')) { - if (currentMinute.minute() % (step * 4) === 0) { - row = $(''); - html.push(row); - } - row.append(``); - currentMinute.add(step, 'm'); - } - table.empty().append(html); - } - - _fillSeconds() { - const table = this.widget.find('.timepicker-seconds table'), - currentSecond = this._viewDate.clone().startOf('m'), - html = []; - let row = $(''); - - while (this._viewDate.isSame(currentSecond, 'm')) { - if (currentSecond.second() % 20 === 0) { - row = $(''); - html.push(row); - } - row.append(``); - currentSecond.add(5, 's'); - } - - table.empty().append(html); - } - - _fillTime() { - let toggle, newDate; - const timeComponents = this.widget.find('.timepicker span[data-time-component]'), - lastPickedDate = this._getLastPickedDate(); - - if (!this.use24Hours) { - toggle = this.widget.find('.timepicker [data-action=togglePeriod]'); - newDate = lastPickedDate ? lastPickedDate.clone().add(lastPickedDate.hours() >= 12 ? -12 : 12, 'h') : void 0; - - lastPickedDate && toggle.text(lastPickedDate.format('A')); - - if (this._isValid(newDate, 'h')) { - toggle.removeClass('disabled'); - } else { - toggle.addClass('disabled'); - } - } - lastPickedDate && timeComponents.filter('[data-time-component=hours]').text(lastPickedDate.format(`${this.use24Hours ? 'HH' : 'hh'}`)); - lastPickedDate && timeComponents.filter('[data-time-component=minutes]').text(lastPickedDate.format('mm')); - lastPickedDate && timeComponents.filter('[data-time-component=seconds]').text(lastPickedDate.format('ss')); - - this._fillHours(); - this._fillMinutes(); - this._fillSeconds(); - } - - _doAction(e, action) { - let lastPicked = this._getLastPickedDate(); - if ($(e.currentTarget).is('.disabled')) { - return false; - } - action = action || $(e.currentTarget).data('action'); - switch (action) { - case 'next': - { - const navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION; - this._viewDate.add(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, navFnc); - this._fillDate(); - this._viewUpdate(navFnc); - break; - } - case 'previous': - { - const navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION; - this._viewDate.subtract(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, navFnc); - this._fillDate(); - this._viewUpdate(navFnc); - break; - } - case 'pickerSwitch': - this._showMode(1); - break; - case 'selectMonth': - { - const month = $(e.target).closest('tbody').find('span').index($(e.target)); - this._viewDate.month(month); - if (this.currentViewMode === this.MinViewModeNumber) { - this._setValue(lastPicked.clone().year(this._viewDate.year()).month(this._viewDate.month()), this._getLastPickedDateIndex()); - if (!this._options.inline) { - this.hide(); - } - } else { - this._showMode(-1); - this._fillDate(); - } - this._viewUpdate('M'); - break; - } - case 'selectYear': - { - const year = parseInt($(e.target).text(), 10) || 0; - this._viewDate.year(year); - if (this.currentViewMode === this.MinViewModeNumber) { - this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex()); - if (!this._options.inline) { - this.hide(); - } - } else { - this._showMode(-1); - this._fillDate(); - } - this._viewUpdate('YYYY'); - break; - } - case 'selectDecade': - { - const year = parseInt($(e.target).data('selection'), 10) || 0; - this._viewDate.year(year); - if (this.currentViewMode === this.MinViewModeNumber) { - this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex()); - if (!this._options.inline) { - this.hide(); - } - } else { - this._showMode(-1); - this._fillDate(); - } - this._viewUpdate('YYYY'); - break; - } - case 'selectDay': - { - const day = this._viewDate.clone(); - if ($(e.target).is('.old')) { - day.subtract(1, 'M'); - } - if ($(e.target).is('.new')) { - day.add(1, 'M'); - } - - var selectDate = day.date(parseInt($(e.target).text(), 10)), index = 0; - if (this._options.allowMultidate) { - index = this._datesFormatted.indexOf(selectDate.format('YYYY-MM-DD')); - if (index !== -1) { - this._setValue(null, index); //deselect multidate - } else { - this._setValue(selectDate, this._getLastPickedDateIndex() + 1); - } - } else { - this._setValue(selectDate, this._getLastPickedDateIndex()); - } - - if (!this._hasTime() && !this._options.keepOpen && !this._options.inline && !this._options.allowMultidate) { - this.hide(); - } - break; - } - case 'incrementHours': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().add(1, 'h'); - if (this._isValid(newDate, 'h')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'incrementMinutes': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().add(this._options.stepping, 'm'); - if (this._isValid(newDate, 'm')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'incrementSeconds': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().add(1, 's'); - if (this._isValid(newDate, 's')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'decrementHours': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().subtract(1, 'h'); - if (this._isValid(newDate, 'h')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'decrementMinutes': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().subtract(this._options.stepping, 'm'); - if (this._isValid(newDate, 'm')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'decrementSeconds': - { - if (!lastPicked) { - break; - } - const newDate = lastPicked.clone().subtract(1, 's'); - if (this._isValid(newDate, 's')) { - if (this._getLastPickedDateIndex() < 0) { - this.date(newDate); - } - this._setValue(newDate, this._getLastPickedDateIndex()); - } - break; - } - case 'togglePeriod': - { - this._setValue(lastPicked.clone().add(lastPicked.hours() >= 12 ? -12 : 12, 'h'), this._getLastPickedDateIndex()); - break; - } - case 'togglePicker': - { - const $this = $(e.target), - $link = $this.closest('a'), - $parent = $this.closest('ul'), - expanded = $parent.find('.show'), - closed = $parent.find('.collapse:not(.show)'), - $span = $this.is('span') ? $this : $this.find('span'); - let collapseData, inactiveIcon, iconTest; - - if (expanded && expanded.length) { - collapseData = expanded.data('collapse'); - if (collapseData && collapseData.transitioning) { - return true; - } - 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('show'); - closed.addClass('show'); - } - - if (this._useFeatherIcons()) { - $link.toggleClass(this._options.icons.time + ' ' + this._options.icons.date); - inactiveIcon = ($link.hasClass(this._options.icons.time)) ? this._options.icons.date : this._options.icons.time; - $link.html(this._iconTag(inactiveIcon)); - } - else { - $span.toggleClass(this._options.icons.time + ' ' + this._options.icons.date); - } - - if (this._useFeatherIcons()) { - iconTest = $link.hasClass(this._options.icons.date); - } - else { - iconTest = $span.hasClass(this._options.icons.date); - } - - if (iconTest) { - $link.attr('title', this._options.tooltips.selectDate); - } else { - $link.attr('title', this._options.tooltips.selectTime); - } - } - } - break; - case 'showPicker': - this.widget.find('.timepicker > div:not(.timepicker-picker)').hide(); - this.widget.find('.timepicker .timepicker-picker').show(); - break; - case 'showHours': - this.widget.find('.timepicker .timepicker-picker').hide(); - this.widget.find('.timepicker .timepicker-hours').show(); - break; - case 'showMinutes': - this.widget.find('.timepicker .timepicker-picker').hide(); - this.widget.find('.timepicker .timepicker-minutes').show(); - break; - case 'showSeconds': - this.widget.find('.timepicker .timepicker-picker').hide(); - this.widget.find('.timepicker .timepicker-seconds').show(); - break; - case 'selectHour': - { - let hour = parseInt($(e.target).text(), 10); - - if (!this.use24Hours) { - if (lastPicked.hours() >= 12) { - if (hour !== 12) { - hour += 12; - } - } else { - if (hour === 12) { - hour = 0; - } - } - } - this._setValue(lastPicked.clone().hours(hour), this._getLastPickedDateIndex()); - if (!this._isEnabled('a') && !this._isEnabled('m') && !this._options.keepOpen && !this._options.inline) { - this.hide(); - } - else { - this._doAction(e, 'showPicker'); - } - break; - } - case 'selectMinute': - this._setValue(lastPicked.clone().minutes(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex()); - if (!this._isEnabled('a') && !this._isEnabled('s') && !this._options.keepOpen && !this._options.inline) { - this.hide(); - } - else { - this._doAction(e, 'showPicker'); - } - break; - case 'selectSecond': - this._setValue(lastPicked.clone().seconds(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex()); - if (!this._isEnabled('a') && !this._options.keepOpen && !this._options.inline) { - this.hide(); - } - else { - this._doAction(e, 'showPicker'); - } - break; - case 'clear': - this.clear(); - break; - case 'close': - this.hide(); - break; - case 'today': - { - const todaysDate = this.getMoment(); - if (this._isValid(todaysDate, 'd')) { - this._setValue(todaysDate, this._getLastPickedDateIndex()); - } - break; - } - } - return false; - } - - //public - hide() { - let transitioning = false; - if (!this.widget) { - return; - } - // Ignore event if in the middle of a picker transition - this.widget.find('.collapse').each(function () { - const collapseData = $(this).data('collapse'); - if (collapseData && collapseData.transitioning) { - transitioning = true; - return false; - } - return true; - }); - if (transitioning) { - return; - } - if (this.component && this.component.hasClass('btn')) { - this.component.toggleClass('active'); - } - this.widget.hide(); - - $(window).off('resize', this._place); - this.widget.off('click', '[data-action]'); - this.widget.off('mousedown', false); - - this.widget.remove(); - this.widget = false; - - if (this.input !== undefined && this.input.val() !== undefined && this.input.val().trim().length !== 0) { - this._setValue(this._parseInputDate(this.input.val().trim(), { - isPickerShow: false - }), 0); - } - const lastPickedDate = this._getLastPickedDate(); - this._notifyEvent({ - type: DateTimePicker.Event.HIDE, - date: this.unset ? null : (lastPickedDate ? lastPickedDate.clone() : void 0) - }); - - if (this.input !== undefined) { - this.input.blur(); - } - - this._viewDate = lastPickedDate ? lastPickedDate.clone() : this.getMoment(); - } - - show() { - let currentMoment, shouldUseCurrentIfUnset = false; - const 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 (this.input !== undefined) { - if (this.input.prop('disabled') || !this._options.ignoreReadonly && this.input.prop('readonly') || this.widget) { - return; - } - if (this.input.val() !== undefined && this.input.val().trim().length !== 0) { - this._setValue(this._parseInputDate(this.input.val().trim(), { - isPickerShow: true - }), 0); - } else { - shouldUseCurrentIfUnset = true - } - } - else { - shouldUseCurrentIfUnset = true; - } - - if (shouldUseCurrentIfUnset && this.unset && this._options.useCurrent) { - currentMoment = this.getMoment(); - if (typeof this._options.useCurrent === 'string') { - currentMoment = useCurrentGranularity[this._options.useCurrent](currentMoment); - } - this._setValue(currentMoment, 0); - } - - this.widget = this._getTemplate(); - - this._fillDow(); - this._fillMonths(); - - this.widget.find('.timepicker-hours').hide(); - this.widget.find('.timepicker-minutes').hide(); - this.widget.find('.timepicker-seconds').hide(); - - this._update(); - this._showMode(); - - $(window).on('resize', { picker: this }, this._place); - this.widget.on('click', '[data-action]', $.proxy(this._doAction, this)); // this handles clicks on the widget - this.widget.on('mousedown', false); - - if (this.component && this.component.hasClass('btn')) { - this.component.toggleClass('active'); - } - this._place(); - this.widget.show(); - if (this.input !== undefined && this._options.focusOnShow && !this.input.is(':focus')) { - this.input.focus(); - } - - this._notifyEvent({ - type: DateTimePicker.Event.SHOW - }); - } - - destroy() { - this.hide(); - //todo doc off? - this._element.removeData(DateTimePicker.DATA_KEY); - this._element.removeData('date'); - } - - disable() { - this.hide(); - if (this.component && this.component.hasClass('btn')) { - this.component.addClass('disabled'); - } - if (this.input !== undefined) { - this.input.prop('disabled', true); //todo disable this/comp if input is null - } - } - - enable() { - if (this.component && this.component.hasClass('btn')) { - this.component.removeClass('disabled'); - } - if (this.input !== undefined) { - this.input.prop('disabled', false); //todo enable comp/this if input is null - } - } - - toolbarPlacement(toolbarPlacement) { - if (arguments.length === 0) { - return this._options.toolbarPlacement; - } - - if (typeof toolbarPlacement !== 'string') { - throw new TypeError('toolbarPlacement() expects a string parameter'); - } - if (toolbarPlacements.indexOf(toolbarPlacement) === -1) { - throw new TypeError(`toolbarPlacement() parameter must be one of (${toolbarPlacements.join(', ')}) value`); - } - this._options.toolbarPlacement = toolbarPlacement; - - if (this.widget) { - this.hide(); - this.show(); - } - } - - widgetPositioning(widgetPositioning) { - if (arguments.length === 0) { - return $.extend({}, this._options.widgetPositioning); - } - - if ({}.toString.call(widgetPositioning) !== '[object Object]') { - throw new TypeError('widgetPositioning() expects an object variable'); - } - if (widgetPositioning.horizontal) { - if (typeof widgetPositioning.horizontal !== 'string') { - throw new TypeError('widgetPositioning() horizontal variable must be a string'); - } - widgetPositioning.horizontal = widgetPositioning.horizontal.toLowerCase(); - if (horizontalModes.indexOf(widgetPositioning.horizontal) === -1) { - throw new TypeError(`widgetPositioning() expects horizontal parameter to be one of (${horizontalModes.join(', ')})`); - } - this._options.widgetPositioning.horizontal = widgetPositioning.horizontal; - } - if (widgetPositioning.vertical) { - if (typeof widgetPositioning.vertical !== 'string') { - throw new TypeError('widgetPositioning() vertical variable must be a string'); - } - widgetPositioning.vertical = widgetPositioning.vertical.toLowerCase(); - if (verticalModes.indexOf(widgetPositioning.vertical) === -1) { - throw new TypeError(`widgetPositioning() expects vertical parameter to be one of (${verticalModes.join(', ')})`); - } - this._options.widgetPositioning.vertical = widgetPositioning.vertical; - } - this._update(); - } - - widgetParent(widgetParent) { - if (arguments.length === 0) { - return this._options.widgetParent; - } - - if (typeof widgetParent === 'string') { - widgetParent = $(widgetParent); - } - - if (widgetParent !== null && typeof widgetParent !== 'string' && !(widgetParent instanceof $)) { - throw new TypeError('widgetParent() expects a string or a jQuery object parameter'); - } - - this._options.widgetParent = widgetParent; - if (this.widget) { - this.hide(); - this.show(); - } - } - - setMultiDate(multiDateArray) { - var dateFormat = this._options.format; - this.clear(); - for (let index = 0; index < multiDateArray.length; index++) { - let date = moment(multiDateArray[index], dateFormat); - this._setValue(date, index); - } - } - - //static - static _jQueryHandleThis(me, option, argument) { - let data = $(me).data(DateTimePicker.DATA_KEY); - if (typeof option === 'object') { - $.extend({}, DateTimePicker.Default, option); - } - - if (!data) { - data = new TempusDominusBootstrap4($(me), option); - $(me).data(DateTimePicker.DATA_KEY, data); - } - - if (typeof option === 'string') { - if (data[option] === undefined) { - throw new Error(`No method named "${option}"`); - } - if (argument === undefined) { - return data[option](); - } - else { - if (option === 'date') { - data.isDateUpdateThroughDateOptionFromClientCode = true; - } - const ret = data[option](argument); - data.isDateUpdateThroughDateOptionFromClientCode = false; - return ret; - } - } - } - - - static _jQueryInterface(option, argument) { - if (this.length === 1) { - return TempusDominusBootstrap4._jQueryHandleThis(this[0], option, argument); - } - return this.each(function () { - TempusDominusBootstrap4._jQueryHandleThis(this, option, argument); - }); - } - } - - /** - * ------------------------------------------------------------------------ - * jQuery - * ------------------------------------------------------------------------ - */ - $(document).on(DateTimePicker.Event.CLICK_DATA_API, DateTimePicker.Selector.DATA_TOGGLE, function () { - const $originalTarget = $(this), $target = getSelectorFromElement($originalTarget), config = $target.data(DateTimePicker.DATA_KEY); - if ($target.length === 0) { - return; - } - if (config._options.allowInputToggle && $originalTarget.is('input[data-toggle="datetimepicker"]')) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, 'toggle'); - }).on(DateTimePicker.Event.CHANGE, `.${DateTimePicker.ClassName.INPUT}`, function (event) { - const $target = getSelectorFromElement($(this)); - if ($target.length === 0 || event.isInit) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, '_change', event); - }).on(DateTimePicker.Event.BLUR, `.${DateTimePicker.ClassName.INPUT}`, function (event) { - const $target = getSelectorFromElement($(this)), config = $target.data(DateTimePicker.DATA_KEY); - if ($target.length === 0) { - return; - } - if (config._options.debug || window.debug) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, 'hide', event); - }).on(DateTimePicker.Event.KEYDOWN, `.${DateTimePicker.ClassName.INPUT}`, function (event) { - const $target = getSelectorFromElement($(this)); - if ($target.length === 0) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, '_keydown', event); - }).on(DateTimePicker.Event.KEYUP, `.${DateTimePicker.ClassName.INPUT}`, function (event) { - const $target = getSelectorFromElement($(this)); - if ($target.length === 0) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, '_keyup', event); - }).on(DateTimePicker.Event.FOCUS, `.${DateTimePicker.ClassName.INPUT}`, function (event) { - const $target = getSelectorFromElement($(this)), config = $target.data(DateTimePicker.DATA_KEY); - if ($target.length === 0) { - return; - } - if (!config._options.allowInputToggle) { - return; - } - TempusDominusBootstrap4._jQueryInterface.call($target, 'show', event); - }); - - $.fn[DateTimePicker.NAME] = TempusDominusBootstrap4._jQueryInterface; - $.fn[DateTimePicker.NAME].Constructor = TempusDominusBootstrap4; - $.fn[DateTimePicker.NAME].noConflict = function () { - $.fn[DateTimePicker.NAME] = JQUERY_NO_CONFLICT; - return TempusDominusBootstrap4._jQueryInterface; - }; - - return TempusDominusBootstrap4; + // ReSharper disable once InconsistentNaming + const JQUERY_NO_CONFLICT = $.fn[DateTimePicker.NAME], + verticalModes = ['top', 'bottom', 'auto'], + horizontalModes = ['left', 'right', 'auto'], + toolbarPlacements = ['default', 'top', 'bottom'], + getSelectorFromElement = function ($element) { + let selector = $element.data('target'), + $selector; + + if (!selector) { + selector = $element.attr('href') || ''; + selector = /^#[a-z]/i.test(selector) ? selector : null; + } + selector = selector.replace("[", "\\[").replace("]", "\\]"); + $selector = $(selector); + if ($selector.length === 0) { + return $element; + } + + if (!$selector.data(DateTimePicker.DATA_KEY)) { + $.extend({}, $selector.data(), $(this).data()); + } + + return $selector; + }; + + // ReSharper disable once InconsistentNaming + class TempusDominusBootstrap4 extends DateTimePicker { + constructor(element, options) { + super(element, options); + this._init(); + } + + _init () { + if (this._element.hasClass('input-group')) { + const datepickerButton = this._element.find('.datepickerbutton'); + if (datepickerButton.length === 0) { + this.component = this._element.find('[data-toggle="datetimepicker"]'); + } else { + this.component = datepickerButton; + } + } + } + + _iconTag (iconName) { + if (typeof feather !== 'undefined' && this._useFeatherIcons() && feather.icons[iconName]) { + return $('').html(feather.icons[iconName].toSvg()); + } + else { + return $('').addClass(iconName); + } + } + + _getDatePickerTemplate () { + const headTemplate = $('').append($('').append($('').append($('').append($('
').addClass('cw').text('#')); - } - - while (currentDate.isBefore(this._viewDate.clone().endOf('w'))) { - row.append($('').addClass('dow').text(currentDate.format('dd'))); - currentDate.add(1, 'd'); - } - this.widget.find('.datepicker-days thead').append(row); - } - - _fillMonths() { - const spans = [], - monthsShort = this._viewDate.clone().startOf('y').startOf('d'); - while (monthsShort.isSame(this._viewDate, 'y')) { - spans.push($('').attr('data-action', 'selectMonth').addClass('month').text(monthsShort.format('MMM'))); - monthsShort.add(1, 'M'); - } - this.widget.find('.datepicker-months td').empty().append(spans); - } - - _updateMonths() { - const monthsView = this.widget.find('.datepicker-months'), - monthsViewHeader = monthsView.find('th'), - months = monthsView.find('tbody').find('span'), self = this, - lastPickedDate = this._getLastPickedDate(); - - monthsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevYear); - monthsViewHeader.eq(1).attr('title', this._options.tooltips.selectYear); - monthsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextYear); - - monthsView.find('.disabled').removeClass('disabled'); - - if (!this._isValid(this._viewDate.clone().subtract(1, 'y'), 'y')) { - monthsViewHeader.eq(0).addClass('disabled'); - } - - monthsViewHeader.eq(1).text(this._viewDate.year()); - - if (!this._isValid(this._viewDate.clone().add(1, 'y'), 'y')) { - monthsViewHeader.eq(2).addClass('disabled'); - } - - months.removeClass('active'); - if (lastPickedDate && lastPickedDate.isSame(this._viewDate, 'y') && !this.unset) { - months.eq(lastPickedDate.month()).addClass('active'); - } - - months.each(function (index) { - if (!self._isValid(self._viewDate.clone().month(index), 'M')) { - $(this).addClass('disabled'); - } - }); - } - - _getStartEndYear(factor, year) { - const step = factor / 10, - startYear = Math.floor(year / factor) * factor, - endYear = startYear + step * 9, - focusValue = Math.floor(year / step) * step; - return [startYear, endYear, focusValue]; - } - - _updateYears() { - const yearsView = this.widget.find('.datepicker-years'), - yearsViewHeader = yearsView.find('th'), - yearCaps = this._getStartEndYear(10, this._viewDate.year()), - startYear = this._viewDate.clone().year(yearCaps[0]), - endYear = this._viewDate.clone().year(yearCaps[1]); - let html = ''; - - yearsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevDecade); - yearsViewHeader.eq(1).attr('title', this._options.tooltips.selectDecade); - yearsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextDecade); - - yearsView.find('.disabled').removeClass('disabled'); - - if (this._options.minDate && this._options.minDate.isAfter(startYear, 'y')) { - yearsViewHeader.eq(0).addClass('disabled'); - } - - yearsViewHeader.eq(1).text(`${startYear.year()}-${endYear.year()}`); - - if (this._options.maxDate && this._options.maxDate.isBefore(endYear, 'y')) { - yearsViewHeader.eq(2).addClass('disabled'); - } - - html += `${startYear.year() - 1}`; - while (!startYear.isAfter(endYear, 'y')) { - html += `${startYear.year()}`; - startYear.add(1, 'y'); - } - html += `${startYear.year()}`; - - yearsView.find('td').html(html); - } - - _updateDecades() { - const decadesView = this.widget.find('.datepicker-decades'), - decadesViewHeader = decadesView.find('th'), - yearCaps = this._getStartEndYear(100, this._viewDate.year()), - startDecade = this._viewDate.clone().year(yearCaps[0]), - endDecade = this._viewDate.clone().year(yearCaps[1]), - lastPickedDate = this._getLastPickedDate(); - let minDateDecade = false, - maxDateDecade = false, - endDecadeYear, - html = ''; - - decadesViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevCentury); - decadesViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextCentury); - - decadesView.find('.disabled').removeClass('disabled'); - - if (startDecade.year() === 0 || this._options.minDate && this._options.minDate.isAfter(startDecade, 'y')) { - decadesViewHeader.eq(0).addClass('disabled'); - } - - decadesViewHeader.eq(1).text(`${startDecade.year()}-${endDecade.year()}`); - - if (this._options.maxDate && this._options.maxDate.isBefore(endDecade, 'y')) { - decadesViewHeader.eq(2).addClass('disabled'); - } - - if (startDecade.year() - 10 < 0) { - html += ' '; - } else { - html += `${startDecade.year() - 10}`; - } - - while (!startDecade.isAfter(endDecade, 'y')) { - endDecadeYear = startDecade.year() + 11; - minDateDecade = this._options.minDate && this._options.minDate.isAfter(startDecade, 'y') && this._options.minDate.year() <= endDecadeYear; - maxDateDecade = this._options.maxDate && this._options.maxDate.isAfter(startDecade, 'y') && this._options.maxDate.year() <= endDecadeYear; - html += `${startDecade.year()}`; - startDecade.add(10, 'y'); - } - html += `${startDecade.year()}`; - - decadesView.find('td').html(html); - } - - _fillDate() { - super._fillDate(); - const daysView = this.widget.find('.datepicker-days'), - daysViewHeader = daysView.find('th'), - html = []; - let currentDate, row, clsName, i; - - if (!this._hasDate()) { - return; - } - - daysViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevMonth); - daysViewHeader.eq(1).attr('title', this._options.tooltips.selectMonth); - daysViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextMonth); - - daysView.find('.disabled').removeClass('disabled'); - daysViewHeader.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)); - - if (!this._isValid(this._viewDate.clone().subtract(1, 'M'), 'M')) { - daysViewHeader.eq(0).addClass('disabled'); - } - if (!this._isValid(this._viewDate.clone().add(1, 'M'), 'M')) { - daysViewHeader.eq(2).addClass('disabled'); - } - - currentDate = this._viewDate.clone().startOf('M').startOf('w').add(12, 'hours'); - - for (i = 0; i < 42; i++) { - //always display 42 days (should show 6 weeks) - if (currentDate.weekday() === 0) { - row = $('
${currentDate.week()}${currentDate.date()}
${currentHour.format(this.use24Hours ? 'HH' : 'hh')}
${currentMinute.format('mm')}
${currentSecond.format('ss')}
').addClass('prev').attr('data-action', 'previous').append(this._iconTag(this._options.icons.previous))).append($('').addClass('picker-switch').attr('data-action', 'pickerSwitch').attr('colspan', `${this._options.calendarWeeks ? '6' : '5'}`)).append($('').addClass('next').attr('data-action', 'next').append(this._iconTag(this._options.icons.next)))), + contTemplate = $('
').attr('colspan', `${this._options.calendarWeeks ? '8' : '7'}`))); + + return [$('
').addClass('datepicker-days').append($('').addClass('table table-sm').append(headTemplate).append($(''))), $('
').addClass('datepicker-months').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('
').addClass('datepicker-years').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone())), $('
').addClass('datepicker-decades').append($('
').addClass('table-condensed').append(headTemplate.clone()).append(contTemplate.clone()))]; + } + + _getTimePickerMainTemplate () { + const topRow = $(''), + middleRow = $(''), + bottomRow = $(''); + + if (this._isEnabled('h')) { + topRow.append($('
').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.incrementHour + }).addClass('btn').attr('data-action', 'incrementHours').append(this._iconTag(this._options.icons.up)))); + middleRow.append($('').append($('').addClass('timepicker-hour').attr({ + 'data-time-component': 'hours', + 'title': this._options.tooltips.pickHour + }).attr('data-action', 'showHours'))); + bottomRow.append($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.decrementHour + }).addClass('btn').attr('data-action', 'decrementHours').append(this._iconTag(this._options.icons.down)))); + } + if (this._isEnabled('m')) { + if (this._isEnabled('h')) { + topRow.append($('').addClass('separator')); + middleRow.append($('').addClass('separator').html(':')); + bottomRow.append($('').addClass('separator')); + } + topRow.append($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.incrementMinute + }).addClass('btn').attr('data-action', 'incrementMinutes').append(this._iconTag(this._options.icons.up)))); + middleRow.append($('').append($('').addClass('timepicker-minute').attr({ + 'data-time-component': 'minutes', + 'title': this._options.tooltips.pickMinute + }).attr('data-action', 'showMinutes'))); + bottomRow.append($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.decrementMinute + }).addClass('btn').attr('data-action', 'decrementMinutes').append(this._iconTag(this._options.icons.down)))); + } + if (this._isEnabled('s')) { + if (this._isEnabled('m')) { + topRow.append($('').addClass('separator')); + middleRow.append($('').addClass('separator').html(':')); + bottomRow.append($('').addClass('separator')); + } + topRow.append($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.incrementSecond + }).addClass('btn').attr('data-action', 'incrementSeconds').append(this._iconTag(this._options.icons.up)))); + middleRow.append($('').append($('').addClass('timepicker-second').attr({ + 'data-time-component': 'seconds', + 'title': this._options.tooltips.pickSecond + }).attr('data-action', 'showSeconds'))); + bottomRow.append($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'title': this._options.tooltips.decrementSecond + }).addClass('btn').attr('data-action', 'decrementSeconds').append(this._iconTag(this._options.icons.down)))); + } + + if (!this.use24Hours) { + topRow.append($('').addClass('separator')); + middleRow.append($('').append($('').addClass('separator')); + } + + return $('
').addClass('timepicker-picker').append($('').addClass('table-condensed').append([topRow, middleRow, bottomRow])); + } + + _getTimePickerTemplate () { + const hoursView = $('
').addClass('timepicker-hours').append($('
').addClass('table-condensed')), + minutesView = $('
').addClass('timepicker-minutes').append($('
').addClass('table-condensed')), + secondsView = $('
').addClass('timepicker-seconds').append($('
').addClass('table-condensed')), + ret = [this._getTimePickerMainTemplate()]; + + if (this._isEnabled('h')) { + ret.push(hoursView); + } + if (this._isEnabled('m')) { + ret.push(minutesView); + } + if (this._isEnabled('s')) { + ret.push(secondsView); + } + + return ret; + } + + _getToolbar () { + const row = []; + if (this._options.buttons.showToday) { + row.push($('
').append($('').attr({ + href: '#', + tabindex: '-1', + 'data-action': 'today', + 'title': this._options.tooltips.today + }).append(this._iconTag(this._options.icons.today)))); + } + if (!this._options.sideBySide && this._options.collapse && this._hasDate() && this._hasTime()) { + let title, icon; + if (this._options.viewMode === 'times') { + title = this._options.tooltips.selectDate; + icon = this._options.icons.date; + } else { + title = this._options.tooltips.selectTime; + icon = this._options.icons.time; + } + row.push($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'data-action': 'togglePicker', + 'title': title + }).append(this._iconTag(icon)))); + } + if (this._options.buttons.showClear) { + row.push($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'data-action': 'clear', + 'title': this._options.tooltips.clear + }).append(this._iconTag(this._options.icons.clear)))); + } + if (this._options.buttons.showClose) { + row.push($('').append($('').attr({ + href: '#', + tabindex: '-1', + 'data-action': 'close', + 'title': this._options.tooltips.close + }).append(this._iconTag(this._options.icons.close)))); + } + return row.length === 0 ? '' : $('').addClass('table-condensed').append($('').append($('').append(row))); + } + + _getTemplate () { + const template = $('
').addClass(( + `bootstrap-datetimepicker-widget dropdown-menu ${this._options.calendarWeeks ? 'tempusdominus-bootstrap-datetimepicker-widget-with-calendar-weeks' : ''} ` + + + `${this._useFeatherIcons() ? 'tempusdominus-bootstrap-datetimepicker-widget-with-feather-icons' : ''} ` + ).trim()), + dateView = $('
').addClass('datepicker').append(this._getDatePickerTemplate()), + timeView = $('
').addClass('timepicker').append(this._getTimePickerTemplate()), + content = $('
    ').addClass('list-unstyled'), + toolbar = $('
  • ').addClass(( + `picker-switch${this._options.collapse ? ' accordion-toggle' : ''} ` + + `${this._useFeatherIcons() ? 'picker-switch-with-feathers-icons' : ''}` + ).trim()).append(this._getToolbar()); + + if (this._options.inline) { + template.removeClass('dropdown-menu'); + } + + if (this.use24Hours) { + template.addClass('usetwentyfour'); + } + if ((this.input !== undefined && this.input.prop('readonly')) || this._options.readonly) { + template.addClass('bootstrap-datetimepicker-widget-readonly'); + } + if (this._isEnabled('s') && !this.use24Hours) { + template.addClass('wider'); + } + + if (this._options.sideBySide && this._hasDate() && this._hasTime()) { + template.addClass('timepicker-sbs'); + if (this._options.toolbarPlacement === 'top') { + template.append(toolbar); + } + template.append($('
    ').addClass('row').append(dateView.addClass('col-md-6')).append(timeView.addClass('col-md-6'))); + if (this._options.toolbarPlacement === 'bottom' || this._options.toolbarPlacement === 'default') { + template.append(toolbar); + } + return template; + } + + if (this._options.toolbarPlacement === 'top') { + content.append(toolbar); + } + if (this._hasDate()) { + content.append($('
  • ').addClass(this._options.collapse && this._hasTime() ? 'collapse' : '') + .addClass((this._options.collapse && this._hasTime() && this._options.viewMode === 'times' ? '' : 'show')) + .append(dateView)); + } + if (this._options.toolbarPlacement === 'default') { + content.append(toolbar); + } + if (this._hasTime()) { + content.append($('
  • ').addClass(this._options.collapse && this._hasDate() ? 'collapse' : '') + .addClass((this._options.collapse && this._hasDate() && this._options.viewMode === 'times' ? 'show' : '')) + .append(timeView)); + } + if (this._options.toolbarPlacement === 'bottom') { + content.append(toolbar); + } + return template.append(content); + } + + _place (e) { + let self = (e && e.data && e.data.picker) || this, vertical = self._options.widgetPositioning.vertical, + horizontal = self._options.widgetPositioning.horizontal, + parent; + const position = (self.component && self.component.length ? self.component : self._element).position(), + offset = (self.component && self.component.length ? self.component : self._element).offset(); + if (self._options.widgetParent) { + parent = self._options.widgetParent.append(self.widget); + } else if (self._element.is('input')) { + parent = self._element.after(self.widget).parent(); + } else if (self._options.inline) { + parent = self._element.append(self.widget); + return; + } else { + parent = self._element; + self._element.children().first().after(self.widget); + } + + // Top and bottom logic + if (vertical === 'auto') { + //noinspection JSValidateTypes + if (offset.top + self.widget.height() * 1.5 >= $(window).height() + $(window).scrollTop() && self.widget.height() + self._element.outerHeight() < offset.top) { + vertical = 'top'; + } else { + vertical = 'bottom'; + } + } + + // Left and right logic + if (horizontal === 'auto') { + if (parent.width() < offset.left + self.widget.outerWidth() / 2 && offset.left + self.widget.outerWidth() > $(window).width()) { + horizontal = 'right'; + } else { + horizontal = 'left'; + } + } + + if (vertical === 'top') { + self.widget.addClass('top').removeClass('bottom'); + } else { + self.widget.addClass('bottom').removeClass('top'); + } + + if (horizontal === 'right') { + self.widget.addClass('float-right'); + } else { + self.widget.removeClass('float-right'); + } + + // find the first parent element that has a relative css positioning + if (parent.css('position') !== 'relative') { + parent = parent.parents().filter(function () { + return $(this).css('position') === 'relative'; + }).first(); + } + + if (parent.length === 0) { + throw new Error('datetimepicker component should be placed within a relative positioned container'); + } + + self.widget.css({ + top: vertical === 'top' ? 'auto' : position.top + self._element.outerHeight() + 'px', + bottom: vertical === 'top' ? parent.outerHeight() - (parent === self._element ? 0 : position.top) + 'px' : 'auto', + left: horizontal === 'left' ? (parent === self._element ? 0 : position.left) + 'px' : 'auto', + right: horizontal === 'left' ? 'auto' : parent.outerWidth() - self._element.outerWidth() - (parent === self._element ? 0 : position.left) + 'px' + }); + } + + _fillDow () { + const row = $('
'), + currentDate = this._viewDate.clone().startOf('w').startOf('d'); + + if (this._options.calendarWeeks === true) { + row.append($(''); + if (this._options.calendarWeeks) { + row.append(``); + } + html.push(row); + } + clsName = ''; + if (currentDate.isBefore(this._viewDate, 'M')) { + clsName += ' old'; + } + if (currentDate.isAfter(this._viewDate, 'M')) { + clsName += ' new'; + } + if (this._options.allowMultidate) { + var index = this._datesFormatted.indexOf(currentDate.format('YYYY-MM-DD')); + if (index !== -1) { + if (currentDate.isSame(this._datesFormatted[index], 'd') && !this.unset) { + clsName += ' active'; + } + } + } else { + if (currentDate.isSame(this._getLastPickedDate(), 'd') && !this.unset) { + clsName += ' active'; + } + } + if (!this._isValid(currentDate, 'd')) { + clsName += ' disabled'; + } + if (currentDate.isSame(this.getMoment(), 'd')) { + clsName += ' today'; + } + if (currentDate.day() === 0 || currentDate.day() === 6) { + clsName += ' weekend'; + } + row.append(``); + currentDate.add(1, 'd'); + } + + $('body').addClass('tempusdominus-bootstrap-datetimepicker-widget-day-click'); + $('body').append('
'); + daysView.find('tbody').empty().append(html); + $('body').find('.tempusdominus-bootstrap-datetimepicker-widget-day-click-glass-panel').remove(); + $('body').removeClass('tempusdominus-bootstrap-datetimepicker-widget-day-click'); + + this._updateMonths(); + + this._updateYears(); + + this._updateDecades(); + } + + _fillHours () { + const table = this.widget.find('.timepicker-hours table'), + currentHour = this._viewDate.clone().startOf('d'), + html = []; + let row = $(''); + + if (this._viewDate.hour() > 11 && !this.use24Hours) { + currentHour.hour(12); + } + while (currentHour.isSame(this._viewDate, 'd') && (this.use24Hours || this._viewDate.hour() < 12 && currentHour.hour() < 12 || this._viewDate.hour() > 11)) { + if (currentHour.hour() % 4 === 0) { + row = $(''); + html.push(row); + } + row.append(``); + currentHour.add(1, 'h'); + } + table.empty().append(html); + } + + _fillMinutes () { + const table = this.widget.find('.timepicker-minutes table'), + currentMinute = this._viewDate.clone().startOf('h'), + html = [], + step = this._options.stepping === 1 ? 5 : this._options.stepping; + let row = $(''); + + while (this._viewDate.isSame(currentMinute, 'h')) { + if (currentMinute.minute() % (step * 4) === 0) { + row = $(''); + html.push(row); + } + row.append(``); + currentMinute.add(step, 'm'); + } + table.empty().append(html); + } + + _fillSeconds () { + const table = this.widget.find('.timepicker-seconds table'), + currentSecond = this._viewDate.clone().startOf('m'), + html = []; + let row = $(''); + + while (this._viewDate.isSame(currentSecond, 'm')) { + if (currentSecond.second() % 20 === 0) { + row = $(''); + html.push(row); + } + row.append(``); + currentSecond.add(5, 's'); + } + + table.empty().append(html); + } + + _fillTime () { + let toggle, newDate; + const timeComponents = this.widget.find('.timepicker span[data-time-component]'), + lastPickedDate = this._getLastPickedDate(); + + if (!this.use24Hours) { + toggle = this.widget.find('.timepicker [data-action=togglePeriod]'); + newDate = lastPickedDate ? lastPickedDate.clone().add(lastPickedDate.hours() >= 12 ? -12 : 12, 'h') : void 0; + + lastPickedDate && toggle.text(lastPickedDate.format('A')); + + if (this._isValid(newDate, 'h')) { + toggle.removeClass('disabled'); + } else { + toggle.addClass('disabled'); + } + } + lastPickedDate && timeComponents.filter('[data-time-component=hours]').text(lastPickedDate.format(`${this.use24Hours ? 'HH' : 'hh'}`)); + lastPickedDate && timeComponents.filter('[data-time-component=minutes]').text(lastPickedDate.format('mm')); + lastPickedDate && timeComponents.filter('[data-time-component=seconds]').text(lastPickedDate.format('ss')); + + this._fillHours(); + this._fillMinutes(); + this._fillSeconds(); + } + + _doAction (e, action) { + let lastPicked = this._getLastPickedDate(); + if ($(e.currentTarget).is('.disabled')) { + return false; + } + action = action || $(e.currentTarget).data('action'); + switch (action) { + case 'next': + { + const navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION; + this._viewDate.add(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, navFnc); + this._fillDate(); + this._viewUpdate(navFnc); + break; + } + case 'previous': + { + const navFnc = DateTimePicker.DatePickerModes[this.currentViewMode].NAV_FUNCTION; + this._viewDate.subtract(DateTimePicker.DatePickerModes[this.currentViewMode].NAV_STEP, navFnc); + this._fillDate(); + this._viewUpdate(navFnc); + break; + } + case 'pickerSwitch': + this._showMode(1); + break; + case 'selectMonth': + { + const month = $(e.target).closest('tbody').find('span').index($(e.target)); + this._viewDate.month(month); + if (this.currentViewMode === this.MinViewModeNumber) { + this._setValue(lastPicked.clone().year(this._viewDate.year()).month(this._viewDate.month()), this._getLastPickedDateIndex()); + if (!this._options.inline) { + this.hide(); + } + } else { + this._showMode(-1); + this._fillDate(); + } + this._viewUpdate('M'); + break; + } + case 'selectYear': + { + const year = parseInt($(e.target).text(), 10) || 0; + this._viewDate.year(year); + if (this.currentViewMode === this.MinViewModeNumber) { + this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex()); + if (!this._options.inline) { + this.hide(); + } + } else { + this._showMode(-1); + this._fillDate(); + } + this._viewUpdate('YYYY'); + break; + } + case 'selectDecade': + { + const year = parseInt($(e.target).data('selection'), 10) || 0; + this._viewDate.year(year); + if (this.currentViewMode === this.MinViewModeNumber) { + this._setValue(lastPicked.clone().year(this._viewDate.year()), this._getLastPickedDateIndex()); + if (!this._options.inline) { + this.hide(); + } + } else { + this._showMode(-1); + this._fillDate(); + } + this._viewUpdate('YYYY'); + break; + } + case 'selectDay': + { + const day = this._viewDate.clone(); + if ($(e.target).is('.old')) { + day.subtract(1, 'M'); + } + if ($(e.target).is('.new')) { + day.add(1, 'M'); + } + + var selectDate = day.date(parseInt($(e.target).text(), 10)), index = 0; + if (this._options.allowMultidate) { + index = this._datesFormatted.indexOf(selectDate.format('YYYY-MM-DD')); + if (index !== -1) { + this._setValue(null, index); //deselect multidate + } else { + this._setValue(selectDate, this._getLastPickedDateIndex() + 1); + } + } else { + this._setValue(selectDate, this._getLastPickedDateIndex()); + } + + if (!this._hasTime() && !this._options.keepOpen && !this._options.inline && !this._options.allowMultidate) { + this.hide(); + } + break; + } + case 'incrementHours': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().add(1, 'h'); + if (this._isValid(newDate, 'h')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'incrementMinutes': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().add(this._options.stepping, 'm'); + if (this._isValid(newDate, 'm')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'incrementSeconds': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().add(1, 's'); + if (this._isValid(newDate, 's')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'decrementHours': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().subtract(1, 'h'); + if (this._isValid(newDate, 'h')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'decrementMinutes': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().subtract(this._options.stepping, 'm'); + if (this._isValid(newDate, 'm')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'decrementSeconds': + { + if (!lastPicked) { + break; + } + const newDate = lastPicked.clone().subtract(1, 's'); + if (this._isValid(newDate, 's')) { + if (this._getLastPickedDateIndex() < 0) { + this.date(newDate); + } + this._setValue(newDate, this._getLastPickedDateIndex()); + } + break; + } + case 'togglePeriod': + { + this._setValue(lastPicked.clone().add(lastPicked.hours() >= 12 ? -12 : 12, 'h'), this._getLastPickedDateIndex()); + break; + } + case 'togglePicker': + { + const $this = $(e.target), + $link = $this.closest('a'), + $parent = $this.closest('ul'), + expanded = $parent.find('.show'), + closed = $parent.find('.collapse:not(.show)'), + $span = $this.is('span') ? $this : $this.find('span'); + let collapseData, inactiveIcon, iconTest; + + if (expanded && expanded.length) { + collapseData = expanded.data('collapse'); + if (collapseData && collapseData.transitioning) { + return true; + } + 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('show'); + closed.addClass('show'); + } + + if (this._useFeatherIcons()) { + $link.toggleClass(this._options.icons.time + ' ' + this._options.icons.date); + inactiveIcon = ($link.hasClass(this._options.icons.time)) ? this._options.icons.date : this._options.icons.time; + $link.html(this._iconTag(inactiveIcon)); + } + else { + $span.toggleClass(this._options.icons.time + ' ' + this._options.icons.date); + } + + if (this._useFeatherIcons()) { + iconTest = $link.hasClass(this._options.icons.date); + } + else { + iconTest = $span.hasClass(this._options.icons.date); + } + + if (iconTest) { + $link.attr('title', this._options.tooltips.selectDate); + } else { + $link.attr('title', this._options.tooltips.selectTime); + } + } + } + break; + case 'showPicker': + this.widget.find('.timepicker > div:not(.timepicker-picker)').hide(); + this.widget.find('.timepicker .timepicker-picker').show(); + break; + case 'showHours': + this.widget.find('.timepicker .timepicker-picker').hide(); + this.widget.find('.timepicker .timepicker-hours').show(); + break; + case 'showMinutes': + this.widget.find('.timepicker .timepicker-picker').hide(); + this.widget.find('.timepicker .timepicker-minutes').show(); + break; + case 'showSeconds': + this.widget.find('.timepicker .timepicker-picker').hide(); + this.widget.find('.timepicker .timepicker-seconds').show(); + break; + case 'selectHour': + { + let hour = parseInt($(e.target).text(), 10); + + if (!this.use24Hours) { + if (lastPicked.hours() >= 12) { + if (hour !== 12) { + hour += 12; + } + } else { + if (hour === 12) { + hour = 0; + } + } + } + this._setValue(lastPicked.clone().hours(hour), this._getLastPickedDateIndex()); + if (!this._isEnabled('a') && !this._isEnabled('m') && !this._options.keepOpen && !this._options.inline) { + this.hide(); + } + else { + this._doAction(e, 'showPicker'); + } + break; + } + case 'selectMinute': + this._setValue(lastPicked.clone().minutes(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex()); + if (!this._isEnabled('a') && !this._isEnabled('s') && !this._options.keepOpen && !this._options.inline) { + this.hide(); + } + else { + this._doAction(e, 'showPicker'); + } + break; + case 'selectSecond': + this._setValue(lastPicked.clone().seconds(parseInt($(e.target).text(), 10)), this._getLastPickedDateIndex()); + if (!this._isEnabled('a') && !this._options.keepOpen && !this._options.inline) { + this.hide(); + } + else { + this._doAction(e, 'showPicker'); + } + break; + case 'clear': + this.clear(); + break; + case 'close': + this.hide(); + break; + case 'today': + { + const todaysDate = this.getMoment(); + if (this._isValid(todaysDate, 'd')) { + this._setValue(todaysDate, this._getLastPickedDateIndex()); + } + break; + } + } + return false; + } + + //public + hide () { + let transitioning = false; + if (!this.widget) { + return; + } + // Ignore event if in the middle of a picker transition + this.widget.find('.collapse').each(function () { + const collapseData = $(this).data('collapse'); + if (collapseData && collapseData.transitioning) { + transitioning = true; + return false; + } + return true; + }); + if (transitioning) { + return; + } + if (this.component && this.component.hasClass('btn')) { + this.component.toggleClass('active'); + } + this.widget.hide(); + + $(window).off('resize', this._place); + this.widget.off('click', '[data-action]'); + this.widget.off('mousedown', false); + + this.widget.remove(); + this.widget = false; + + if (this.input !== undefined && this.input.val() !== undefined && this.input.val().trim().length !== 0) { + this._setValue(this._parseInputDate(this.input.val().trim(), { + isPickerShow: false + }), 0); + } + const lastPickedDate = this._getLastPickedDate(); + this._notifyEvent({ + type: DateTimePicker.Event.HIDE, + date: this.unset ? null : (lastPickedDate ? lastPickedDate.clone() : void 0) + }); + + if (this.input !== undefined) { + this.input.blur(); + } + + this._viewDate = lastPickedDate ? lastPickedDate.clone() : this.getMoment(); + } + + show () { + let currentMoment, shouldUseCurrentIfUnset = false; + const 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 (this.input !== undefined) { + if (this.input.prop('disabled') || !this._options.ignoreReadonly && this.input.prop('readonly') || this.widget) { + return; + } + if (this.input.val() !== undefined && this.input.val().trim().length !== 0) { + this._setValue(this._parseInputDate(this.input.val().trim(), { + isPickerShow: true + }), 0); + } else { + shouldUseCurrentIfUnset = true + } + } + else { + shouldUseCurrentIfUnset = true; + } + + if (shouldUseCurrentIfUnset && this.unset && this._options.useCurrent) { + currentMoment = this.getMoment(); + if (typeof this._options.useCurrent === 'string') { + currentMoment = useCurrentGranularity[this._options.useCurrent](currentMoment); + } + this._setValue(currentMoment, 0); + } + + this.widget = this._getTemplate(); + + this._fillDow(); + this._fillMonths(); + + this.widget.find('.timepicker-hours').hide(); + this.widget.find('.timepicker-minutes').hide(); + this.widget.find('.timepicker-seconds').hide(); + + this._update(); + this._showMode(); + + $(window).on('resize', { picker: this }, this._place); + this.widget.on('click', '[data-action]', $.proxy(this._doAction, this)); // this handles clicks on the widget + this.widget.on('mousedown', false); + + if (this.component && this.component.hasClass('btn')) { + this.component.toggleClass('active'); + } + this._place(); + this.widget.show(); + if (this.input !== undefined && this._options.focusOnShow && !this.input.is(':focus')) { + this.input.focus(); + } + + this._notifyEvent({ + type: DateTimePicker.Event.SHOW + }); + } + + destroy () { + this.hide(); + //todo doc off? + this._element.removeData(DateTimePicker.DATA_KEY); + this._element.removeData('date'); + } + + disable () { + this.hide(); + if (this.component && this.component.hasClass('btn')) { + this.component.addClass('disabled'); + } + if (this.input !== undefined) { + this.input.prop('disabled', true); //todo disable this/comp if input is null + } + } + + enable () { + if (this.component && this.component.hasClass('btn')) { + this.component.removeClass('disabled'); + } + if (this.input !== undefined) { + this.input.prop('disabled', false); //todo enable comp/this if input is null + } + } + + toolbarPlacement (toolbarPlacement) { + if (arguments.length === 0) { + return this._options.toolbarPlacement; + } + + if (typeof toolbarPlacement !== 'string') { + throw new TypeError('toolbarPlacement() expects a string parameter'); + } + if (toolbarPlacements.indexOf(toolbarPlacement) === -1) { + throw new TypeError(`toolbarPlacement() parameter must be one of (${toolbarPlacements.join(', ')}) value`); + } + this._options.toolbarPlacement = toolbarPlacement; + + if (this.widget) { + this.hide(); + this.show(); + } + } + + widgetPositioning (widgetPositioning) { + if (arguments.length === 0) { + return $.extend({}, this._options.widgetPositioning); + } + + if ({}.toString.call(widgetPositioning) !== '[object Object]') { + throw new TypeError('widgetPositioning() expects an object variable'); + } + if (widgetPositioning.horizontal) { + if (typeof widgetPositioning.horizontal !== 'string') { + throw new TypeError('widgetPositioning() horizontal variable must be a string'); + } + widgetPositioning.horizontal = widgetPositioning.horizontal.toLowerCase(); + if (horizontalModes.indexOf(widgetPositioning.horizontal) === -1) { + throw new TypeError(`widgetPositioning() expects horizontal parameter to be one of (${horizontalModes.join(', ')})`); + } + this._options.widgetPositioning.horizontal = widgetPositioning.horizontal; + } + if (widgetPositioning.vertical) { + if (typeof widgetPositioning.vertical !== 'string') { + throw new TypeError('widgetPositioning() vertical variable must be a string'); + } + widgetPositioning.vertical = widgetPositioning.vertical.toLowerCase(); + if (verticalModes.indexOf(widgetPositioning.vertical) === -1) { + throw new TypeError(`widgetPositioning() expects vertical parameter to be one of (${verticalModes.join(', ')})`); + } + this._options.widgetPositioning.vertical = widgetPositioning.vertical; + } + this._update(); + } + + widgetParent (widgetParent) { + if (arguments.length === 0) { + return this._options.widgetParent; + } + + if (typeof widgetParent === 'string') { + widgetParent = $(widgetParent); + } + + if (widgetParent !== null && typeof widgetParent !== 'string' && !(widgetParent instanceof $)) { + throw new TypeError('widgetParent() expects a string or a jQuery object parameter'); + } + + this._options.widgetParent = widgetParent; + if (this.widget) { + this.hide(); + this.show(); + } + } + + setMultiDate (multiDateArray) { + var dateFormat = this._options.format; + this.clear(); + for (let index = 0; index < multiDateArray.length; index++) { + let date = moment(multiDateArray[index], dateFormat); + this._setValue(date, index); + } + } + + //static + static _jQueryHandleThis (me, option, argument) { + let data = $(me).data(DateTimePicker.DATA_KEY); + if (typeof option === 'object') { + $.extend({}, DateTimePicker.Default, option); + } + + if (!data) { + data = new TempusDominusBootstrap4($(me), option); + $(me).data(DateTimePicker.DATA_KEY, data); + } + + if (typeof option === 'string') { + if (data[option] === undefined) { + throw new Error(`No method named "${option}"`); + } + if (argument === undefined) { + return data[option](); + } + else { + if (option === 'date') { + data.isDateUpdateThroughDateOptionFromClientCode = true; + } + const ret = data[option](argument); + data.isDateUpdateThroughDateOptionFromClientCode = false; + return ret; + } + } + } + + + static _jQueryInterface (option, argument) { + if (this.length === 1) { + return TempusDominusBootstrap4._jQueryHandleThis(this[0], option, argument); + } + return this.each(function () { + TempusDominusBootstrap4._jQueryHandleThis(this, option, argument); + }); + } + } + + /** + * ------------------------------------------------------------------------ + * jQuery + * ------------------------------------------------------------------------ + */ + $(document).on(DateTimePicker.Event.CLICK_DATA_API, DateTimePicker.Selector.DATA_TOGGLE, function () { + const $originalTarget = $(this), $target = getSelectorFromElement($originalTarget), config = $target.data(DateTimePicker.DATA_KEY); + if ($target.length === 0) { + return; + } + if (config._options.allowInputToggle && $originalTarget.is('input[data-toggle="datetimepicker"]')) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, 'toggle'); + }).on(DateTimePicker.Event.CHANGE, `.${DateTimePicker.ClassName.INPUT}`, function (event) { + const $target = getSelectorFromElement($(this)); + if ($target.length === 0 || event.isInit) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, '_change', event); + }).on(DateTimePicker.Event.BLUR, `.${DateTimePicker.ClassName.INPUT}`, function (event) { + const $target = getSelectorFromElement($(this)), config = $target.data(DateTimePicker.DATA_KEY); + if ($target.length === 0) { + return; + } + if (config._options.debug || window.debug) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, 'hide', event); + }).on(DateTimePicker.Event.KEYDOWN, `.${DateTimePicker.ClassName.INPUT}`, function (event) { + const $target = getSelectorFromElement($(this)); + if ($target.length === 0) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, '_keydown', event); + }).on(DateTimePicker.Event.KEYUP, `.${DateTimePicker.ClassName.INPUT}`, function (event) { + const $target = getSelectorFromElement($(this)); + if ($target.length === 0) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, '_keyup', event); + }).on(DateTimePicker.Event.FOCUS, `.${DateTimePicker.ClassName.INPUT}`, function (event) { + const $target = getSelectorFromElement($(this)), config = $target.data(DateTimePicker.DATA_KEY); + if ($target.length === 0) { + return; + } + if (!config._options.allowInputToggle) { + return; + } + TempusDominusBootstrap4._jQueryInterface.call($target, 'show', event); + }); + + $.fn[DateTimePicker.NAME] = TempusDominusBootstrap4._jQueryInterface; + $.fn[DateTimePicker.NAME].Constructor = TempusDominusBootstrap4; + $.fn[DateTimePicker.NAME].noConflict = function () { + $.fn[DateTimePicker.NAME] = JQUERY_NO_CONFLICT; + return TempusDominusBootstrap4._jQueryInterface; + }; + + return TempusDominusBootstrap4; })(jQuery);
').addClass('cw').text('#')); + } + + while (currentDate.isBefore(this._viewDate.clone().endOf('w'))) { + row.append($('').addClass('dow').text(currentDate.format('dd'))); + currentDate.add(1, 'd'); + } + this.widget.find('.datepicker-days thead').append(row); + } + + _fillMonths () { + const spans = [], + monthsShort = this._viewDate.clone().startOf('y').startOf('d'); + while (monthsShort.isSame(this._viewDate, 'y')) { + spans.push($('').attr('data-action', 'selectMonth').addClass('month').text(monthsShort.format('MMM'))); + monthsShort.add(1, 'M'); + } + this.widget.find('.datepicker-months td').empty().append(spans); + } + + _updateMonths () { + const monthsView = this.widget.find('.datepicker-months'), + monthsViewHeader = monthsView.find('th'), + months = monthsView.find('tbody').find('span'), self = this, + lastPickedDate = this._getLastPickedDate(); + + monthsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevYear); + monthsViewHeader.eq(1).attr('title', this._options.tooltips.selectYear); + monthsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextYear); + + monthsView.find('.disabled').removeClass('disabled'); + + if (!this._isValid(this._viewDate.clone().subtract(1, 'y'), 'y')) { + monthsViewHeader.eq(0).addClass('disabled'); + } + + monthsViewHeader.eq(1).text(this._viewDate.year()); + + if (!this._isValid(this._viewDate.clone().add(1, 'y'), 'y')) { + monthsViewHeader.eq(2).addClass('disabled'); + } + + months.removeClass('active'); + if (lastPickedDate && lastPickedDate.isSame(this._viewDate, 'y') && !this.unset) { + months.eq(lastPickedDate.month()).addClass('active'); + } + + months.each(function (index) { + if (!self._isValid(self._viewDate.clone().month(index), 'M')) { + $(this).addClass('disabled'); + } + }); + } + + _getStartEndYear (factor, year) { + const step = factor / 10, + startYear = Math.floor(year / factor) * factor, + endYear = startYear + step * 9, + focusValue = Math.floor(year / step) * step; + return [startYear, endYear, focusValue]; + } + + _updateYears () { + const yearsView = this.widget.find('.datepicker-years'), + yearsViewHeader = yearsView.find('th'), + yearCaps = this._getStartEndYear(10, this._viewDate.year()), + startYear = this._viewDate.clone().year(yearCaps[0]), + endYear = this._viewDate.clone().year(yearCaps[1]); + let html = ''; + + yearsViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevDecade); + yearsViewHeader.eq(1).attr('title', this._options.tooltips.selectDecade); + yearsViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextDecade); + + yearsView.find('.disabled').removeClass('disabled'); + + if (this._options.minDate && this._options.minDate.isAfter(startYear, 'y')) { + yearsViewHeader.eq(0).addClass('disabled'); + } + + yearsViewHeader.eq(1).text(`${startYear.year()}-${endYear.year()}`); + + if (this._options.maxDate && this._options.maxDate.isBefore(endYear, 'y')) { + yearsViewHeader.eq(2).addClass('disabled'); + } + + html += `${startYear.year() - 1}`; + while (!startYear.isAfter(endYear, 'y')) { + html += `${startYear.year()}`; + startYear.add(1, 'y'); + } + html += `${startYear.year()}`; + + yearsView.find('td').html(html); + } + + _updateDecades () { + const decadesView = this.widget.find('.datepicker-decades'), + decadesViewHeader = decadesView.find('th'), + yearCaps = this._getStartEndYear(100, this._viewDate.year()), + startDecade = this._viewDate.clone().year(yearCaps[0]), + endDecade = this._viewDate.clone().year(yearCaps[1]), + lastPickedDate = this._getLastPickedDate(); + let minDateDecade = false, + maxDateDecade = false, + endDecadeYear, + html = ''; + + decadesViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevCentury); + decadesViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextCentury); + + decadesView.find('.disabled').removeClass('disabled'); + + if (startDecade.year() === 0 || this._options.minDate && this._options.minDate.isAfter(startDecade, 'y')) { + decadesViewHeader.eq(0).addClass('disabled'); + } + + decadesViewHeader.eq(1).text(`${startDecade.year()}-${endDecade.year()}`); + + if (this._options.maxDate && this._options.maxDate.isBefore(endDecade, 'y')) { + decadesViewHeader.eq(2).addClass('disabled'); + } + + if (startDecade.year() - 10 < 0) { + html += ' '; + } else { + html += `${startDecade.year() - 10}`; + } + + while (!startDecade.isAfter(endDecade, 'y')) { + endDecadeYear = startDecade.year() + 11; + minDateDecade = this._options.minDate && this._options.minDate.isAfter(startDecade, 'y') && this._options.minDate.year() <= endDecadeYear; + maxDateDecade = this._options.maxDate && this._options.maxDate.isAfter(startDecade, 'y') && this._options.maxDate.year() <= endDecadeYear; + html += `${startDecade.year()}`; + startDecade.add(10, 'y'); + } + html += `${startDecade.year()}`; + + decadesView.find('td').html(html); + } + + _fillDate () { + super._fillDate(); + const daysView = this.widget.find('.datepicker-days'), + daysViewHeader = daysView.find('th'), + html = []; + let currentDate, row, clsName, i; + + if (!this._hasDate()) { + return; + } + + daysViewHeader.eq(0).find('span').attr('title', this._options.tooltips.prevMonth); + daysViewHeader.eq(1).attr('title', this._options.tooltips.selectMonth); + daysViewHeader.eq(2).find('span').attr('title', this._options.tooltips.nextMonth); + + daysView.find('.disabled').removeClass('disabled'); + daysViewHeader.eq(1).text(this._viewDate.format(this._options.dayViewHeaderFormat)); + + if (!this._isValid(this._viewDate.clone().subtract(1, 'M'), 'M')) { + daysViewHeader.eq(0).addClass('disabled'); + } + if (!this._isValid(this._viewDate.clone().add(1, 'M'), 'M')) { + daysViewHeader.eq(2).addClass('disabled'); + } + + currentDate = this._viewDate.clone().startOf('M').startOf('w').add(12, 'hours'); + + for (i = 0; i < 42; i++) { + //always display 42 days (should show 6 weeks) + if (currentDate.weekday() === 0) { + row = $('
${currentDate.week()}${currentDate.date()}
${currentHour.format(this.use24Hours ? 'HH' : 'hh')}
${currentMinute.format('mm')}
${currentSecond.format('ss')}