(function () { 'use strict'; /*! DateTime picker for DataTables.net v1.0.1 * * ©2020 SpryMedia Ltd, all rights reserved. * License: MIT datatables.net/license/mit */ /** * @summary DateTime picker for DataTables.net * @version 1.0.1 * @file dataTables.dateTime.js * @author SpryMedia Ltd * @contact www.datatables.net/contact */ (function( factory ){ if ( typeof define === 'function' && define.amd ) { // AMD define( ['jquery'], function ( $ ) { return factory( $, window, document ); } ); } else if ( typeof exports === 'object' ) { // CommonJS module.exports = function (root, $) { if ( ! root ) { root = window; } return factory( $, root, root.document ); }; } else { // Browser factory( jQuery, window, document ); } }(function( $, window, document, undefined$1 ) { // Support libraries which support a Moment like API var dateLib = window.moment ? window.moment : window.dayjs ? window.dayjs : null; /* * This file provides a DateTime GUI picker (calendar and time input). Only the * format YYYY-MM-DD is supported without additional software, but the end user * experience can be greatly enhanced by including the momentjs or dayjs library * which provide date / time parsing and formatting options. * * This functionality is required because the HTML5 date and datetime input * types are not widely supported in desktop browsers. * * Constructed by using: * * new DateTime( input, opts ) * * where `input` is the HTML input element to use and `opts` is an object of * options based on the `DateTime.defaults` object. */ var DateTime = function ( input, opts ) { this.c = $.extend( true, {}, DateTime.defaults, opts ); var classPrefix = this.c.classPrefix; var i18n = this.c.i18n; // Only IS8601 dates are supported without moment pr dayjs if ( ! dateLib && this.c.format !== 'YYYY-MM-DD' ) { throw "DateTime: Without momentjs or dayjs only the format 'YYYY-MM-DD' can be used"; } // Min and max need to be `Date` objects in the config if (typeof this.c.minDate === 'string') { this.c.minDate = new Date(this.c.minDate); } if (typeof this.c.maxDate === 'string') { this.c.maxDate = new Date(this.c.maxDate); } // DOM structure var structure = $( '
'+ '
'+ '
'+ '
'+ ''+ '
'+ '
'+ ''+ '
'+ '
'+ ''+ ''+ '
'+ '
'+ ''+ ''+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
'+ '
' ); this.dom = { container: structure, date: structure.find( '.'+classPrefix+'-date' ), title: structure.find( '.'+classPrefix+'-title' ), calendar: structure.find( '.'+classPrefix+'-calendar' ), time: structure.find( '.'+classPrefix+'-time' ), error: structure.find( '.'+classPrefix+'-error' ), input: $(input) }; this.s = { /** @type {Date} Date value that the picker has currently selected */ d: null, /** @type {Date} Date of the calendar - might not match the value */ display: null, /** @type {number} Used to select minutes in a range where the range base is itself unavailable */ minutesRange: null, /** @type {number} Used to select minutes in a range where the range base is itself unavailable */ secondsRange: null, /** @type {String} Unique namespace string for this instance */ namespace: 'dateime-'+(DateTime._instance++), /** @type {Object} Parts of the picker that should be shown */ parts: { date: this.c.format.match( /[YMD]|L(?!T)|l/ ) !== null, time: this.c.format.match( /[Hhm]|LT|LTS/ ) !== null, seconds: this.c.format.indexOf( 's' ) !== -1, hours12: this.c.format.match( /[haA]/ ) !== null } }; this.dom.container .append( this.dom.date ) .append( this.dom.time ) .append( this.dom.error ); this.dom.date .append( this.dom.title ) .append( this.dom.calendar ); this._constructor(); }; $.extend( DateTime.prototype, { /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Public */ /** * Destroy the control */ destroy: function () { this._hide(true); this.dom.container.off().empty(); this.dom.input.off('.datetime'); }, errorMsg: function ( msg ) { var error = this.dom.error; if ( msg ) { error.html( msg ); } else { error.empty(); } return this; }, hide: function () { this._hide(); return this; }, max: function ( date ) { this.c.maxDate = typeof date === 'string' ? new Date(date) : date; this._optionsTitle(); this._setCalander(); return this; }, min: function ( date ) { this.c.minDate = typeof date === 'string' ? new Date(date) : date; this._optionsTitle(); this._setCalander(); return this; }, /** * Check if an element belongs to this control * * @param {node} node Element to check * @return {boolean} true if owned by this control, false otherwise */ owns: function ( node ) { return $(node).parents().filter( this.dom.container ).length > 0; }, /** * Get / set the value * * @param {string|Date} set Value to set * @param {boolean} [write=true] Flag to indicate if the formatted value * should be written into the input element */ val: function ( set, write ) { if ( set === undefined$1 ) { return this.s.d; } if ( set instanceof Date ) { this.s.d = this._dateToUtc( set ); } else if ( set === null || set === '' ) { this.s.d = null; } else if ( set === '--now' ) { this.s.d = new Date(); } else if ( typeof set === 'string' ) { if ( dateLib ) { // Use moment or dayjs if possible (even for ISO8601 strings, since it // will correctly handle 0000-00-00 and the like) var m = dateLib.utc( set, this.c.format, this.c.locale, this.c.strict ); this.s.d = m.isValid() ? m.toDate() : null; } else { // Else must be using ISO8601 without a date library (constructor would // have thrown an error otherwise) var match = set.match(/(\d{4})\-(\d{2})\-(\d{2})/ ); this.s.d = match ? new Date( Date.UTC(match[1], match[2]-1, match[3]) ) : null; } } if ( write || write === undefined$1 ) { if ( this.s.d ) { this._writeOutput(); } else { // The input value was not valid... this.dom.input.val( set ); } } // We need a date to be able to display the calendar at all if ( ! this.s.d ) { this.s.d = this._dateToUtc( new Date() ); } this.s.display = new Date( this.s.d.toString() ); // Set the day of the month to be 1 so changing between months doesn't // run into issues when going from day 31 to 28 (for example) this.s.display.setUTCDate( 1 ); // Update the display elements for the new value this._setTitle(); this._setCalander(); this._setTime(); return this; }, /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Constructor */ /** * Build the control and assign initial event handlers * * @private */ _constructor: function () { var that = this; var classPrefix = this.c.classPrefix; var onChange = function () { that.c.onChange.call( that, that.dom.input.val(), that.s.d, that.dom.input ); }; if ( ! this.s.parts.date ) { this.dom.date.css( 'display', 'none' ); } if ( ! this.s.parts.time ) { this.dom.time.css( 'display', 'none' ); } if ( ! this.s.parts.seconds ) { this.dom.time.children('div.'+classPrefix+'-seconds').remove(); this.dom.time.children('span').eq(1).remove(); } // Render the options this._optionsTitle(); window.allan = this; // When attached to a hidden input, we always show the input picker, and // do so inline if (this.dom.input.attr('type') === 'hidden') { this.dom.container.addClass('inline'); this.c.attachTo = 'input'; this.val( this.dom.input.val(), false ); this._show(); } // Trigger the display of the widget when clicking or focusing on the // input element this.dom.input .attr('autocomplete', 'off') .on('focus.datetime click.datetime', function () { // If already visible - don't do anything if ( that.dom.container.is(':visible') || that.dom.input.is(':disabled') ) { return; } // In case the value has changed by text that.val( that.dom.input.val(), false ); that._show(); } ) .on('keyup.datetime', function () { // Update the calendar's displayed value as the user types if ( that.dom.container.is(':visible') ) { that.val( that.dom.input.val(), false ); } } ); // Main event handlers for input in the widget this.dom.container .on( 'change', 'select', function () { var select = $(this); var val = select.val(); if ( select.hasClass(classPrefix+'-month') ) { // Month select that._correctMonth( that.s.display, val ); that._setTitle(); that._setCalander(); } else if ( select.hasClass(classPrefix+'-year') ) { // Year select that.s.display.setUTCFullYear( val ); that._setTitle(); that._setCalander(); } else if ( select.hasClass(classPrefix+'-hours') || select.hasClass(classPrefix+'-ampm') ) { // Hours - need to take account of AM/PM input if present if ( that.s.parts.hours12 ) { var hours = $(that.dom.container).find('.'+classPrefix+'-hours').val() * 1; var pm = $(that.dom.container).find('.'+classPrefix+'-ampm').val() === 'pm'; that.s.d.setUTCHours( hours === 12 && !pm ? 0 : pm && hours !== 12 ? hours + 12 : hours ); } else { that.s.d.setUTCHours( val ); } that._setTime(); that._writeOutput( true ); onChange(); } else if ( select.hasClass(classPrefix+'-minutes') ) { // Minutes select that.s.d.setUTCMinutes( val ); that._setTime(); that._writeOutput( true ); onChange(); } else if ( select.hasClass(classPrefix+'-seconds') ) { // Seconds select that.s.d.setSeconds( val ); that._setTime(); that._writeOutput( true ); onChange(); } that.dom.input.focus(); that._position(); } ) .on( 'click', function (e) { var d = that.s.d; var nodeName = e.target.nodeName.toLowerCase(); var target = nodeName === 'span' ? e.target.parentNode : e.target; nodeName = target.nodeName.toLowerCase(); if ( nodeName === 'select' ) { return; } e.stopPropagation(); if ( nodeName === 'button' ) { var button = $(target); var parent = button.parent(); if ( parent.hasClass('disabled') && ! parent.hasClass('range') ) { button.blur(); return; } if ( parent.hasClass(classPrefix+'-iconLeft') ) { // Previous month that.s.display.setUTCMonth( that.s.display.getUTCMonth()-1 ); that._setTitle(); that._setCalander(); that.dom.input.focus(); } else if ( parent.hasClass(classPrefix+'-iconRight') ) { // Next month that._correctMonth( that.s.display, that.s.display.getUTCMonth()+1 ); that._setTitle(); that._setCalander(); that.dom.input.focus(); } else if ( button.parents('.'+classPrefix+'-time').length ) { var val = button.data('value'); var unit = button.data('unit'); if ( unit === 'minutes' ) { if ( parent.hasClass('disabled') && parent.hasClass('range') ) { that.s.minutesRange = val; that._setTime(); return; } else { that.s.minutesRange = null; } } if ( unit === 'seconds' ) { if ( parent.hasClass('disabled') && parent.hasClass('range') ) { that.s.secondsRange = val; that._setTime(); return; } else { that.s.secondsRange = null; } } // Specific to hours for 12h clock if ( val === 'am' ) { if ( d.getUTCHours() >= 12 ) { val = d.getUTCHours() - 12; } else { return; } } else if ( val === 'pm' ) { if ( d.getUTCHours() < 12 ) { val = d.getUTCHours() + 12; } else { return; } } var set = unit === 'hours' ? 'setUTCHours' : unit === 'minutes' ? 'setUTCMinutes' : 'setSeconds'; d[set]( val ); that._setTime(); that._writeOutput( true ); onChange(); } else { // Calendar click if ( ! d ) { d = that._dateToUtc( new Date() ); } // Can't be certain that the current day will exist in // the new month, and likewise don't know that the // new day will exist in the old month, But 1 always // does, so we can change the month without worry of a // recalculation being done automatically by `Date` d.setUTCDate( 1 ); d.setUTCFullYear( button.data('year') ); d.setUTCMonth( button.data('month') ); d.setUTCDate( button.data('day') ); that._writeOutput( true ); // Don't hide if there is a time picker, since we want to // be able to select a time as well. if ( ! that.s.parts.time ) { // This is annoying but IE has some kind of async // behaviour with focus and the focus from the above // write would occur after this hide - resulting in the // calendar opening immediately setTimeout( function () { that._hide(); }, 10 ); } else { that._setCalander(); } onChange(); } } else { // Click anywhere else in the widget - return focus to the // input element that.dom.input.focus(); } } ); }, /* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * Private */ /** * Compare the date part only of two dates - this is made super easy by the * toDateString method! * * @param {Date} a Date 1 * @param {Date} b Date 2 * @private */ _compareDates: function( a, b ) { // Can't use toDateString as that converts to local time return this._dateToUtcString(a) === this._dateToUtcString(b); }, /** * When changing month, take account of the fact that some months don't have * the same number of days. For example going from January to February you * can have the 31st of Jan selected and just add a month since the date * would still be 31, and thus drop you into March. * * @param {Date} date Date - will be modified * @param {integer} month Month to set * @private */ _correctMonth: function ( date, month ) { var days = this._daysInMonth( date.getUTCFullYear(), month ); var correctDays = date.getUTCDate() > days; date.setUTCMonth( month ); if ( correctDays ) { date.setUTCDate( days ); date.setUTCMonth( month ); } }, /** * Get the number of days in a method. Based on * http://stackoverflow.com/a/4881951 by Matti Virkkunen * * @param {integer} year Year * @param {integer} month Month (starting at 0) * @private */ _daysInMonth: function ( year, month ) { // var isLeap = ((year % 4) === 0 && ((year % 100) !== 0 || (year % 400) === 0)); var months = [31, (isLeap ? 29 : 28), 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; return months[month]; }, /** * Create a new date object which has the UTC values set to the local time. * This allows the local time to be used directly for the library which * always bases its calculations and display on UTC. * * @param {Date} s Date to "convert" * @return {Date} Shifted date */ _dateToUtc: function ( s ) { return new Date( Date.UTC( s.getFullYear(), s.getMonth(), s.getDate(), s.getHours(), s.getMinutes(), s.getSeconds() ) ); }, /** * Create a UTC ISO8601 date part from a date object * * @param {Date} d Date to "convert" * @return {string} ISO formatted date */ _dateToUtcString: function ( d ) { return d.getUTCFullYear()+'-'+ this._pad(d.getUTCMonth()+1)+'-'+ this._pad(d.getUTCDate()); }, /** * Hide the control and remove events related to its display * * @private */ _hide: function (destroy) { if (! destroy && this.dom.input.attr('type') === 'hidden') { return; } var namespace = this.s.namespace; this.dom.container.detach(); $(window).off( '.'+namespace ); $(document).off( 'keydown.'+namespace ); $('div.dataTables_scrollBody').off( 'scroll.'+namespace ); $('div.DTE_Body_Content').off( 'scroll.'+namespace ); $('body').off( 'click.'+namespace ); }, /** * Convert a 24 hour value to a 12 hour value * * @param {integer} val 24 hour value * @return {integer} 12 hour value * @private */ _hours24To12: function ( val ) { return val === 0 ? 12 : val > 12 ? val - 12 : val; }, /** * Generate the HTML for a single day in the calendar - this is basically * and HTML cell with a button that has data attributes so we know what was * clicked on (if it is clicked on) and a bunch of classes for styling. * * @param {object} day Day object from the `_htmlMonth` method * @return {string} HTML cell */ _htmlDay: function( day ) { if ( day.empty ) { return ''; } var classes = [ 'selectable' ]; var classPrefix = this.c.classPrefix; if ( day.disabled ) { classes.push( 'disabled' ); } if ( day.today ) { classes.push( 'now' ); } if ( day.selected ) { classes.push( 'selected' ); } return '' + '' + ''; }, /** * Create the HTML for a month to be displayed in the calendar table. * * Based upon the logic used in Pikaday - MIT licensed * Copyright (c) 2014 David Bushell * https://github.com/dbushell/Pikaday * * @param {integer} year Year * @param {integer} month Month (starting at 0) * @return {string} Calendar month HTML * @private */ _htmlMonth: function ( year, month ) { var now = this._dateToUtc( new Date() ), days = this._daysInMonth( year, month ), before = new Date( Date.UTC(year, month, 1) ).getUTCDay(), data = [], row = []; if ( this.c.firstDay > 0 ) { before -= this.c.firstDay; if (before < 0) { before += 7; } } var cells = days + before, after = cells; while ( after > 7 ) { after -= 7; } cells += 7 - after; var minDate = this.c.minDate; var maxDate = this.c.maxDate; if ( minDate ) { minDate.setUTCHours(0); minDate.setUTCMinutes(0); minDate.setSeconds(0); } if ( maxDate ) { maxDate.setUTCHours(23); maxDate.setUTCMinutes(59); maxDate.setSeconds(59); } for ( var i=0, r=0 ; i= (days + before), disabled = (minDate && day < minDate) || (maxDate && day > maxDate); var disableDays = this.c.disableDays; if ( Array.isArray( disableDays ) && $.inArray( day.getUTCDay(), disableDays ) !== -1 ) { disabled = true; } else if ( typeof disableDays === 'function' && disableDays( day ) === true ) { disabled = true; } var dayConfig = { day: 1 + (i - before), month: month, year: year, selected: selected, today: today, disabled: disabled, empty: empty }; row.push( this._htmlDay(dayConfig) ); if ( ++r === 7 ) { if ( this.c.showWeekNumber ) { row.unshift( this._htmlWeekOfYear(i - before, month, year) ); } data.push( ''+row.join('')+'' ); row = []; r = 0; } } var classPrefix = this.c.classPrefix; var className = classPrefix+'-table'; if ( this.c.showWeekNumber ) { className += ' weekNumber'; } // Show / hide month icons based on min/max if ( minDate ) { var underMin = minDate >= new Date( Date.UTC(year, month, 1, 0, 0, 0 ) ); this.dom.title.find('div.'+classPrefix+'-iconLeft') .css( 'display', underMin ? 'none' : 'block' ); } if ( maxDate ) { var overMax = maxDate < new Date( Date.UTC(year, month+1, 1, 0, 0, 0 ) ); this.dom.title.find('div.'+classPrefix+'-iconRight') .css( 'display', overMax ? 'none' : 'block' ); } return '' + ''+ this._htmlMonthHead() + ''+ ''+ data.join('') + ''+ '
'; }, /** * Create the calendar table's header (week days) * * @return {string} HTML cells for the row * @private */ _htmlMonthHead: function () { var a = []; var firstDay = this.c.firstDay; var i18n = this.c.i18n; // Take account of the first day shift var dayName = function ( day ) { day += firstDay; while (day >= 7) { day -= 7; } return i18n.weekdays[day]; }; // Empty cell in the header if ( this.c.showWeekNumber ) { a.push( '' ); } for ( var i=0 ; i<7 ; i++ ) { a.push( ''+dayName( i )+'' ); } return a.join(''); }, /** * Create a cell that contains week of the year - ISO8601 * * Based on https://stackoverflow.com/questions/6117814/ and * http://techblog.procurios.nl/k/n618/news/view/33796/14863/ * * @param {integer} d Day of month * @param {integer} m Month of year (zero index) * @param {integer} y Year * @return {string} * @private */ _htmlWeekOfYear: function ( d, m, y ) { var date = new Date( y, m, d, 0, 0, 0, 0 ); // First week of the year always has 4th January in it date.setDate( date.getDate() + 4 - (date.getDay() || 7) ); var oneJan = new Date( y, 0, 1 ); var weekNum = Math.ceil( ( ( (date - oneJan) / 86400000) + 1)/7 ); return '' + weekNum + ''; }, /** * Create option elements from a range in an array * * @param {string} selector Class name unique to the select element to use * @param {array} values Array of values * @param {array} [labels] Array of labels. If given must be the same * length as the values parameter. * @private */ _options: function ( selector, values, labels ) { if ( ! labels ) { labels = values; } var select = this.dom.container.find('select.'+this.c.classPrefix+'-'+selector); select.empty(); for ( var i=0, ien=values.length ; i'+labels[i]+'' ); } }, /** * Set an option and update the option's span pair (since the select element * has opacity 0 for styling) * * @param {string} selector Class name unique to the select element to use * @param {*} val Value to set * @private */ _optionSet: function ( selector, val ) { var select = this.dom.container.find('select.'+this.c.classPrefix+'-'+selector); var span = select.parent().children('span'); select.val( val ); var selected = select.find('option:selected'); span.html( selected.length !== 0 ? selected.text() : this.c.i18n.unknown ); }, /** * Create time options list. * * @param {string} unit Time unit - hours, minutes or seconds * @param {integer} count Count range - 12, 24 or 60 * @param {integer} val Existing value for this unit * @param {integer[]} allowed Values allow for selection * @param {integer} range Override range * @private */ _optionsTime: function ( unit, count, val, allowed, range ) { var classPrefix = this.c.classPrefix; var container = this.dom.container.find('div.'+classPrefix+'-'+unit); var i, j; var render = count === 12 ? function (i) { return i; } : this._pad; var classPrefix = this.c.classPrefix; var className = classPrefix+'-table'; var i18n = this.c.i18n; if ( ! container.length ) { return; } var a = ''; var span = 10; var button = function (value, label, className) { // Shift the value for PM if ( count === 12 && typeof value === 'number' ) { if (val >= 12 ) { value += 12; } if (value == 12) { value = 0; } else if (value == 24) { value = 12; } } var selected = val === value || (value === 'am' && val < 12) || (value === 'pm' && val >= 12) ? 'selected' : ''; if (allowed && $.inArray(value, allowed) === -1) { selected += ' disabled'; } if ( className ) { selected += ' '+className; } return '' + '' + ''; }; if ( count === 12 ) { // Hours with AM/PM a += ''; for ( i=1 ; i<=6 ; i++ ) { a += button(i, render(i)); } a += button('am', i18n.amPm[0]); a += ''; a += ''; for ( i=7 ; i<=12 ; i++ ) { a += button(i, render(i)); } a += button('pm', i18n.amPm[1]); a += ''; span = 7; } else if ( count === 24 ) { // Hours - 24 var c = 0; for (j=0 ; j<4 ; j++ ) { a += ''; for ( i=0 ; i<6 ; i++ ) { a += button(c, render(c)); c++; } a += ''; } span = 6; } else { // Minutes and seconds a += ''; for (j=0 ; j<60 ; j+=10 ) { a += button(j, render(j), 'range'); } a += ''; // Slight hack to allow for the different number of columns a += ''; var start = range !== null ? range : Math.floor( val / 10 )*10; a += ''; for (j=start+1 ; j'+ ''+ ''+ a+ ''+ '
'+ i18n[unit] + '
' ); }, /** * Create the options for the month and year * * @param {integer} year Year * @param {integer} month Month (starting at 0) * @private */ _optionsTitle: function () { var i18n = this.c.i18n; var min = this.c.minDate; var max = this.c.maxDate; var minYear = min ? min.getFullYear() : null; var maxYear = max ? max.getFullYear() : null; var i = minYear !== null ? minYear : new Date().getFullYear() - this.c.yearRange; var j = maxYear !== null ? maxYear : new Date().getFullYear() + this.c.yearRange; this._options( 'month', this._range( 0, 11 ), i18n.months ); this._options( 'year', this._range( i, j ) ); }, /** * Simple two digit pad * * @param {integer} i Value that might need padding * @return {string|integer} Padded value * @private */ _pad: function ( i ) { return i<10 ? '0'+i : i; }, /** * Position the calendar to look attached to the input element * @private */ _position: function () { var offset = this.c.attachTo === 'input' ? this.dom.input.position() : this.dom.input.offset(); var container = this.dom.container; var inputHeight = this.dom.input.outerHeight(); if (container.hasClass('inline')) { container.insertAfter( this.dom.input ); return; } if ( this.s.parts.date && this.s.parts.time && $(window).width() > 550 ) { container.addClass('horizontal'); } else { container.removeClass('horizontal'); } if(this.c.attachTo === 'input') { container .css( { top: offset.top + inputHeight, left: offset.left } ) .insertAfter( this.dom.input ); } else { container .css( { top: offset.top + inputHeight, left: offset.left } ) .appendTo( 'body' ); } var calHeight = container.outerHeight(); var calWidth = container.outerWidth(); var scrollTop = $(window).scrollTop(); // Correct to the bottom if ( offset.top + inputHeight + calHeight - scrollTop > $(window).height() ) { var newTop = offset.top - calHeight; container.css( 'top', newTop < 0 ? 0 : newTop ); } // Correct to the right if ( calWidth + offset.left > $(window).width() ) { var newLeft = $(window).width() - calWidth; // Account for elements which are inside a position absolute element if (this.c.attachTo === 'input') { newLeft -= $(container).offsetParent().offset().left; } container.css( 'left', newLeft < 0 ? 0 : newLeft ); } }, /** * Create a simple array with a range of values * * @param {integer} start Start value (inclusive) * @param {integer} end End value (inclusive) * @param {integer} [inc=1] Increment value * @return {array} Created array * @private */ _range: function ( start, end, inc ) { var a = []; if ( ! inc ) { inc = 1; } for ( var i=start ; i<=end ; i+=inc ) { a.push( i ); } return a; }, /** * Redraw the calendar based on the display date - this is a destructive * operation * * @private */ _setCalander: function () { if ( this.s.display ) { this.dom.calendar .empty() .append( this._htmlMonth( this.s.display.getUTCFullYear(), this.s.display.getUTCMonth() ) ); } }, /** * Set the month and year for the calendar based on the current display date * * @private */ _setTitle: function () { this._optionSet( 'month', this.s.display.getUTCMonth() ); this._optionSet( 'year', this.s.display.getUTCFullYear() ); }, /** * Set the time based on the current value of the widget * * @private */ _setTime: function () { var that = this; var d = this.s.d; var hours = d ? d.getUTCHours() : 0; var allowed = function ( prop ) { // Backwards compt with `Increment` option return that.c[prop+'Available'] ? that.c[prop+'Available'] : that._range( 0, 59, that.c[prop+'Increment'] ); }; this._optionsTime( 'hours', this.s.parts.hours12 ? 12 : 24, hours, this.c.hoursAvailable ); this._optionsTime( 'minutes', 60, d ? d.getUTCMinutes() : 0, allowed('minutes'), this.s.minutesRange ); this._optionsTime( 'seconds', 60, d ? d.getSeconds() : 0, allowed('seconds'), this.s.secondsRange ); }, /** * Show the widget and add events to the document required only while it * is displayed * * @private */ _show: function () { var that = this; var namespace = this.s.namespace; this._position(); // Need to reposition on scroll $(window).on( 'scroll.'+namespace+' resize.'+namespace, function () { that._hide(); } ); $('div.DTE_Body_Content').on( 'scroll.'+namespace, function () { that._hide(); } ); $('div.dataTables_scrollBody').on( 'scroll.'+namespace, function () { that._hide(); } ); var offsetParent = this.dom.input[0].offsetParent; if ( offsetParent !== document.body ) { $(offsetParent).on( 'scroll.'+namespace, function () { that._hide(); } ); } // On tab focus will move to a different field (no keyboard navigation // in the date picker - this might need to be changed). $(document).on( 'keydown.'+namespace, function (e) { if ( e.keyCode === 9 || // tab e.keyCode === 27 || // esc e.keyCode === 13 // return ) { that._hide(); } } ); // Hide if clicking outside of the widget - but in a different click // event from the one that was used to trigger the show (bubble and // inline) setTimeout( function () { $('body').on( 'click.'+namespace, function (e) { var parents = $(e.target).parents(); if ( ! parents.filter( that.dom.container ).length && e.target !== that.dom.input[0] ) { that._hide(); } } ); }, 10 ); }, /** * Write the formatted string to the input element this control is attached * to * * @private */ _writeOutput: function ( focus ) { var date = this.s.d; // Use moment or dayjs if possible - otherwise it must be ISO8601 (or the // constructor would have thrown an error) var out = dateLib ? dateLib.utc( date, undefined$1, this.c.locale, this.c.strict ).format( this.c.format ) : date.getUTCFullYear() +'-'+ this._pad(date.getUTCMonth() + 1) +'-'+ this._pad(date.getUTCDate()); this.dom.input .val( out ) .trigger('change', {write: date}); if ( this.dom.input.attr('type') === 'hidden' ) { this.val(out, false); } if ( focus ) { this.dom.input.focus(); } } } ); /** * Use a specificmoment compatible date library */ DateTime.use = function (lib) { dateLib = lib; }; /** * For generating unique namespaces * * @type {Number} * @private */ DateTime._instance = 0; /** * Defaults for the date time picker * * @type {Object} */ DateTime.defaults = { attachTo: 'body', // Not documented - could be an internal property classPrefix: 'dt-datetime', // function or array of ints disableDays: null, // first day of the week (0: Sunday, 1: Monday, etc) firstDay: 1, format: 'YYYY-MM-DD', hoursAvailable: null, i18n: { previous: 'Previous', next: 'Next', months: [ 'January', 'February', 'March', 'April', 'May', 'June', 'July', 'August', 'September', 'October', 'November', 'December' ], weekdays: [ 'Sun', 'Mon', 'Tue', 'Wed', 'Thu', 'Fri', 'Sat' ], amPm: [ 'am', 'pm' ], hours: 'Hour', minutes: 'Minute', seconds: 'Second', unknown: '-' }, maxDate: null, minDate: null, minutesAvailable: null, minutesIncrement: 1, // deprecated strict: true, locale: 'en', onChange: function () {}, secondsAvailable: null, secondsIncrement: 1, // deprecated // show the ISO week number at the head of the row showWeekNumber: false, // overruled by max / min date yearRange: 25 }; DateTime.version = '1.0.1'; // Global export - if no conflicts if (! window.DateTime) { window.DateTime = DateTime; } // Make available via jQuery $.fn.dtDateTime = function (options) { return this.each(function() { new DateTime(this, options); }); }; // Attach to DataTables if present if ($.fn.dataTable) { $.fn.dataTable.DateTime = DateTime; $.fn.DataTable.DateTime = DateTime; } return DateTime; })); var $; var DataTable; var moment = window.moment; /** * Sets the value of jQuery for use in the file * @param jq the instance of jQuery to be set */ function setJQuery(jq) { $ = jq; DataTable = jq.fn.dataTable; } /** * The Criteria class is used within SearchBuilder to represent a search criteria */ var Criteria = /** @class */ (function () { function Criteria(table, opts, topGroup, index, depth) { var _this = this; if (index === void 0) { index = 0; } if (depth === void 0) { depth = 1; } // Check that the required version of DataTables is included if (!DataTable || !DataTable.versionCheck || !DataTable.versionCheck('1.10.0')) { throw new Error('SearchPane requires DataTables 1.10 or newer'); } this.classes = $.extend(true, {}, Criteria.classes); // Get options from user and any extra conditions/column types defined by plug-ins this.c = $.extend(true, {}, Criteria.defaults, $.fn.dataTable.ext.searchBuilder, opts); var i18n = this.c.i18n; this.s = { condition: undefined, conditions: {}, data: undefined, dataIdx: -1, dataPoints: [], depth: depth, dt: table, filled: false, index: index, momentFormat: false, topGroup: topGroup, type: '', value: [] }; this.dom = { buttons: $('
') .addClass(this.classes.buttonContainer), condition: $('') .addClass(this.classes.data) .addClass(this.classes.dropDown) .addClass(this.classes.italic), dataTitle: $('