/*
* Gijgo DatePicker v1.9.13
* http://gijgo.com/datepicker
*
* Copyright 2014, 2019 gijgo.com
* Released under the MIT license
*/
/* global window alert jQuery gj */
/**
*/
gj.datepicker = {
plugins: {}
};
gj.datepicker.config = {
base: {
/** Whether to display dates in other months at the start or end of the current month.
*/
showOtherMonths: false,
/** Whether days in other months shown before or after the current month are selectable.
* This only applies if the showOtherMonths option is set to true.
*/
selectOtherMonths: true,
/** The width of the datepicker.
*/
width: undefined,
/** The minimum selectable date. When not set, there is no minimum.
*/
minDate: undefined,
/** The maximum selectable date. When not set, there is no maximum
*/
maxDate: undefined,
/** Specifies the format, which is used to format the value of the DatePicker displayed in the input.
*/
format: 'mm/dd/yyyy',
/** The name of the UI library that is going to be in use.
*/
uiLibrary: 'materialdesign',
/** The name of the icons library that is going to be in use. Currently we support Material Icons, Font Awesome and Glyphicons.
*/
iconsLibrary: 'materialicons',
/** The initial datepicker value.
*/
value: undefined,
/** Day of the week start. 0 (Sunday) to 6 (Saturday)
*/
weekStartDay: 0,
/** An array or function that will be used to determine which dates to be disabled for selection by the widget.
*/
disableDates: undefined,
/** An array that will be used to determine which days of week to be disabled for selection by the widget.
* The array needs to contains only numbers where 0 is Sunday, 1 is Monday and etc.
*/
disableDaysOfWeek: undefined,
/** Whether to display week number in year on the left side of the calendar.
*/
calendarWeeks: false,
/** Whether to enable keyboard navigation.
*/
keyboardNavigation: true,
/** The language that needs to be in use.
*/
locale: 'en-us',
icons: {
/** datepicker icon definition.
*/
rightIcon: 'event',
previousMonth: '',
nextMonth: ''
},
fontSize: undefined,
/** The size of the datepicker input.
*/
size: 'default',
/** If set to true, the datepicker will have modal behavior.
*/
modal: false,
/** If set to true, add header to the datepicker.
*/
header: false,
/** If set to true, add footer with ok and cancel buttons to the datepicker.
*/
footer: false,
/** If set to true, show datepicker on input focus.
*/
showOnFocus: true,
/** If set to true, show datepicker icon on the right side of the input.
*/
showRightIcon: true,
style: {
modal: 'gj-modal',
wrapper: 'gj-datepicker gj-datepicker-md gj-unselectable',
input: 'gj-textbox-md',
calendar: 'gj-picker gj-picker-md datepicker gj-unselectable',
footer: '',
button: 'gj-button-md'
}
},
bootstrap: {
style: {
wrapper: 'gj-datepicker gj-datepicker-bootstrap gj-unselectable input-group',
input: 'form-control',
calendar: 'gj-picker gj-picker-bootstrap datepicker gj-unselectable',
footer: 'modal-footer',
button: 'btn btn-default'
},
iconsLibrary: 'glyphicons',
showOtherMonths: true
},
bootstrap4: {
style: {
wrapper: 'gj-datepicker gj-datepicker-bootstrap gj-unselectable input-group',
input: 'form-control',
calendar: 'gj-picker gj-picker-bootstrap datepicker gj-unselectable',
footer: 'modal-footer',
button: 'btn btn-default'
},
showOtherMonths: true
},
fontawesome: {
icons: {
rightIcon: '',
previousMonth: '',
nextMonth: ''
}
},
glyphicons: {
icons: {
rightIcon: '',
previousMonth: '',
nextMonth: ''
}
}
};
gj.datepicker.methods = {
init: function (jsConfig) {
gj.widget.prototype.init.call(this, jsConfig, 'datepicker');
this.attr('data-datepicker', 'true');
gj.datepicker.methods.initialize(this, this.data());
return this;
},
initialize: function ($datepicker, data) {
var $calendar, $rightIcon,
$wrapper = $datepicker.parent('div[role="wrapper"]');
if ($wrapper.length === 0) {
$wrapper = $('
').addClass(data.style.wrapper); // The css class needs to be added before the wrapping, otherwise doesn't work.
$datepicker.wrap($wrapper);
} else {
$wrapper.addClass(data.style.wrapper);
}
$wrapper = $datepicker.parent('div[role="wrapper"]');
data.width && $wrapper.css('width', data.width);
$datepicker.val(data.value).addClass(data.style.input).attr('role', 'input');
data.fontSize && $datepicker.css('font-size', data.fontSize);
if (data.uiLibrary === 'bootstrap' || data.uiLibrary === 'bootstrap4') {
if (data.size === 'small') {
$wrapper.addClass('input-group-sm');
$datepicker.addClass('form-control-sm');
} else if (data.size === 'large') {
$wrapper.addClass('input-group-lg');
$datepicker.addClass('form-control-lg');
}
} else {
if (data.size === 'small') {
$wrapper.addClass('small');
} else if (data.size === 'large') {
$wrapper.addClass('large');
}
}
if (data.showRightIcon) {
if (data.uiLibrary === 'bootstrap') {
$rightIcon = $('' + data.icons.rightIcon + '');
} else if (data.uiLibrary === 'bootstrap4') {
$rightIcon = $('');
} else {
$rightIcon = $(data.icons.rightIcon);
}
$rightIcon.attr('role', 'right-icon');
$rightIcon.on('click', function (e) {
var $calendar = $('body').find('[role="calendar"][guid="' + $datepicker.attr('data-guid') + '"]');
if ($calendar.is(':visible')) {
gj.datepicker.methods.close($datepicker);
} else {
gj.datepicker.methods.open($datepicker, data);
}
});
$wrapper.append($rightIcon);
}
if (data.showOnFocus) {
$datepicker.on('focus', function () {
gj.datepicker.methods.open($datepicker, data);
});
}
$calendar = gj.datepicker.methods.createCalendar($datepicker, data);
if (data.footer !== true) {
$datepicker.on('blur', function () {
$datepicker.timeout = setTimeout(function () {
gj.datepicker.methods.close($datepicker);
}, 500);
});
$calendar.mousedown(function () {
clearTimeout($datepicker.timeout);
document.activeElement !== $datepicker[0] && $datepicker.focus();
return false;
});
$calendar.on('click', function () {
clearTimeout($datepicker.timeout);
document.activeElement !== $datepicker[0] && $datepicker.focus();
});
}
if (data.keyboardNavigation) {
$(document).on('keydown', gj.datepicker.methods.createKeyDownHandler($datepicker, $calendar, data));
}
},
createCalendar: function ($datepicker, data) {
var date, $body, $footer, $btnCancel, $btnOk,
$calendar = $('').addClass(data.style.calendar).attr('guid', $datepicker.attr('data-guid'));
data.fontSize && $calendar.css('font-size', data.fontSize);
date = gj.core.parseDate(data.value, data.format, data.locale);
if (!date || isNaN(date.getTime())) {
date = new Date();
} else {
$datepicker.attr('day', date.getFullYear() + '-' + date.getMonth() + '-' + date.getDate());
}
$calendar.attr('month', date.getMonth());
$calendar.attr('year', date.getFullYear());
gj.datepicker.methods.renderHeader($datepicker, $calendar, data, date);
$body = $('');
$calendar.append($body);
if (data.footer) {
$footer = $('');
$btnCancel = $('');
$btnCancel.on('click', function () { $datepicker.close(); });
$footer.append($btnCancel);
$btnOk = $('');
$btnOk.on('click', function () {
var date, dayArr, dayStr = $calendar.attr('selectedDay');
if (dayStr) {
dayArr = dayStr.split('-');
date = new Date(dayArr[0], dayArr[1], dayArr[2], $calendar.attr('hour') || 0, $calendar.attr('minute') || 0);
gj.datepicker.methods.change($datepicker, $calendar, data, date);
} else {
$datepicker.close();
}
});
$footer.append($btnOk);
$calendar.append($footer);
}
$calendar.hide();
$('body').append($calendar);
if (data.modal) {
$calendar.wrapAll('');
gj.core.center($calendar);
}
return $calendar;
},
renderHeader: function ($datepicker, $calendar, data, date) {
var $header, $date, $year;
if (data.header) {
$header = $('');
$year = $('').on('click', function () {
gj.datepicker.methods.renderDecade($datepicker, $calendar, data);
$year.addClass('selected');
$date.removeClass('selected');
});
$year.html(gj.core.formatDate(date, 'yyyy', data.locale));
$header.append($year);
$date = $('').on('click', function () {
gj.datepicker.methods.renderMonth($datepicker, $calendar, data);
$date.addClass('selected');
$year.removeClass('selected');
});
$date.html(gj.core.formatDate(date, 'ddd, mmm dd', data.locale));
$header.append($date);
$calendar.append($header);
}
},
updateHeader: function ($calendar, data, date) {
$calendar.find('[role="header"] [role="year"]').removeClass('selected').html(gj.core.formatDate(date, 'yyyy', data.locale));
$calendar.find('[role="header"] [role="date"]').addClass('selected').html(gj.core.formatDate(date, 'ddd, mmm dd', data.locale));
$calendar.find('[role="header"] [role="hour"]').removeClass('selected').html(gj.core.formatDate(date, 'HH', data.locale));
$calendar.find('[role="header"] [role="minute"]').removeClass('selected').html(gj.core.formatDate(date, 'MM', data.locale));
},
createNavigation: function ($datepicker, $body, $table, data) {
var $row, $navigator, $thead = $('');
$navigator = $('');
$navigator.append($('
'),
$tbody = $(''),
period = gj.core.messages[data.locale].titleFormat;
$body.off().empty();
gj.datepicker.methods.createNavigation($datepicker, $body, $table, data);
month = parseInt($calendar.attr('month'), 10);
year = parseInt($calendar.attr('year'), 10);
$calendar.attr('type', 'month');
period = period.replace('mmmm', gj.core.messages[data.locale].monthNames[month]).replace('yyyy', year);
$calendar.find('div[role="period"]').text(period);
daysInMonth = new Array(31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31);
if (year % 4 == 0 && year != 1900) {
daysInMonth[1] = 29;
}
total = daysInMonth[month];
firstDayPosition = (new Date(year, month, 1).getDay() + 7 - data.weekStartDay) % 7;
weekDay = 0;
$row = $('
');
prevMonth = gj.datepicker.methods.getPrevMonth(month, year);
for (i = 1; i <= firstDayPosition; i++) {
day = (daysInMonth[prevMonth.month] - firstDayPosition + i);
date = new Date(prevMonth.year, prevMonth.month, day);
if (data.calendarWeeks && i === 1) {
$row.append('
' + gj.datepicker.methods.getWeekNumber(date) + '
');
}
$cell = $('
');
if (data.showOtherMonths) {
$day = $('
' + day + '
');
$cell.append($day);
if (data.selectOtherMonths && gj.datepicker.methods.isSelectable(data, date)) {
$cell.addClass('gj-cursor-pointer').attr('day', day).attr('month', prevMonth.month).attr('year', prevMonth.year);
$day.on('click', gj.datepicker.methods.dayClickHandler($datepicker, $calendar, data, date));
$day.on('mousedown', function (e) { e.stopPropagation() });
} else {
$cell.addClass('disabled');
}
}
$row.append($cell);
weekDay++;
}
if (i > 1) {
$tbody.append($row);
}
now = new Date();
for (i = 1; i <= total; i++) {
date = new Date(year, month, i);
if (weekDay == 0) {
$row = $('