Javascript Source
You can view the full source code for jquery.agjCalendar.js below.
In production environments we recommend you use jquery.agjCalendar.min.js.
/**
* Javascript source code of agjCalendar v1.1.0.
*
* Copyright (c) 2013-2024 Andrew G. Johnson <andrew@andrewgjohnson.com>
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to
* deal in the Software without restriction, including without limitation the
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
* sell copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
* IN THE SOFTWARE.
* @file The Javascript source code for the agjCalendar jQuery plugin.
* @copyright 2013-2024 Andrew G. Johnson <andrew@andrewgjohnson.com>
* @license MIT
* @see {@link https://github.com/andrewgjohnson/agjCalendar GitHub Repository}
* @see {@link https://agjCalendar.agjjQuery.org/ Online Documentation}
* @author Andrew G. Johnson <andrew@andrewgjohnson.com>
* @version 1.1.0
*/
/* global jQuery */
(function($) {
var agjCalendars = [];
var lastClickWasOnAgjCalendar = false;
var lastBodyMarginRight = '';
var lastBodyOverflow = '';
var lastScrollLeft = 0;
var lastScrollTop = 0;
var regexPatterns = {
// date format 1 = MM/DD/YYYY, e.g. 01/02/2003
'1': new RegExp(/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/),
// date format 2 = MMM D, YYYY, e.g. Jan 2, 2003
'2': new RegExp(/^([A-Za-zÀ-ÖØ-öø-ÿ]+) ([0-9]{1,2}), ([0-9]{4})$/),
// date format 3 = DD/MM/YYYY, e.g. 02/01/2003
'3': new RegExp(/^([0-9]{2})\/([0-9]{2})\/([0-9]{4})$/),
// date format 4 = YYYY-MM-DD, e.g. 2003-01-02
'4': new RegExp(/^([0-9]{4})-([0-9]{2})-([0-9]{2})$/),
// date format 5 = D MMMM YYYY, e.g. 2 January 2003
'5': new RegExp(/^([0-9]{1,2}) ([A-Za-zÀ-ÖØ-öø-ÿ]+) ([0-9]{4})$/),
// YYYY-MM, e.g. 2003-01
'month': new RegExp(/^([0-9]{4})-([0-9]{2})$/)
};
var translations = {
// English
en: {
days: {
full: {
0: 'Sunday',
1: 'Monday',
2: 'Tuesday',
3: 'Wednesday',
4: 'Thursday',
5: 'Friday',
6: 'Saturday'
},
medium: {
0: 'Sun',
1: 'Mon',
2: 'Tue',
3: 'Wed',
4: 'Thu',
5: 'Fri',
6: 'Sat'
},
short: {
0: 'S',
1: 'M',
2: 'T',
3: 'W',
4: 'T',
5: 'F',
6: 'S'
}
},
months: {
full: {
0: 'January',
1: 'February',
2: 'March',
3: 'April',
4: 'May',
5: 'June',
6: 'July',
7: 'August',
8: 'September',
9: 'October',
10: 'November',
11: 'December'
},
abbreviated: {
0: 'Jan',
1: 'Feb',
2: 'Mar',
3: 'Apr',
4: 'May',
5: 'Jun',
6: 'Jul',
7: 'Aug',
8: 'Sep',
9: 'Oct',
10: 'Nov',
11: 'Dec'
}
},
hideCalendar: 'Hide Calendar',
nextMonth: 'Next Month',
previousMonth: 'Previous Month',
poweredBy: 'Powered by',
selectADate: 'Select a Date'
},
// Français (French)
fr: {
days: {
full: {
0: 'dimanche',
1: 'lundi',
2: 'mardi',
3: 'mercredi',
4: 'jeudi',
5: 'vendredi',
6: 'samedi'
},
medium: {
0: 'dim',
1: 'lun',
2: 'mar',
3: 'mer',
4: 'jeu',
5: 'ven',
6: 'sam'
},
short: {
0: 'd',
1: 'l',
2: 'm',
3: 'm',
4: 'j',
5: 'v',
6: 's'
}
},
months: {
full: {
0: 'janvier',
1: 'février',
2: 'mars',
3: 'avril',
4: 'mai',
5: 'juin',
6: 'juillet',
7: 'août',
8: 'septembre',
9: 'octobre',
10: 'novembre',
11: 'décembre'
},
abbreviated: {
0: 'janv',
1: 'févr',
2: 'mars',
3: 'avr',
4: 'mai',
5: 'juin',
6: 'juil',
7: 'août',
8: 'sept',
9: 'octo',
10: 'nov',
11: 'déc'
}
},
hideCalendar: 'Masquer le calendrier',
nextMonth: 'Le mois prochain',
previousMonth: 'Le mois précédent',
poweredBy: 'Propulsé par',
selectADate: 'Sélectionnez une date'
}
};
/**
* The activateCalendar() function will activate an integration.
* @param {object} agjCalendar - The integration to activate.
* @param {boolean} activateEnd - Whether or not to activate on the end input.
* @returns {void}
*/
var activateCalendar = function(agjCalendar, activateEnd) {
if (activateEnd !== true) {
activateEnd = false;
}
// if there is an active date picker but it isn’t this one
if (
$.agjCalendar.isActive() &&
!checkIfActive(agjCalendar['position'], activateEnd)
) {
hideModalBackground();
}
switch (agjCalendar['inputType']) {
case 'text':
$(agjCalendar[activateEnd ? 'endDateSelector' : 'dateSelector'])
.addClass('agjCalendar-active-input');
break;
case 'dropdown':
$(agjCalendar[activateEnd ? 'endMonthSelector' : 'monthSelector'])
.addClass('agjCalendar-active-input');
$(agjCalendar[activateEnd ? 'endDaySelector' : 'daySelector'])
.addClass('agjCalendar-active-input');
break;
}
var calendarElement = $('#agjCalendar');
if (calendarElement.length === 0) {
calendarElement = createDomElements();
}
var modalBackgroundElement = $('#agjCalendar-modal-background');
calendarElement.attr({
'class': '', // remove all classes
'data-active': agjCalendar['position'],
'data-active-is-end': activateEnd
});
if (agjCalendar['theme'].length > 0) {
// remove any active themes from the modal background element
var modalBackgroundClasses = modalBackgroundElement.attr('class');
if (
typeof modalBackgroundClasses === 'string' &&
modalBackgroundClasses.length > 0
) {
modalBackgroundClasses = modalBackgroundClasses.split(' ');
for (var i = 0; i < modalBackgroundClasses.length; i++) {
if (modalBackgroundClasses[i].indexOf('agjCalendar-theme-') === 0) {
modalBackgroundElement.removeClass(modalBackgroundClasses[i]);
}
}
}
modalBackgroundElement
.addClass('agjCalendar-theme-' + agjCalendar['theme']);
calendarElement.addClass('agjCalendar-theme-' + agjCalendar['theme']);
}
calendarElement.find('#agjCalendar-hide').attr(
'title',
translations[agjCalendar['language']]['hideCalendar']
).text(translations[agjCalendar['language']]['hideCalendar']);
calendarElement.find('#agjCalendar-header-inner span').text(
translations[agjCalendar['language']]['poweredBy']
);
calendarElement.find('a.agjCalendar-previous-month').attr(
'title',
translations[agjCalendar['language']]['previousMonth']
).find('span.agjCalendar-previous-month-inner').text(
translations[agjCalendar['language']]['previousMonth']
);
calendarElement.find('a.agjCalendar-next-month').attr(
'title',
translations[agjCalendar['language']]['nextMonth']
).find('span.agjCalendar-next-month-inner').text(
translations[agjCalendar['language']]['nextMonth']
);
switch (agjCalendar['calendarCount']) {
case 2:
calendarElement.addClass('agjCalendar-double');
break;
case 3:
calendarElement.addClass('agjCalendar-triple');
break;
default:
calendarElement.addClass('agjCalendar-single');
break;
}
if (agjCalendar['startWeekOnMonday']) {
calendarElement.addClass('agjCalendar-start-week-on-monday');
} else {
calendarElement.removeClass('agjCalendar-start-week-on-monday');
}
var days;
if (agjCalendar['startWeekOnMonday']) {
days = [1, 2, 3, 4, 5, 6, 0];
} else {
days = [0, 1, 2, 3, 4, 5, 6];
}
var daysMarkup = '';
for (var i = 0; i < days.length; i++) {
var className = 'agjCalendar-' + dayNumberToName(
days[i],
'full',
'en'
).toLowerCase();
var fullDayName = dayNumberToName(
days[i],
'full',
agjCalendar['language']
);
var customDayName = dayNumberToName(
days[i],
agjCalendar['dayNameFormat'],
agjCalendar['language']
);
daysMarkup += '<div';
daysMarkup += ' class="' + className + '"';
daysMarkup += ' title="' + fullDayName + '"';
daysMarkup += '>';
daysMarkup += customDayName;
daysMarkup +='</div>';
}
calendarElement.find('div.agjCalendar-days').empty().append(daysMarkup);
// prevent scrolling while modal/full display is active using CSS
switch (agjCalendar['calendarDisplay']) {
case 'full':
case 'modal':
var bodyElement = $('body');
lastBodyMarginRight = getCssValueInPixels(
bodyElement.css('marginRight')
);
if (isNaN(lastBodyMarginRight)) {
lastBodyMarginRight = 0;
}
lastBodyOverflow = bodyElement.css('overflow');
var windowWidth = $(window).width();
bodyElement.css({
overflow: 'hidden'
}).css({
// we do these CSS calls separately because the $(window).width()
// value will only change after overflow:hidden is applied to the
// <body> element
marginRight: lastBodyMarginRight + $(window).width() - windowWidth
});
lastScrollLeft = $(window).scrollLeft();
lastScrollTop = $(window).scrollTop();
if (agjCalendar['calendarDisplay'] === 'full') {
// because full calendar display uses the entire display we scroll to
// the top of the page to ensure the address bar is not visible on
// mobile/touch devices
window.scrollTo(0, 1);
window.scrollTo(0, 0);
}
$('#agjCalendar-modal-background').show();
break;
}
updateDropdown(agjCalendar, activateEnd);
var monthToDraw = getActiveDate(agjCalendar, activateEnd);
if (monthToDraw === -1) {
var startDate = getActiveDate(agjCalendar, false);
if (startDate !== -1) {
monthToDraw = new Date(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['minimumRange']
);
} else {
monthToDraw = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
if (activateEnd) {
monthToDraw.setFullYear(
monthToDraw.getFullYear(),
monthToDraw.getMonth(),
monthToDraw.getDate() + agjCalendar['minimumRange']
);
}
}
}
redrawCalendars(monthToDraw);
positionCalendar(agjCalendar, activateEnd);
$('body').addClass('agjCalendar-active');
};
/**
* The autoSetEndDate() function will automatically set the end date of an
* integration.
* @param {object} agjCalendar - The integration to automatically set the end
* date of.
* @returns {void}
*/
var autoSetEndDate = function(agjCalendar) {
if (agjCalendar['allowRange']) {
var startDate = getActiveDate(agjCalendar);
if (startDate !== -1) {
var endDateNeedsToChange = false;
var endDateMinimum = new Date(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['minimumRange']
);
if (endDateMaximum < agjCalendar['minimumDate']) {
endDateMinimum.setFullYear(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
}
var endDateMaximum = new Date(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['maximumRange']
);
if (endDateMaximum > agjCalendar['maximumDate']) {
endDateMaximum.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
}
var endDate = getActiveDate(agjCalendar, true);
if (
endDate !== -1 &&
(endDate < endDateMinimum || endDate > endDateMaximum) &&
(
agjCalendar['autoSetEndDate'] === 'always' ||
agjCalendar['autoSetEndDate'] === 'dates'
)
) {
// endDate is a date and is either earlier than the minimum or later
// than the maximum
endDateNeedsToChange = true;
} else if (
endDate === -1 &&
(
agjCalendar['autoSetEndDate'] === 'always' ||
agjCalendar['autoSetEndDate'] === 'blanks'
)
) {
// endDate is a blank
endDateNeedsToChange = true;
}
if (endDateNeedsToChange) {
endDate = new Date(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['defaultRange']
);
if (endDate < endDateMinimum) {
endDate.setFullYear(
endDateMinimum.getFullYear(),
endDateMinimum.getMonth(),
endDateMinimum.getDate()
);
} else if (endDate > endDateMaximum) {
endDate.setFullYear(
endDateMaximum.getFullYear(),
endDateMaximum.getMonth(),
endDateMaximum.getDate()
);
}
setDate(agjCalendar, endDate, true);
}
}
}
};
/**
* The checkIfActive() function will check if a specific integration is
* active.
* @param {number} position - The position of the integration.
* @param {boolean} isEnd - Check if the end date is active.
* @returns {boolean} - Returns true if the integration whose position was
* passed is active or false if not.
*/
var checkIfActive = function(position, isEnd) {
if ($.agjCalendar.isActive()) {
var calendarElement = $('#agjCalendar');
if (parseInt(calendarElement.attr('data-active'), 10) === position) {
var activeIsEnd =
calendarElement.attr('data-active-is-end') === true ||
calendarElement.attr('data-active-is-end') === 'true';
return activeIsEnd === isEnd;
}
}
return false;
};
/**
* The createDomElements() function will create the DOM elements needed for
* the date picker and bind event handlers to them.
* @returns {object} - Returns the newly created agjCalendar DOM element.
*/
var createDomElements = function() {
var calendarElement = $('body').append(
'<div id="agjCalendar-modal-background"></div>' +
'<div id="agjCalendar">' +
'<div id="agjCalendar-header">' +
'<div id="agjCalendar-header-inner">' +
'<a href="#" id="agjCalendar-hide"></a>' +
'<span></span>' +
' ' +
'<a' +
' href="https://agjcalendar.agjjquery.org/"' +
' target="_blank"' +
' title="agjCalendar"' +
' id="agjCalendar-powered-by"' +
'>' +
'agjCalendar' +
'</a>' +
'</div>' +
'</div>' +
'<div id="agjCalendar-body">' +
'<div id="agjCalendar-first">' +
'<div class="agjCalendar-month">' +
'<div class="agjCalendar-month-inner-1">' +
'<div class="agjCalendar-month-inner-2">' +
'<select id="agjCalendar-dropdown"></select>' +
'<a href="#" class="agjCalendar-next-month">' +
'<span class="agjCalendar-next-month-inner"></span>' +
'</a>' +
'<a href="#" class="agjCalendar-previous-month">' +
'<span class="agjCalendar-previous-month-inner"></span>' +
'</a>' +
'</div>' +
'</div>' +
'</div>' +
'<div class="agjCalendar-days"></div>' +
'</div>' +
'<div id="agjCalendar-second">' +
'<div class="agjCalendar-month">' +
'<div class="agjCalendar-month-inner" colspan="5">' +
'<strong id="agjCalendar-second-month-name"></strong>' +
'<a href="#" class="agjCalendar-next-month">' +
'<span class="agjCalendar-next-month-inner"></span>' +
'</a>' +
'<a href="#" class="agjCalendar-previous-month">' +
'<span class="agjCalendar-previous-month-inner"></span>' +
'</a>' +
'</div>' +
'</div>' +
'<div class="agjCalendar-days"></div>' +
'</div>' +
'<div id="agjCalendar-third">' +
'<div class="agjCalendar-month">' +
'<div class="agjCalendar-month-inner" colspan="5">' +
'<strong id="agjCalendar-third-month-name"></strong>' +
'<a href="#" class="agjCalendar-next-month">' +
'<span class="agjCalendar-next-month-inner"></span>' +
'</a>' +
'<a href="#" class="agjCalendar-previous-month">' +
'<span class="agjCalendar-previous-month-inner"></span>' +
'</a>' +
'</div>' +
'</div>' +
'<div class="agjCalendar-days"></div>' +
'</div>' +
'</div>' +
'</div>'
).find('#agjCalendar');
calendarElement.find('#agjCalendar-hide').on('click', function() {
$.agjCalendar.deactivate();
return false;
});
calendarElement.find('#agjCalendar-dropdown').on('change', function() {
if (regexPatterns['month'].test($(this).val())) {
var firstDayOfTheMonth = new Date(
$(this).val().substring(0, 4),
parseInt($(this).val().substring(5, 7), 10) - 1,
1
);
redrawCalendars(firstDayOfTheMonth);
}
});
calendarElement.find(
'a.agjCalendar-previous-month, a.agjCalendar-next-month'
).on('click', function() {
if (regexPatterns['month'].test($('#agjCalendar-dropdown').val())) {
var firstDayOfTheMonth = new Date(
$('#agjCalendar-dropdown').val().substring(0, 4),
parseInt($('#agjCalendar-dropdown').val().substring(5, 7), 10) - 1,
1
);
if ($(this).hasClass('agjCalendar-previous-month')) {
firstDayOfTheMonth.setFullYear(
firstDayOfTheMonth.getFullYear(),
firstDayOfTheMonth.getMonth() - 1,
firstDayOfTheMonth.getDate()
);
} else if ($(this).hasClass('agjCalendar-next-month')) {
firstDayOfTheMonth.setFullYear(
firstDayOfTheMonth.getFullYear(),
firstDayOfTheMonth.getMonth() + 1,
firstDayOfTheMonth.getDate()
);
}
var newDropdownValue = dateToString(firstDayOfTheMonth, 'YYYY-MM');
if (
calendarElement.find(
'#agjCalendar-dropdown option[value=' + newDropdownValue + ']'
).length > 0
) {
calendarElement.find('#agjCalendar-dropdown')
.val(newDropdownValue)
.trigger('change');
}
}
return false;
});
/**
* The windowSizeChanged() function will handle events where the window
* size may have changed.
* @returns {void}
*/
var windowSizeChanged = function() {
if ($.agjCalendar.isActive()) {
var calendarElement = $('#agjCalendar');
var agjCalendar = agjCalendars[calendarElement.attr('data-active')];
var agjCalendarIsEnd =
calendarElement.attr('data-active-is-end') === true ||
calendarElement.attr('data-active-is-end') === 'true';
positionCalendar(agjCalendar, agjCalendarIsEnd);
}
};
$(window).on('resize', windowSizeChanged);
$(document)
.on('resize', windowSizeChanged)
.on('keyup', function(event) {
if (event.key === 'Escape' && $.agjCalendar.isActive()) {
$('*:focus').trigger('blur');
$.agjCalendar.deactivate();
return false;
}
return true;
})
.on('click', function(event) {
lastClickWasOnAgjCalendar = false;
if ($.agjCalendar.isActive()) {
var targetIsAgjCalendarOrChild =
$(event.target).attr('id') === 'agjCalendar' ||
$(event.target).parents('#agjCalendar').length > 0;
var targetIsActiveInputOrChild =
$(event.target).is('.agjCalendar-active-input') ||
$(event.target).parents('.agjCalendar-active-input').length > 0;
if (targetIsAgjCalendarOrChild || targetIsActiveInputOrChild) {
// if the user clicked on something related to the date picker
// while the date picker is active then use the global flag to
// remember that
lastClickWasOnAgjCalendar = true;
} else if (
!targetIsAgjCalendarOrChild && !targetIsActiveInputOrChild
) {
// if the user clicked on something unrelated to the date picker
// while the date picker is active then possibly deactivate
var calendarDisplay = -1;
var active = $('#agjCalendar').attr('data-active');
if (active >= 0) {
calendarDisplay = agjCalendars[active]['calendarDisplay'];
}
switch (calendarDisplay) {
case 'modal':
case 'full':
// do nothing for modal or full displays
break;
default:
// deactivate the date picker for all other displays
$.agjCalendar.deactivate();
break;
}
}
}
return true;
});
return calendarElement;
};
/**
* The dateToString() function will format a given date with a given format
* in a string.
* @param {Date} date - The date to format into a string.
* @param {string} dateFormat - The date format to return the string in.
* @param {string} language - The language to use.
* @returns {string} - The date formatted as a string.
*/
var dateToString = function(date, dateFormat, language) {
language = language === 'fr' ? language : 'en';
var dateFormats = {
DD: function(date) {
return (date.getDate() < 10 ? '0' : '') + date.getDate();
},
D: function(date) {
return date.getDate();
},
MMMM: function(date) {
return monthNumberToName(date.getMonth(), true, language);
},
MMM: function(date) {
return monthNumberToName(date.getMonth(), false, language);
},
MM: function(date) {
return (date.getMonth() + 1 < 10 ? '0' : '') + (date.getMonth() + 1);
},
M: function(date) {
return date.getMonth() + 1;
},
YYYY: function(date) {
return date.getFullYear();
}
};
var processedString = '';
var processPosition = 0;
while (dateFormat.length > processPosition) {
var dateFormatFound = false;
$.map(dateFormats, function(callbackFunction, dateFormatCheck) {
if (
!dateFormatFound &&
dateFormat.substring(
processPosition,
processPosition + dateFormatCheck.length
) === dateFormatCheck
) {
processedString += callbackFunction(date);
processPosition += dateFormatCheck.length;
dateFormatFound = true;
}
});
if (!dateFormatFound) {
processedString += dateFormat.substring(
processPosition,
processPosition + 1
);
processPosition++;
}
}
return processedString;
};
/**
* The dayNumberToName() function will return the name of a day of the week.
* @param {number} dayNumber - A numeric representation of the day of the
* week we want the name of.
* @param {string} variation - The variation of the name you want returned.
* @param {string} language - The language to use.
* @returns {string|number} - Returns the day’s name if found or -1 if not.
*/
var dayNumberToName = function(dayNumber, variation, language) {
if (dayNumber >= 0 && dayNumber <= 6) {
switch (variation) {
case 'full':
case 'medium':
case 'short':
return translations[language]['days'][variation][dayNumber];
}
}
return -1;
};
/**
* The generateRandomInteger() function will generate a random integer
* between two passed integers.
* @param {number} minimum - The bottom of the random range.
* @param {number} maximum - The top of the random range.
* @returns {number} - Returns a random integer between the passed integers.
*/
var generateRandomInteger = function(minimum, maximum) {
return Math.round(Math.random() * (maximum - minimum) + minimum);
};
/**
* The getActiveDate() function will get the active date of an integration.
* @param {object} agjCalendar - The integration to get the active date of.
* @param {boolean} getEnd - Whether or not to get the active end date.
* @returns {void}
*/
var getActiveDate = function(agjCalendar, getEnd) {
if (getEnd !== true) {
getEnd = false;
}
var activeDate = -1;
if (!getEnd || agjCalendar['allowRange']) {
switch (agjCalendar['inputType']) {
case 'text':
activeDate = stringToDate(
$(agjCalendar[
getEnd ? 'endDateSelector' : 'dateSelector'
]).val(),
agjCalendar['dateFormat'],
agjCalendar['language']
);
break;
case 'dropdown':
var startDateString;
startDateString = $(
agjCalendar[getEnd ? 'endMonthSelector' : 'monthSelector']
).val();
startDateString += '-';
startDateString += $(
agjCalendar[getEnd ? 'endDaySelector' : 'daySelector']
).val();
activeDate = stringToDate(
startDateString,
4,
agjCalendar['language']
);
break;
}
}
if (activeDate !== -1) {
if (activeDate < agjCalendar['minimumDate']) {
return agjCalendar['minimumDate'];
} else if (activeDate > agjCalendar['maximumDate']) {
return agjCalendar['maximumDate'];
} else {
if (agjCalendar['excludeDates'].length > 0) {
for (var i = 0; i < agjCalendar['excludeDates'].length; i++) {
var excludeDate = agjCalendar['excludeDates'][i];
if (
activeDate.getFullYear() === excludeDate.getFullYear() &&
activeDate.getMonth() === excludeDate.getMonth() &&
activeDate.getDate() === excludeDate.getDate()
) {
return -1;
}
}
}
return activeDate;
}
}
return -1;
};
/**
* The getCssValueInPixels() function will extract the value in pixels from a
* CSS value.
* @param {string} cssValue - The CSS value to extract the pixel count.
* @returns {number} - The pixel count for the CSS value.
*/
var getCssValueInPixels = function(cssValue) {
if (cssValue.substring(cssValue.length - 2).toLowerCase() === 'px') {
cssValue = cssValue.substring(0, cssValue.length - 2);
}
return isNaN(cssValue) ? 0 : parseInt(cssValue, 10);
};
/**
* The getDaysInMonth() function will return the number of days in a given
* month.
* @param {number} month - The month to base the calculation on.
* @param {number} year - The year to base the calculation on.
* @returns {number} - The number of days in the given month or -1 if the
* month is invalid.
*/
var getDaysInMonth = function(month, year) {
if (!isNaN(month)) {
month = parseInt(month, 10);
}
switch (month) {
case 0: // January
case 2: // March
case 4: // May
case 6: // July
case 7: // August
case 9: // October
case 11: // December
return 31;
case 3: // April
case 5: // June
case 8: // September
case 10: // November
return 30;
case 1: // February
year = parseInt(year, 10);
var isLeapYear =
(year % 4 === 0 && year % 100 !== 0) ||
year % 400 === 0;
return isLeapYear ? 29 : 28;
}
return -1;
};
/**
* The getTrueHeight() function will calculate the true height; height +
* vertical padding + vertical borders + vertical margins.
* @param {object} jQueryElement - The jQuery element you want to calculate
* the true height of.
* @returns {number} - The true height of the passed jQuery element in pixels.
*/
var getTrueHeight = function(jQueryElement) {
var trueHeight = jQueryElement.height();
var cssAttributes = [
'margin-top',
'borderTopWidth',
'padding-top',
'padding-bottom',
'borderBottomWidth',
'margin-bottom'
];
for (var i = 0; i < cssAttributes.length; i++) {
var cssValue = getCssValueInPixels(jQueryElement.css(cssAttributes[i]));
if (!isNaN(cssValue)) {
trueHeight += cssValue;
}
}
return trueHeight;
};
/**
* The getTrueWidth() function will calculate the true width; width +
* horizontal padding + horizontal borders + horizontal margins.
* @param {object} jQueryElement - The jQuery element you want to calculate
* the true width of.
* @returns {number} - The true width of the passed jQuery element in pixels.
*/
var getTrueWidth = function(jQueryElement) {
var trueWidth = jQueryElement.width();
var cssAttributes = [
'margin-left',
'borderLeftWidth',
'padding-left',
'padding-right',
'borderRightWidth',
'margin-right'
];
for (var i = 0; i < cssAttributes.length; i++) {
var cssValue = getCssValueInPixels(jQueryElement.css(cssAttributes[i]));
if (!isNaN(cssValue)) {
trueWidth += cssValue;
}
}
return trueWidth;
};
/**
* The hideModalBackground() function will hide the modal background element.
* @returns {void}
*/
var hideModalBackground = function() {
var modalBackgroundElement = $('#agjCalendar-modal-background');
if (modalBackgroundElement.is(':visible')) {
window.scrollTo(lastScrollLeft, lastScrollTop);
$('body').css({
marginRight: lastBodyMarginRight,
overflow: lastBodyOverflow
});
modalBackgroundElement.hide();
}
};
/**
* The monthNameToNumber() function will return the numeric position of a
* month.
* @param {string} monthName - The name of the month we want the numeric
* position of.
* @param {string} language - The language to use.
* @returns {number} - The month’s numeric position or -1 if the month isn’t
* found.
*/
var monthNameToNumber = function(monthName, language) {
var returnValue = -1;
var variations = [
'full',
'abbreviated'
];
for (var variation = 0; variation < variations.length; variation++) {
$.map(
translations[language]['months'][variations[variation]],
function(translatedMonthName, monthNumber) {
if (
returnValue === -1 &&
translatedMonthName.toLowerCase() === monthName.toLowerCase()
) {
returnValue = monthNumber;
return false;
}
}
);
if (returnValue !== -1) {
return returnValue;
}
}
return returnValue;
};
/**
* The monthNumberToName() function will return the name of a month.
* @param {number} monthNumber - A numeric representation of the month we
* want the name of.
* @param {boolean} fullName - Whether to return the month’s full name,
* default is true.
* @param {string} language - The language to use.
* @returns {string|number} - Returns the month’s name if found or -1 if not.
*/
var monthNumberToName = function(monthNumber, fullName, language) {
if (monthNumber >= 0 && monthNumber <= 11) {
var variation = fullName ? 'full' : 'abbreviated';
return translations[language]['months'][variation][monthNumber];
}
return -1;
};
/**
* The numberToText() function will return a number as text.
* @param {number} number - The number to be returned as text.
* @returns {string} - The number as text.
*/
var numberToText = function(number) {
if (!isNaN(number)) {
number = parseInt(number, 10);
}
switch (number) {
case 0:
return 'Zero';
case 1:
return 'One';
case 2:
return 'Two';
case 3:
return 'Three';
case 4:
return 'Four';
case 5:
return 'Five';
case 6:
return 'Six';
case 7:
return 'Seven';
case 8:
return 'Eight';
case 9:
return 'Nine';
case 10:
return 'Ten';
}
return -1;
};
/**
* The positionCalendar() function will position the date picker on the
* webpage.
* @param {object} agjCalendar - The integration to set the date on.
* @param {boolean} useEnd - Whether or not to use the end date for
* positioning.
* @returns {void}
*/
var positionCalendar = function(agjCalendar, useEnd) {
var calendarElement = $('#agjCalendar');
switch (agjCalendar['calendarDisplay']) {
case 'inline':
switch (agjCalendar['inputType']) {
case 'text':
var dateElement = $(
agjCalendar[useEnd ? 'endDateSelector' : 'dateSelector']
);
var expanderElement = $(
agjCalendar[useEnd ? 'endExpanderSelector' : 'expanderSelector']
);
if (calendarElement.length === 1 && dateElement.length === 1) {
var expanderBottom = 0;
if (expanderElement.length > 0) {
expanderBottom = expanderElement.offset().top;
expanderBottom += getTrueHeight(expanderElement);
}
var dateBottom;
if (dateElement.attr('type') === 'hidden') {
dateBottom = dateElement.parent().offset().top;
dateBottom += getTrueHeight(dateElement.parent());
} else {
dateBottom = dateElement.offset().top;
dateBottom += getTrueHeight(dateElement);
}
var expanderLeft = Number.MAX_SAFE_INTEGER;
if (expanderElement.length > 0) {
expanderLeft = expanderElement.offset().left;
}
var dateLeft;
if (dateElement.attr('type') === 'hidden') {
dateLeft = dateElement.parent().offset().left;
} else {
dateLeft = dateElement.offset().left;
}
calendarElement.css({
left: Math.min(expanderLeft, dateLeft),
top: Math.max(expanderBottom, dateBottom) + 1
});
}
break;
case 'dropdown':
var monthElement = $(
agjCalendar[useEnd ? 'endMonthSelector' : 'monthSelector']
);
var dayElement = $(
agjCalendar[useEnd ? 'endDaySelector' : 'daySelector']
);
var expanderElement = $(
agjCalendar[useEnd ? 'endExpanderSelector' : 'expanderSelector']
);
if (
calendarElement.length === 1 &&
monthElement.length === 1 &&
dayElement.length === 1
) {
var expanderBottom = 0;
if (expanderElement.length > 0) {
expanderBottom = expanderElement.offset().top;
expanderBottom += getTrueHeight(expanderElement);
}
var monthBottom = monthElement.offset().top;
monthBottom += getTrueHeight(monthElement);
var dayBottom = dayElement.offset().top;
dayBottom += getTrueHeight(dayElement);
var calendarTop = 1 + Math.max(
expanderBottom,
monthBottom,
dayBottom
);
var expanderLeft = Number.MAX_SAFE_INTEGER;
if (expanderElement.length > 0) {
expanderLeft = expanderElement.offset().left;
}
var monthLeft = monthElement.offset().left;
var dayLeft = dayElement.offset().left;
var calendarLeft = Math.min(expanderLeft, monthLeft, dayLeft);
calendarElement.css({
left: calendarLeft,
top: calendarTop
});
}
break;
}
calendarElement.removeClass('agjCalendar-full').css({
position: 'absolute'
});
break;
case 'modal':
calendarElement.removeClass('agjCalendar-full');
var fixedLeft = $(window).width() / 2;
fixedLeft -= getTrueWidth(calendarElement) / 2;
var fixedTop = $(window).height() / 2;
fixedTop -= getTrueHeight(calendarElement) / 2;
calendarElement.css({
left: fixedLeft,
position: 'fixed',
top: fixedTop
});
$('#agjCalendar-modal-background')
.removeClass('agjCalendar-modal-background-full');
break;
case 'full':
calendarElement.addClass('agjCalendar-full').css({
left: 0,
position: 'fixed',
top: 0
});
$('#agjCalendar-modal-background')
.addClass('agjCalendar-modal-background-full');
break;
}
};
/**
* The redrawCalendars() function will redraw the calendars on the date
* picker.
* @param {Date} drawMonth - The month to draw on the left most calendar of
* the date picker.
* @returns {void}
*/
var redrawCalendars = function(drawMonth) {
if (drawMonth.getDate() !== 1) {
drawMonth.setFullYear(drawMonth.getFullYear(), drawMonth.getMonth(), 1);
}
drawMonth.setHours(0, 0, 0, 0);
var calendarElement = $('#agjCalendar');
if (calendarElement.length > 0) {
var agjCalendar = agjCalendars[calendarElement.attr('data-active')];
var agjCalendarIsEnd =
calendarElement.attr('data-active-is-end') === true ||
calendarElement.attr('data-active-is-end') === 'true';
var currentStartDate = getActiveDate(agjCalendar);
var currentEndDate = -1;
if (agjCalendar['allowRange']) {
currentEndDate = getActiveDate(agjCalendar, true);
}
var agjCalendarDropdownElement = $('#agjCalendar-dropdown');
for (
var calendar = 1;
calendar <= agjCalendar['calendarCount'];
calendar++
) {
var getDay;
if (agjCalendar['startWeekOnMonday']) {
getDay = (drawMonth.getDay() + 6) % 7;
} else {
getDay = drawMonth.getDay();
}
var calendarSelector = -1;
switch (calendar) {
case 1:
calendarSelector = '#agjCalendar-first';
break;
case 2:
calendarSelector = '#agjCalendar-second';
break;
case 3:
calendarSelector = '#agjCalendar-third';
break;
}
switch (calendar) {
case 1:
agjCalendarDropdownElement.val(
dateToString(drawMonth, 'YYYY-MM', agjCalendar['language'])
);
break;
case 2:
case 3:
$(calendarSelector + '-month-name').text(
dateToString(drawMonth, 'MMMM YYYY', agjCalendar['language'])
);
break;
}
var currentDay = 0;
var calendarMarkup = '';
if (getDay > 0) {
calendarMarkup += '<div';
calendarMarkup += ' class="agjCalendar-week agjCalendar-week-one"';
calendarMarkup += '>';
for (var day = 1; day <= getDay; day++) {
currentDay++;
calendarMarkup += '<div class="agjCalendar-blank agjCalendar-';
calendarMarkup += dayNumberToName(
(currentDay - (
agjCalendar['startWeekOnMonday'] ? 0 : 1
)) % 7,
'full',
'en'
).toLowerCase();
calendarMarkup += '"></div>';
}
}
var minimumDate = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
if (agjCalendar['allowRange'] && agjCalendarIsEnd) {
if (currentStartDate === -1) {
minimumDate.setFullYear(
minimumDate.getFullYear(),
minimumDate.getMonth(),
minimumDate.getDate() + agjCalendar['minimumRange']
);
} else {
minimumDate.setFullYear(
currentStartDate.getFullYear(),
currentStartDate.getMonth(),
currentStartDate.getDate() + agjCalendar['minimumRange']
);
}
}
minimumDate.setHours(0, 0, 0, 0);
var maximumDate = new Date(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
if (agjCalendar['allowRange']) {
if (!agjCalendarIsEnd) {
maximumDate.setFullYear(
maximumDate.getFullYear(),
maximumDate.getMonth(),
maximumDate.getDate() - agjCalendar['minimumRange']
);
} else if (agjCalendarIsEnd && currentStartDate !== -1) {
maximumDate.setFullYear(
currentStartDate.getFullYear(),
currentStartDate.getMonth(),
currentStartDate.getDate() + agjCalendar['maximumRange']
);
if (maximumDate > agjCalendar['maximumDate']) {
maximumDate.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
}
}
}
maximumDate.setHours(23, 59, 59, 999);
for (day = 1; day <= 42 - getDay; day++) {
if (currentDay % 7 === 0) {
if (calendarMarkup.length > 0) {
calendarMarkup += '</div>';
}
calendarMarkup += '<div';
calendarMarkup += ' class="agjCalendar-week';
calendarMarkup += ' agjCalendar-week-' + numberToText(
Math.round(currentDay / 7) + 1
).toLowerCase() + '">';
}
var daysInMonth = getDaysInMonth(
drawMonth.getMonth(),
drawMonth.getFullYear()
);
if (agjCalendar['startWeekOnMonday']) {
daysInMonth++;
}
if (day <= daysInMonth) {
var drawDate = new Date(
drawMonth.getFullYear(),
drawMonth.getMonth(),
day
);
var dateIsSelectable = false;
if (drawDate >= minimumDate && drawDate <= maximumDate) {
dateIsSelectable = true;
if (agjCalendar['excludeDates'].length > 0) {
for (var i = 0; i < agjCalendar['excludeDates'].length; i++) {
var excludeDate = agjCalendar['excludeDates'][i];
if (
drawDate.getFullYear() === excludeDate.getFullYear() &&
drawDate.getMonth() === excludeDate.getMonth() &&
drawDate.getDate() === excludeDate.getDate()
) {
dateIsSelectable = false;
break;
}
}
}
}
var classMarkup = 'agjCalendar-' + dayNumberToName(
(currentDay + (agjCalendar['startWeekOnMonday'] ? 1 : 0)) % 7,
'full',
'en'
).toLowerCase();
if (dateIsSelectable) {
classMarkup += ' agjCalendar-selectable';
}
if (
drawDate.getFullYear() === new Date().getFullYear() &&
drawDate.getMonth() === new Date().getMonth() &&
drawDate.getDate() === new Date().getDate()
) {
classMarkup += ' agjCalendar-today';
}
var matchesStartDate =
currentStartDate !== -1 &&
(
drawDate.getFullYear() === currentStartDate.getFullYear() &&
drawDate.getMonth() === currentStartDate.getMonth() &&
drawDate.getDate() === currentStartDate.getDate()
);
if (matchesStartDate) {
if (!agjCalendarIsEnd) {
classMarkup += ' agjCalendar-active';
} else {
classMarkup += ' agjCalendar-other-active';
}
}
var matchesEndDate =
currentEndDate !== -1 &&
(
drawDate.getFullYear() === currentEndDate.getFullYear() &&
drawDate.getMonth() === currentEndDate.getMonth() &&
drawDate.getDate() === currentEndDate.getDate()
);
if (matchesEndDate) {
if (agjCalendarIsEnd) {
classMarkup += ' agjCalendar-active';
} else {
classMarkup += ' agjCalendar-other-active';
}
}
if (
currentStartDate !== -1 &&
currentEndDate !== -1 &&
currentStartDate !== currentEndDate
) {
if (
(
currentStartDate < currentEndDate &&
drawDate >= currentStartDate &&
drawDate <= currentEndDate
) ||
(
currentStartDate > currentEndDate &&
drawDate <= currentStartDate &&
drawDate >= currentEndDate
)
) {
classMarkup += ' agjCalendar-in-range';
}
}
calendarMarkup += '<div class="' + classMarkup + '">';
if (dateIsSelectable) {
var fullDateText = '';
switch (agjCalendar['language']) {
case 'en':
fullDateText = dateToString(
drawDate,
'MMMM D, YYYY',
agjCalendar['language']
);
break;
case 'fr':
fullDateText = dateToString(
drawDate,
'D MMMM YYYY',
agjCalendar['language']
);
break;
}
calendarMarkup += '<a';
calendarMarkup += ' href="#"';
calendarMarkup += ' title="' + fullDateText + '"';
calendarMarkup += ' id="agjCalendar-' + dateToString(
drawDate,
'YYYY-MM-DD',
agjCalendar['language']
) + '"';
calendarMarkup += '>';
}
calendarMarkup += day;
if (dateIsSelectable) {
calendarMarkup += '</a>';
}
calendarMarkup += '</div>';
} else {
calendarMarkup += '<div';
calendarMarkup += ' class="agjCalendar-blank';
calendarMarkup += ' agjCalendar-' + dayNumberToName(
(currentDay + (agjCalendar['startWeekOnMonday'] ? 1 : 0)) % 7,
'full',
'en'
).toLowerCase();
calendarMarkup += '"></div>';
}
currentDay++;
}
calendarMarkup += '</div>';
$(calendarSelector + ' div.agjCalendar-week').remove();
$(calendarSelector).append(calendarMarkup);
if (
$(
calendarSelector +
' div.agjCalendar-week-five div.agjCalendar-blank'
).length === 7
) {
$(calendarSelector)
.removeClass('agjCalendar-five-weeks agjCalendar-six-weeks')
.addClass('agjCalendar-four-weeks');
} else if (
$(
calendarSelector +
' div.agjCalendar-week-six div.agjCalendar-blank'
).length === 7
) {
$(calendarSelector)
.removeClass('agjCalendar-four-weeks agjCalendar-six-weeks')
.addClass('agjCalendar-five-weeks');
} else {
$(calendarSelector)
.removeClass('agjCalendar-four-weeks agjCalendar-five-weeks')
.addClass('agjCalendar-six-weeks');
}
drawMonth.setFullYear(
drawMonth.getFullYear(),
drawMonth.getMonth() + 1,
1
);
}
$('div.agjCalendar-week a').on('click', function() {
var newDate = new Date(
this.id.substring(12, 16),
parseInt(this.id.substring(17, 19), 10) - 1,
this.id.substring(20, 22)
);
setDate(agjCalendar, newDate, agjCalendarIsEnd);
if (agjCalendar['allowRange'] && !agjCalendarIsEnd) {
autoSetEndDate(agjCalendar);
}
$.agjCalendar.deactivate();
return false;
});
if (agjCalendarDropdownElement.val() !== null) {
var dropdownDate = new Date(
agjCalendarDropdownElement.val().substring(0, 4),
parseInt(agjCalendarDropdownElement.val().substring(5, 7), 10),
1
);
if (
agjCalendarDropdownElement.find(
'option[value=' + dateToString(
dropdownDate,
'YYYY-MM',
agjCalendar['language']
) + ']'
).length === 0
) {
$('a.agjCalendar-next-month').fadeTo(1, 0.33);
} else {
$('a.agjCalendar-next-month').fadeTo(1, 1);
}
dropdownDate.setFullYear(
dropdownDate.getFullYear(),
dropdownDate.getMonth() - 2,
dropdownDate.getDate()
);
if (
agjCalendarDropdownElement.find(
'option[value=' + dateToString(
dropdownDate,
'YYYY-MM',
agjCalendar['language']
) + ']'
).length === 0
) {
$('a.agjCalendar-previous-month').fadeTo(1, 0.33);
} else {
$('a.agjCalendar-previous-month').fadeTo(1, 1);
}
}
}
};
/**
* The setDate() function will set a date on an integration’s inputs.
* @param {object} agjCalendar - The integration to set the date on.
* @param {Date} dateToSet - The date to set on the integration’s inputs.
* @param {boolean} setEnd - Whether or not to set the end date.
* @returns {void}
*/
var setDate = function(agjCalendar, dateToSet, setEnd) {
if (setEnd === undefined) {
setEnd = false;
}
switch (agjCalendar['inputType']) {
case 'text':
var dateElement = $(
agjCalendar[setEnd ? 'endDateSelector' : 'dateSelector']
);
var newValue = '';
if (dateToSet === 'blank') {
switch (agjCalendar['dateFormat']) {
case 1:
newValue = 'mm/dd/yyyy';
break;
case 2:
newValue = translations[agjCalendar['language']]['selectADate'];
break;
case 3:
newValue = 'dd/mm/yyyy';
break;
case 4:
newValue = 'yyyy-mm-dd';
break;
case 5:
newValue = translations[agjCalendar['language']]['selectADate'];
break;
}
} else {
switch (agjCalendar['dateFormat']) {
case 1:
newValue = dateToString(
dateToSet,
'MM/DD/YYYY',
agjCalendar['language']
);
break;
case 2:
newValue = dateToString(
dateToSet,
'MMM D, YYYY',
agjCalendar['language']
);
break;
case 3:
newValue = dateToString(
dateToSet,
'DD/MM/YYYY',
agjCalendar['language']
);
break;
case 4:
newValue = dateToString(
dateToSet,
'YYYY-MM-DD',
agjCalendar['language']
);
break;
case 5:
newValue = dateToString(
dateToSet,
'D MMMM YYYY',
agjCalendar['language']
);
break;
}
}
if (newValue.length > 0) {
dateElement.val(newValue).trigger('change');
}
break;
case 'dropdown':
var dayValue;
if (dateToSet === 'blank') {
dayValue = '';
} else {
dayValue = dateToString(dateToSet, 'DD', agjCalendar['language']);
}
var monthElement = $(
agjCalendar[setEnd ? 'endMonthSelector' : 'monthSelector']
);
var monthValue;
if (dateToSet === 'blank') {
monthValue = '';
} else {
monthValue = dateToString(
dateToSet,
'YYYY-MM',
agjCalendar['language']
);
}
if (
monthValue.length > 0 &&
monthElement.find('option[value=' + monthValue + ']').length > 0 &&
(
dateToSet === 'blank' ||
parseInt(dayValue, 10) <= getDaysInMonth(
dateToSet.getMonth(),
dateToSet.getFullYear()
)
)
) {
monthElement.val(monthValue).trigger('change');
updateDayElement(agjCalendar, setEnd);
$(agjCalendar[setEnd ? 'endDaySelector' : 'daySelector'])
.val(dayValue)
.trigger('change');
}
break;
}
};
/**
* The stringToDate() function will parse a string and return a Date object.
* @param {string} string - The string we want to extract a date from.
* @param {number} dateFormat - The format we want to search the string for.
* @param {string} language - The language to use.
* @returns {number|Date} - Returns a date if one can be extracted from the
* string or -1 if no date is found.
*/
var stringToDate = function(string, dateFormat, language) {
switch (dateFormat) {
case 1:
if (regexPatterns[1].test(string)) {
var dateFromString = new Date(
string.substring(6, 10),
parseInt(string.substring(0, 2), 10) - 1,
string.substring(3, 5)
);
return dateFromString;
}
break;
case 2:
if (regexPatterns[2].test(string)) {
var monthNumber = monthNameToNumber(
string.substring(0, string.indexOf(' ')),
language
);
if (monthNumber !== -1) {
var dateFromString = new Date(
string.substring(string.length - 4, string.length),
monthNumber,
string.substring(string.indexOf(' ') + 1, string.indexOf(','))
);
return dateFromString;
}
}
break;
case 3:
if (regexPatterns[3].test(string)) {
var dateFromString = new Date(
string.substring(6, 10),
parseInt(string.substring(3, 5), 10) - 1,
string.substring(0, 2), 10
);
return dateFromString;
}
break;
case 4:
if (regexPatterns[4].test(string)) {
var dateFromString = new Date(
string.substring(0, 4),
parseInt(string.substring(5, 7), 10) - 1,
string.substring(8, 10)
);
return dateFromString;
}
break;
case 5:
if (regexPatterns[5].test(string)) {
var monthNumber = monthNameToNumber(
string.substring(string.indexOf(' ') + 1, string.lastIndexOf(' ')),
language
);
if (monthNumber !== -1) {
var dateFromString = new Date(
string.substring(string.lastIndexOf(' ') + 1),
monthNumber,
string.substring(0, string.indexOf(' '))
);
return dateFromString;
}
}
break;
}
return -1;
};
/**
* The throwError() function will throw an error.
* @param {string} errorMessage - The message of the error to throw.
* @returns {void}
*/
var throwError = function(errorMessage) {
errorMessage = 'agjCalendar Error! ' + errorMessage;
var console = window.console;
if (console && console.error) {
console.error(errorMessage);
} else if (console && console.log) {
console.log(errorMessage);
}
};
/**
* The updateDayElement() function will update an integration’s day element.
* @param {object} agjCalendar - The integration to update.
* @param {boolean} updateEnd - Whether or not to update the end date.
* @returns {void}
*/
var updateDayElement = function(agjCalendar, updateEnd) {
if (updateEnd === undefined) {
updateEnd = false;
}
if (agjCalendar['overwriteDayOptions']) {
var monthElement = $(
agjCalendar[updateEnd ? 'endMonthSelector' : 'monthSelector']
);
var dayElement = $(
agjCalendar[updateEnd ? 'endDaySelector' : 'daySelector']
);
dayElement.find('option').remove();
if (regexPatterns['month'].test(monthElement.val())) {
if (agjCalendar['allowBlankDates']) {
dayElement.append('<option value=""></option>');
}
var selectedDate = getActiveDate(agjCalendar, updateEnd);
var startDate;
if (agjCalendar['allowRange'] && updateEnd) {
startDate = getActiveDate(agjCalendar, false);
}
var minimumDate = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
if (updateEnd) {
if (startDate === -1) {
minimumDate.setFullYear(
minimumDate.getFullYear(),
minimumDate.getMonth(),
minimumDate.getDate() + agjCalendar['minimumRange']
);
} else {
minimumDate.setFullYear(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['minimumRange']
);
}
}
minimumDate.setHours(0, 0, 0, 0);
var maximumDate = new Date(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate() - agjCalendar['minimumRange']
);
if (updateEnd) {
if (startDate === -1) {
maximumDate.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
} else {
maximumDate.setFullYear(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['maximumRange']
);
if (maximumDate > agjCalendar['maximumDate']) {
maximumDate.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
}
}
}
maximumDate.setHours(23, 59, 59, 999);
var monthElementMonth = monthElement.val().substring(5, 7);
monthElementMonth = parseInt(monthElementMonth, 10) - 1;
var drawDate = new Date(
monthElement.val().substring(0, 4),
monthElementMonth,
1
);
while (
drawDate < maximumDate &&
drawDate.getMonth() === monthElementMonth
) {
if (drawDate >= minimumDate) {
var optionMarkup = '<option';
optionMarkup += ' value="' + dateToString(
drawDate,
'DD',
agjCalendar['language']
) + '"';
if (
selectedDate !== -1 &&
drawDate.getDate() === selectedDate.getDate()
) {
optionMarkup += ' selected="selected"';
}
optionMarkup += '>';
optionMarkup += drawDate.getDate();
optionMarkup += '</option>';
dayElement.append(optionMarkup);
}
drawDate.setFullYear(
drawDate.getFullYear(),
drawDate.getMonth(),
drawDate.getDate() + 1
);
}
}
if (dayElement.find('option').length === 0) {
dayElement.append('<option value=""></option>');
}
}
};
/**
* The updateDropdown() function will update the date picker dropdown.
* @param {object} agjCalendar - The integration to use to update.
* @param {boolean} updateForEnd - Whether or not to update for the end date.
*/
var updateDropdown = function(agjCalendar, updateForEnd) {
if (updateForEnd === undefined) {
updateForEnd = false;
}
var minimumDate = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
minimumDate.setHours(0, 0, 0, 0);
var maximumDate = new Date(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
maximumDate.setHours(23, 59, 59, 999);
if (updateForEnd) {
var currentStartDate = getActiveDate(agjCalendar);
if (currentStartDate !== -1) {
minimumDate.setFullYear(
currentStartDate.getFullYear(),
currentStartDate.getMonth(),
currentStartDate.getDate() + agjCalendar['minimumRange']
);
var endOfMaximumRange = new Date(
currentStartDate.getFullYear(),
currentStartDate.getMonth(),
currentStartDate.getDate() + agjCalendar['maximumRange']
);
if (endOfMaximumRange < agjCalendar['maximumDate']) {
maximumDate.setFullYear(
endOfMaximumRange.getFullYear(),
endOfMaximumRange.getMonth(),
endOfMaximumRange.getDate()
);
}
}
}
var dropdownElement = $('#agjCalendar-dropdown');
dropdownElement.find('option').remove();
var drawDate = new Date(
minimumDate.getFullYear(),
minimumDate.getMonth(),
minimumDate.getDate()
);
do {
dropdownElement.append(
'<option value="' + dateToString(drawDate, 'YYYY-MM') + '">' +
dateToString(drawDate, 'MMM YYYY', agjCalendar['language']) +
'</option>'
);
drawDate.setFullYear(drawDate.getFullYear(), drawDate.getMonth() + 1, 1);
} while (drawDate < maximumDate);
};
/**
* The updateMonthElement() function will update an integration’s month
* element.
* @param {object} agjCalendar - The integration to update.
* @param {boolean} updateEnd - Whether or not to update the end date.
* @returns {void}
*/
var updateMonthElement = function(agjCalendar, updateEnd) {
if (updateEnd === undefined) {
updateEnd = false;
}
if (agjCalendar['overwriteMonthOptions']) {
var monthElement = $(
agjCalendar[updateEnd ? 'endMonthSelector' : 'monthSelector']
);
monthElement.find('option').remove();
if (agjCalendar['allowBlankDates']) {
monthElement.append('<option value=""></option>');
}
var selectedDate = getActiveDate(agjCalendar, updateEnd);
var startDate;
if (agjCalendar['allowRange'] && updateEnd) {
startDate = getActiveDate(agjCalendar, false);
}
var minimumDate = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
if (updateEnd) {
if (startDate === -1) {
minimumDate.setFullYear(
minimumDate.getFullYear(),
minimumDate.getMonth(),
minimumDate.getDate() + agjCalendar['minimumRange']
);
} else {
minimumDate.setFullYear(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['minimumRange']
);
}
}
minimumDate.setHours(0, 0, 0, 0);
var maximumDate = new Date(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate() - agjCalendar['minimumRange']
);
if (updateEnd) {
if (startDate === -1) {
maximumDate.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
} else {
maximumDate.setFullYear(
startDate.getFullYear(),
startDate.getMonth(),
startDate.getDate() + agjCalendar['maximumRange']
);
if (maximumDate > agjCalendar['maximumDate']) {
maximumDate.setFullYear(
agjCalendar['maximumDate'].getFullYear(),
agjCalendar['maximumDate'].getMonth(),
agjCalendar['maximumDate'].getDate()
);
}
}
}
maximumDate.setHours(23, 59, 59, 999);
var drawDate = new Date(
minimumDate.getFullYear(),
minimumDate.getMonth(),
minimumDate.getDate()
);
while (drawDate < maximumDate) {
var optionMarkup = '<option';
optionMarkup += ' value="' + dateToString(
drawDate,
'YYYY-MM',
agjCalendar['language']
) + '"';
if (
selectedDate !== -1 &&
drawDate.getFullYear() === selectedDate.getFullYear() &&
drawDate.getMonth() === selectedDate.getMonth()
) {
optionMarkup += ' selected="selected"';
}
optionMarkup += '>';
optionMarkup += dateToString(
drawDate,
'MMMM YYYY',
agjCalendar['language']
);
optionMarkup += '</option>';
monthElement.append(optionMarkup);
drawDate.setFullYear(
drawDate.getFullYear(),
drawDate.getMonth() + 1,
1
);
}
}
};
/**
* The $.fn.agjCalendar() function will initialize a new agjCalendar
* integration.
* @param {object} options - A JSON object of configuration options.
* @returns {jQuery} - Returns the element to allow for chaining.
*/
$.fn.agjCalendar = function(options) {
if (typeof options !== 'object') {
options = {};
}
if (this.prop('tagName').toLowerCase() === 'input') {
var className;
do {
className = 'agjCalendar-' + generateRandomInteger(100000, 999999);
} while ($('input.' + className).length > 0);
this.addClass(className);
options['dateSelector'] = 'input.' + className;
$.agjCalendar(options);
} else {
throwError(
'Invalid tag "' + this.prop('tagName').toLowerCase() +
'" ("input" expected)'
);
}
return this;
};
/**
* The $.agjCalendar() function will initialize a new agjCalendar integration.
* @param {object} options - A JSON object of configuration options.
* @returns {boolean} - Returns true on success or false on error.
*/
$.agjCalendar = function(options) {
options = $.extend({
allowBlankDates: false,
allowRange: false,
autoSetEndDate: 'dates',
calendarCount: 1,
calendarDisplay: 'inline',
dateFormat: 1,
dateSelector: null,
dayNameFormat: 'short',
daySelector: null,
defaultDate: new Date(),
defaultEndDate: null,
defaultRange: -1,
endDateSelector: null,
endDaySelector: null,
endExpanderSelector: null,
endMonthSelector: null,
excludeDates: [],
expanderSelector: null,
inputType: 'text',
language: 'en',
// we are squishing maximumDate into one long line and disabling ESLint
// with the "eslint-disable-line" comment because of a ESLint bug which
// won’t let us use the multiline notation without throwing an error.
maximumDate: new Date(new Date().getFullYear() + 1, new Date().getMonth(), new Date().getDate()), // eslint-disable-line
/*
maximumDate: new Date(
new Date().getFullYear() + 1,
new Date().getMonth(),
new Date().getDate()
),
*/
maximumRange: -1,
minimumDate: new Date(),
minimumRange: -1,
monthSelector: null,
overwriteDayOptions: true,
overwriteMonthOptions: true,
startWeekOnMonday: false,
theme: null
}, options);
var agjCalendar = {
position: agjCalendars.length
};
agjCalendar['language'] = 'en';
if (options['language'] === 'fr') {
agjCalendar['language'] = 'fr';
}
agjCalendar['overwriteMonthOptions'] = true;
if (options['overwriteMonthOptions'] === false) {
agjCalendar['overwriteMonthOptions'] = false;
}
agjCalendar['overwriteDayOptions'] = true;
if (options['overwriteDayOptions'] === false) {
agjCalendar['overwriteDayOptions'] = false;
}
agjCalendar['allowBlankDates'] = false;
if (options['allowBlankDates'] === true) {
agjCalendar['allowBlankDates'] = true;
}
agjCalendar['startWeekOnMonday'] = false;
if (options['startWeekOnMonday'] === true) {
agjCalendar['startWeekOnMonday'] = true;
}
agjCalendar['allowRange'] = false;
if (options['allowRange'] === true) {
agjCalendar['allowRange'] = true;
}
agjCalendar['inputType'] = 'text';
if (options['inputType'] === 'dropdown') {
agjCalendar['inputType'] = 'dropdown';
}
agjCalendar['calendarCount'] = 1;
switch (options['calendarCount']) {
case 2:
case 3:
agjCalendar['calendarCount'] = options['calendarCount'];
break;
}
agjCalendar['calendarDisplay'] = 'inline';
switch (options['calendarDisplay']) {
case 'modal':
case 'full':
agjCalendar['calendarDisplay'] = options['calendarDisplay'];
break;
}
agjCalendar['dayNameFormat'] = 'short';
switch (options['dayNameFormat']) {
case 'medium':
case 'full':
agjCalendar['dayNameFormat'] = options['dayNameFormat'];
break;
}
agjCalendar['dateFormat'] = 1;
switch (options['dateFormat']) {
case 2:
case 3:
case 4:
case 5:
agjCalendar['dateFormat'] = options['dateFormat'];
break;
}
agjCalendar['theme'] = '';
switch (options['theme']) {
case 'red':
case 'orange':
case 'yellow':
case 'green':
case 'cyan':
case 'blue':
case 'purple':
case 'pink':
agjCalendar['theme'] = options['theme'];
break;
default:
// custom themes must begin with 'custom-'
if (
typeof options['theme'] === 'string' &&
options['theme'].toLowerCase().indexOf('custom-') === 0
) {
agjCalendar['theme'] = options['theme'];
}
break;
}
agjCalendar['autoSetEndDate'] = 'dates';
switch (options['autoSetEndDate']) {
case true: // this is here for backwards compatability
agjCalendar['autoSetEndDate'] = 'always';
break;
case false: // this is here for backwards compatability
agjCalendar['autoSetEndDate'] = 'never';
break;
case 'blanks':
case 'always':
case 'never':
agjCalendar['autoSetEndDate'] = options['autoSetEndDate'];
break;
}
agjCalendar['minimumDate'] = new Date();
agjCalendar['minimumDate'].setHours(0, 0, 0, 0);
if (regexPatterns[4].test(options['minimumDate'])) {
agjCalendar['minimumDate'].setFullYear(
options['minimumDate'].substring(0, 4),
parseInt(options['minimumDate'].substring(5, 7), 10) - 1,
options['minimumDate'].substring(8, 10)
);
} else if (options['minimumDate'] instanceof Date) {
agjCalendar['minimumDate'].setFullYear(
options['minimumDate'].getFullYear(),
options['minimumDate'].getMonth(),
options['minimumDate'].getDate()
);
}
agjCalendar['maximumDate'] = new Date(
new Date().getFullYear() + 1,
new Date().getMonth(),
new Date().getDate()
);
agjCalendar['maximumDate'].setHours(23, 59, 59, 999);
if (regexPatterns[4].test(options['maximumDate'])) {
var maximumDate = new Date(
options['maximumDate'].substring(0, 4),
parseInt(options['maximumDate'].substring(5, 7), 10) - 1,
options['maximumDate'].substring(8, 10)
);
if (maximumDate >= agjCalendar['minimumDate']) {
agjCalendar['maximumDate'].setFullYear(
maximumDate.getFullYear(),
maximumDate.getMonth(),
maximumDate.getDate()
);
}
} else if (
options['maximumDate'] instanceof Date &&
options['maximumDate'] >= agjCalendar['minimumDate']
) {
agjCalendar['maximumDate'].setFullYear(
options['maximumDate'].getFullYear(),
options['maximumDate'].getMonth(),
options['maximumDate'].getDate()
);
}
agjCalendar['defaultDate'] = new Date();
if (
regexPatterns[4].test(options['defaultDate']) ||
options['defaultDate'] instanceof Date
) {
var defaultDate = new Date();
if (regexPatterns[4].test(options['defaultDate'])) {
defaultDate.setFullYear(
options['defaultDate'].substring(0, 4),
parseInt(options['defaultDate'].substring(5, 7), 10) - 1,
options['defaultDate'].substring(8, 10)
);
} else {
defaultDate.setFullYear(
options['defaultDate'].getFullYear(),
options['defaultDate'].getMonth(),
options['defaultDate'].getDate()
);
}
if (
defaultDate >= agjCalendar['minimumDate'] &&
defaultDate <= agjCalendar['maximumDate']
) {
agjCalendar['defaultDate'].setFullYear(
defaultDate.getFullYear(),
defaultDate.getMonth(),
defaultDate.getDate()
);
}
} else if (
agjCalendar['allowBlankDates'] &&
options['defaultDate'] === 'blank'
) {
agjCalendar['defaultDate'] = 'blank';
}
agjCalendar['excludeDates'] = [];
if (
options['excludeDates'] &&
options['excludeDates'] instanceof Array &&
options['excludeDates'].length > 0
) {
for (var i = 0; i < options['excludeDates'].length; i++) {
var excludeDate = -1;
if (regexPatterns[4].test(options['excludeDates'][i])) {
excludeDate = new Date(
options['excludeDates'][i].substring(0, 4),
parseInt(options['excludeDates'][i].substring(5, 7), 10) - 1,
options['excludeDates'][i].substring(8, 10)
);
} else if (options['excludeDates'][i] instanceof Date) {
excludeDate = new Date(
options['excludeDates'][i].getFullYear(),
options['excludeDates'][i].getMonth(),
options['excludeDates'][i].getDate()
);
}
if (
excludeDate !== -1 &&
excludeDate >= agjCalendar['minimumDate'] &&
excludeDate <= agjCalendar['maximumDate']
) {
agjCalendar['excludeDates'].push(excludeDate);
}
}
}
agjCalendar['minimumRange'] = 0;
agjCalendar['maximumRange'] = 0;
agjCalendar['defaultRange'] = 0;
if (agjCalendar['allowRange']) {
var totalRange = 0;
var rangeCheck = new Date(
agjCalendar['minimumDate'].getFullYear(),
agjCalendar['minimumDate'].getMonth(),
agjCalendar['minimumDate'].getDate()
);
while (rangeCheck <= agjCalendar['maximumDate']) {
totalRange++;
rangeCheck.setFullYear(
rangeCheck.getFullYear(),
rangeCheck.getMonth(),
rangeCheck.getDate() + 1
);
}
agjCalendar['minimumRange'] = totalRange === 0 ? 0 : 1;
if (
!isNaN(options['minimumRange']) &&
parseInt(options['minimumRange'], 10) >= 0 &&
parseInt(options['minimumRange'], 10) <= totalRange
) {
agjCalendar['minimumRange'] = options['minimumRange'];
}
agjCalendar['maximumRange'] = totalRange === 0 ? 0 : totalRange;
if (
!isNaN(options['maximumRange']) &&
parseInt(options['maximumRange'], 10) >= 0 &&
parseInt(options['maximumRange'], 10) <= totalRange &&
parseInt(options['maximumRange'], 10) >= agjCalendar['minimumRange']
) {
agjCalendar['maximumRange'] = options['maximumRange'];
}
agjCalendar['defaultRange'] = totalRange === 0 ? 0 : 1;
if (!isNaN(options['defaultRange'])) {
var defaultRange = parseInt(options['defaultRange'], 10);
if (
defaultRange >= agjCalendar['minimumRange'] &&
defaultRange <= agjCalendar['maximumRange']
) {
agjCalendar['defaultRange'] = defaultRange;
}
}
agjCalendar['defaultEndDate'] =
agjCalendar['defaultDate'] === 'blank' ?
'blank' :
new Date(
agjCalendar['defaultDate'].getFullYear(),
agjCalendar['defaultDate'].getMonth(),
agjCalendar['defaultDate'].getDate() + agjCalendar['defaultRange']
);
if (
regexPatterns[4].test(options['defaultEndDate']) ||
options['defaultEndDate'] instanceof Date
) {
var defaultEndDate = new Date();
if (regexPatterns[4].test(options['defaultEndDate'])) {
defaultEndDate.setFullYear(
options['defaultEndDate'].substring(0, 4),
parseInt(options['defaultEndDate'].substring(5, 7), 10) - 1,
options['defaultEndDate'].substring(8, 10)
);
} else {
defaultEndDate.setFullYear(
options['defaultEndDate'].getFullYear(),
options['defaultEndDate'].getMonth(),
options['defaultEndDate'].getDate()
);
}
if (
defaultEndDate >= agjCalendar['minimumDate'] &&
defaultEndDate <= agjCalendar['maximumDate']
) {
agjCalendar['defaultEndDate'].setFullYear(
defaultEndDate.getFullYear(),
defaultEndDate.getMonth(),
defaultEndDate.getDate()
);
}
} else if (
agjCalendar['allowBlankDates'] &&
options['defaultEndDate'] === 'blank'
) {
agjCalendar['defaultEndDate'] = 'blank';
}
}
/**
* The inputFocusEvent() function will handle events when an integration’s
* input gains focus.
* @param {object} event - The event object.
* @returns {boolean} - Returns false.
*/
var inputFocusEvent = function(event) {
if (checkIfActive(agjCalendar['position'], event.data.isEnd)) {
$.agjCalendar.deactivate();
} else {
activateCalendar(agjCalendar, event.data.isEnd);
}
return false;
};
var expanderElement = $(options['expanderSelector']);
if (expanderElement.length > 0) {
agjCalendar['expanderSelector'] = options['expanderSelector'];
expanderElement.on('click', {
isEnd: false
}, inputFocusEvent);
if (agjCalendar['allowRange']) {
var endExpanderElement = $(options['endExpanderSelector']);
if (endExpanderElement.length > 0) {
agjCalendar['endExpanderSelector'] = options['endExpanderSelector'];
endExpanderElement.on('click', {
isEnd: true
}, inputFocusEvent);
}
}
}
switch (agjCalendar['inputType']) {
case 'text':
var dateElement = $(options['dateSelector']);
if (dateElement.length !== 1) {
throwError(
'Invalid `dateSelector` value: "' + options['dateSelector'] +
'" (' + dateElement.length + ' elements found, 1 required)'
);
return false;
} else {
agjCalendar['dateSelector'] = options['dateSelector'];
/**
* The inputBlurEvent() function will handle events when an
* integration’s input loses focus.
* @param {object} event - The event object.
* @returns {boolean} - Returns true to allow chaining.
*/
var inputBlurEvent = function(event) {
setTimeout(function() {
switch (agjCalendar['calendarDisplay']) {
case 'full':
case 'modal':
break;
default:
if (!lastClickWasOnAgjCalendar) {
$.agjCalendar.deactivate();
if (event.data.isEnd) {
autoSetEndDate(agjCalendar);
}
}
break;
}
}, 1);
return true;
};
var originalValue = dateElement.val();
dateElement
.on('blur', {
isEnd: false
}, inputBlurEvent)
.on('focus', {
isEnd: false
}, inputFocusEvent);
setDate(agjCalendar, agjCalendar['defaultDate']);
if (originalValue.length > 0) {
dateElement.val(originalValue);
}
if (agjCalendar['allowRange']) {
var endDateElement = $(options['endDateSelector']);
if (endDateElement.length !== 1) {
throwError(
'Invalid `endDateSelector` value: "' +
options['endDateSelector'] + '" (' + endDateElement.length +
' elements found, 1 required)'
);
return false;
} else {
agjCalendar['endDateSelector'] = options['endDateSelector'];
originalValue = endDateElement.val();
endDateElement
.on('blur', {
isEnd: true
}, inputBlurEvent)
.on('focus', {
isEnd: true
}, inputFocusEvent);
setDate(agjCalendar, agjCalendar['defaultEndDate'], true);
if (originalValue.length > 0) {
endDateElement.val(originalValue);
}
}
}
}
break;
case 'dropdown':
var monthElement = $(options['monthSelector']);
if (monthElement.length !== 1) {
throwError(
'Invalid `monthSelector` value: "' +
options['monthSelector'] + '" (' + monthElement.length +
' elements found, 1 required)'
);
return false;
} else {
var dayElement = $(options['daySelector']);
if (dayElement.length !== 1) {
throwError(
'Invalid `daySelector` value: "' + options['daySelector'] +
'" (' + dayElement.length + ' elements found, 1 required)'
);
return false;
} else {
agjCalendar['monthSelector'] = options['monthSelector'];
agjCalendar['daySelector'] = options['daySelector'];
/**
* The monthChangeEvent() function will handle events when an
* integration’s month input changes.
* @param {object} event - The event object.
* @returns {void}
*/
var monthChangeEvent = function(event) {
updateDayElement(agjCalendar, event.data.isEnd);
if (!event.data.isEnd) {
autoSetEndDate(agjCalendar);
}
};
var originalMonthValue = monthElement.val();
var originalDayValue = dayElement.val();
monthElement.on('change', {
isEnd: false
}, monthChangeEvent);
updateMonthElement(agjCalendar);
updateDayElement(agjCalendar);
if (
originalMonthValue !== null &&
originalMonthValue.length > 0 &&
monthElement.find(
'option[value=' + originalMonthValue + ']'
).length > 0
) {
monthElement.val(originalMonthValue).trigger('change');
}
if (
originalDayValue !== null &&
originalDayValue.length > 0 &&
dayElement.find(
'option[value=' + originalDayValue + ']'
).length > 0
) {
dayElement.val(originalDayValue).trigger('change');
}
if (agjCalendar['allowRange']) {
var endMonthElement = $(options['endMonthSelector']);
if (endMonthElement.length !== 1) {
throwError(
'Invalid `endMonthSelector` value: "' +
options['endMonthSelector'] + '" (' +
endMonthElement.length + ' elements found, 1 required)'
);
return false;
} else {
var endDayElement = $(options['endDaySelector']);
if (endDayElement.length !== 1) {
throwError(
'Invalid `endDaySelector` value: "' +
options['endDaySelector'] + '" (' + endDayElement.length +
' elements found, 1 required)'
);
return false;
} else {
agjCalendar['endMonthSelector'] = options['endMonthSelector'];
agjCalendar['endDaySelector'] = options['endDaySelector'];
var originalMonthValue = endMonthElement.val();
var originalDayValue = endDayElement.val();
dayElement.on('change', function() {
autoSetEndDate(agjCalendar);
updateMonthElement(agjCalendar, true);
updateDayElement(agjCalendar, true);
});
endMonthElement.on('change', {
isEnd: true
}, monthChangeEvent);
updateMonthElement(agjCalendar, true);
updateDayElement(agjCalendar, true);
if (
originalMonthValue !== null &&
originalMonthValue.length > 0 &&
endMonthElement.find(
'option[value=' + originalMonthValue + ']'
).length > 0
) {
endMonthElement.val(originalMonthValue).trigger('change');
}
if (
originalDayValue !== null &&
originalDayValue.length > 0 &&
endDayElement.find(
'option[value=' + originalDayValue + ']'
).length > 0
) {
endDayElement.val(originalDayValue).trigger('change');
}
}
}
}
}
}
break;
}
// the integration was successfully initialized, save the configuration in
// the agjCalendars global
agjCalendars.push(agjCalendar);
return true;
};
/**
* The $.agjCalendar.deactivate() function will deactivate/hide all date
* pickers.
* @returns {void}
*/
$.agjCalendar.deactivate = function() {
lastClickWasOnAgjCalendar = false;
var calendarElement = $('#agjCalendar');
if (calendarElement.length > 0) {
$('body').removeClass('agjCalendar-active');
calendarElement.attr('data-active', -1);
$('.agjCalendar-active-input').removeClass('agjCalendar-active-input');
}
hideModalBackground();
};
/**
* The $.agjCalendar.isActive() function will let you know if a date picker
* is active.
* @returns {boolean} - Returns true if the date picker is active or false if
* it’s not.
*/
$.agjCalendar.isActive = function() {
return $('body').hasClass('agjCalendar-active');
};
/**
* The previous name of the agjCalendar plugin was ctcCalendar so this
* function acts solely as an alias to support backwards compatability.
* @param {object} options - A JSON object of configuration options.
* @returns {boolean} - Returns true on success or false on error.
* @deprecated The plugin’s name changed to agjCalendar for version 1.0.0.
*/
$.ctcCalendar = function(options) {
return $.agjCalendar(options);
};
})(jQuery);