META-INF.resources.primefaces.datepicker.0-datepicker.js Maven / Gradle / Ivy
// ================================================================================
// NOTE: All the documentation and TypeScript declarations are in 0-datepicker.d.ts
// ================================================================================
/**
* Prime DatePicker Widget
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD. Register as an anonymous module.
define(['jquery'], factory);
} else if (typeof module === 'object' && module.exports) {
// Node/CommonJS
module.exports = function (root, jQuery) {
factory(jQuery);
return jQuery;
};
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
$.widget("prime.datePicker", {
options: {
id: null,
name: null,
defaultDate: null,
viewDate: null,
style: null,
styleClass: null,
inline: false,
flex: false,
selectionMode: 'single',
rangeSeparator: '-',
timeSeparator: ':',
fractionSeparator: '.',
inputId: null,
inputStyle: null,
inputStyleClass: null,
required: false,
readOnlyInput: false,
disabled: false,
valid: true,
tabIndex: null,
placeholder: null,
showIcon: false,
icon: 'ui-icon ui-icon-calendar',
showOnFocus: true,
keepInvalid: false,
numberOfMonths: 1,
view: 'date',
touchUI: false,
showWeek: false,
weekCalculator: null,
showTime: false,
timeOnly: false,
showSeconds: false,
showMilliseconds: false,
hourFormat: '24',
stepHour: 1,
stepMinute: 1,
stepSecond: 1,
stepMillisecond: 1,
shortYearCutoff: '+10',
hideOnDateTimeSelect: false,
userLocale: null,
locale: {
firstDayOfWeek: 0,
showMonthAfterYear: false,
dayNames: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"],
dayNamesShort: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"],
dayNamesMin: ["Su", "Mo", "Tu", "We", "Th", "Fr", "Sa"],
monthNames: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"],
monthNamesShort: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"],
today: 'Today',
clear: 'Clear',
now: 'Now',
year: 'Year',
month: 'Month',
week: 'Week',
day: 'Day',
am: 'AM',
pm: 'PM'
},
dateFormat: 'mm/dd/yy',
yearRange: null,
panelStyle: null,
panelStyleClass: null,
monthNavigator: false,
yearNavigator: false,
dateStyleClasses: null,
disabledDates: null,
disabledDays: null,
minDate: null,
maxDate: null,
maxDateCount: null,
showMinMaxRange: true,
showOtherMonths: false,
selectOtherMonths: false,
autoMonthFormat: true,
showButtonBar: false,
todayButtonStyleClass: 'ui-priority-secondary',
clearButtonStyleClass: 'ui-priority-secondary',
appendTo: null,
dateTemplate: null,
timeInput: false,
onFocus: null,
onBlur: null,
onInput: null,
onSelect: null,
onChange: null,
onViewDateChange: null,
onTodayButtonClick: null,
onClearButtonClick: null,
onBeforeShow: null,
onBeforeHide: null,
onMonthChange: null,
onYearChange: null
},
_create: function () {
this.container = this.element;
this.inputfield = this.element.children('input');
this.inputfield.addClass('hasDatepicker'); // needed for ui-float-label
this._setInitValues();
this._render();
},
_setInitValues: function () {
if (this.options.userLocale && typeof this.options.userLocale === 'object') {
$.extend(this.options.locale, this.options.userLocale);
}
if (this.options.timeOnly) {
this.options.showTime = true;
}
if (this.options.showWeek && !this.options.weekCalculator) {
this.options.weekCalculator = this.calculateWeekNumber.bind(this);
// initialize the potentially missing firstDayWeekOffset option
// based on the firstDay(OfWeek) option:
// - firstDay = saturday => firstDayWeekOffset = 12
// - firstDay = sunday => firstDayWeekOffset = 6
// - firstDay = monday (ISO8601) => firstDayWeekOffset = 4
//
// those defaults are based on the locales on the library
// moment.js and won't be correct for _all_ locales.
var sundayIndex = this.getSundayIndex();
if (this.options.locale.firstDayWeekOffset === undefined) {
if (sundayIndex == 0) {
this.options.locale.firstDayWeekOffset = 6;
}
else if (sundayIndex == 1) {
this.options.locale.firstDayWeekOffset = 12;
}
else if (sundayIndex == 6) {
this.options.locale.firstDayWeekOffset = 4;
}
else {
this.options.showWeek = false;
}
}
}
var parsedDefaultDate = this.parseValue(this.options.defaultDate);
var hasMultipleDates = (this.isMultipleSelection() || this.isRangeSelection()) && parsedDefaultDate instanceof Array;
var viewDateDefaultsToNow = false;
this.value = parsedDefaultDate;
if (this.options.viewDate && !hasMultipleDates) {
this.viewDate = this.parseValue(this.options.viewDate);
if (!this.viewDate) {
this.viewDate = new Date();
}
}
else {
if (hasMultipleDates) {
this.viewDate = parsedDefaultDate[0];
}
else {
this.viewDate = parsedDefaultDate;
}
if (this.viewDate === null) {
this.viewDate = new Date();
if (!this.options.showSeconds && !this.options.showMilliseconds) {
this.viewDate.setSeconds(0);
}
if (!this.options.showMilliseconds) {
this.viewDate.setMilliseconds(0);
}
viewDateDefaultsToNow = true;
}
}
// #6047 round to nearest stepMinute on even if editing using keyboard
this.viewDate = this.isDate(this.viewDate) ? new Date(this.viewDate) : new Date();
this.viewDate.setMinutes(this.stepMinute(this.viewDate.getMinutes()));
this.options.minDate = this.parseMinMaxValue(this.options.minDate);
this.options.maxDate = this.parseMinMaxValue(this.options.maxDate);
this.ticksTo1970 = (((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000);
if (viewDateDefaultsToNow) {
if (this.options.minDate) {
if (this.viewDate < this.options.minDate) {
this.viewDate = new Date(this.options.minDate.getTime());
}
}
if (this.options.maxDate) {
if (this.viewDate > this.options.maxDate) {
this.viewDate = new Date(this.options.maxDate.getTime());
}
}
}
if (!this.options.viewDate) {
this.options.viewDate = this.viewDate;
}
this.hasCustomYearRange = this.options.yearRange !== null;
this.updateYearNavigator();
if (this.options.disabledDates) {
for (var i = 0; i < this.options.disabledDates.length; i++) {
this.options.disabledDates[i] = this.parseOptionValue(this.options.disabledDates[i]);
}
}
this.bindResponsiveResizeListener();
},
parseOptionValue: function(option) {
if (option && typeof option === 'string') {
return this.parseDate(option, this.options.dateFormat);
}
return option;
},
parseMinMaxValue: function(option) {
if (option && typeof option === 'string') {
return this.parseDateTime(option);
}
return option;
},
parseValue: function(option) {
if (option && typeof option === 'string') {
return this.parseValueFromString(option);
}
return option;
},
setDate: function(date) {
if (!date) {
this.updateModel(null, null);
return;
}
var newDate = this.parseValue(date);
var newDateMeta = { day: newDate.getDate(), month: newDate.getMonth(), year: newDate.getFullYear(), selectable: true /*, today: true*/ };
/* set changes */
this.value = newDate;
this.updateViewDate(null, newDate);
this.onDateSelect(null, newDateMeta);
},
getDate: function() {
return this.value;
},
getFirstDayOfMonthIndex: function (month, year) {
var day = new Date();
day.setDate(1);
day.setMonth(month);
day.setFullYear(year);
var dayIndex = day.getDay() + this.getSundayIndex();
return dayIndex >= 7 ? dayIndex - 7 : dayIndex;
},
getFirstDayOfWeek: function () {
return this.options.locale.firstDay !== undefined ? this.options.locale.firstDay : this.options.locale.firstDayOfWeek;
},
getSundayIndex: function () {
var firstDayOfWeek = this.getFirstDayOfWeek();
return firstDayOfWeek > 0 ? 7 - firstDayOfWeek : 0;
},
getSaturdayIndex: function () {
return 7 - this.getFirstDayOfWeek() - 1;
},
getDaysCountInMonth: function (month, year) {
return 32 - this.daylightSavingAdjust(new Date(year, month, 32)).getDate();
},
getDaysCountInPrevMonth: function (month, year) {
var prev = this.getPreviousMonthAndYear(month, year);
return this.getDaysCountInMonth(prev.month, prev.year);
},
daylightSavingAdjust: function (date) {
if (!date) {
return null;
}
date.setHours(date.getHours() > 12 ? date.getHours() + 2 : 0);
return date;
},
getPreviousMonthAndYear: function (month, year) {
var m, y;
if (month === 0) {
m = 11;
y = year - 1;
}
else {
m = month - 1;
y = year;
}
return { 'month': m, 'year': y };
},
getNextMonthAndYear: function (month, year) {
var m, y;
if (month === 11) {
m = 0;
y = year + 1;
}
else {
m = month + 1;
y = year;
}
return { 'month': m, 'year': y };
},
createWeekDaysInternal: function (dayNames) {
var weekDays = [],
dayIndex = this.getFirstDayOfWeek();
for (var i = 0; i < 7; i++) {
weekDays.push(dayNames[dayIndex]);
dayIndex = (dayIndex === 6) ? 0 : ++dayIndex;
}
return weekDays;
},
createWeekDaysMin: function () {
return this.createWeekDaysInternal(this.options.locale.dayNamesMin);
},
createWeekDaysShort: function () {
return this.createWeekDaysInternal(this.options.locale.dayNamesShort);
},
createWeekDays: function () {
return this.createWeekDaysInternal(this.options.locale.dayNames);
},
createMonths: function (month, year) {
var months = [];
for (var i = 0; i < this.options.numberOfMonths; i++) {
var m = month + i,
y = year;
if (m > 11) {
y = year + Math.floor(m / 12);
m = m % 12;
}
months.push(this.createMonth(m, y, i));
}
return months;
},
createMonth: function (month, year, index) {
var dates = [];
firstDay = this.getFirstDayOfMonthIndex(month, year);
daysLength = this.getDaysCountInMonth(month, year);
prevMonthDaysLength = this.getDaysCountInPrevMonth(month, year);
dayNo = 1;
today = new Date();
monthRows = Math.ceil((daysLength + firstDay) / 7);
for (var i = 0; i < monthRows; i++) {
var week = [];
if (i === 0) {
for (var j = (prevMonthDaysLength - firstDay + 1); j <= prevMonthDaysLength; j++) {
var prev = this.getPreviousMonthAndYear(month, year);
week.push({
day: j, month: prev.month, year: prev.year, otherMonth: true,
today: this.isToday(today, j, prev.month, prev.year), selectable: this.isSelectable(j, prev.month, prev.year, true)
});
}
var remainingDaysLength = 7 - week.length;
for (var j = 0; j < remainingDaysLength; j++) {
week.push({
day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year),
selectable: this.isSelectable(dayNo, month, year, false)
});
dayNo++;
}
}
else {
for (var j = 0; j < 7; j++) {
if (dayNo > daysLength) {
var next = this.getNextMonthAndYear(month, year);
week.push({
day: dayNo - daysLength, month: next.month, year: next.year, otherMonth: true,
today: this.isToday(today, dayNo - daysLength, next.month, next.year),
selectable: this.isSelectable((dayNo - daysLength), next.month, next.year, true)
});
}
else {
week.push({
day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year),
selectable: this.isSelectable(dayNo, month, year, false)
});
}
dayNo++;
}
}
dates.push(week);
}
return {
month: month,
year: year,
dates: dates,
index: index
};
},
isSelectable: function (day, month, year, otherMonth) {
var validMin = true;
validMax = true;
validDate = true;
validDay = true;
validMonth = true;
if (this.options.minDate) {
if (this.options.minDate.getFullYear() > year) {
validMin = false;
}
else if (this.options.minDate.getFullYear() === year) {
if (this.options.minDate.getMonth() > month) {
validMin = false;
}
else if (this.options.minDate.getMonth() === month) {
if (this.options.minDate.getDate() > day) {
validMin = false;
}
}
}
}
if (this.options.maxDate) {
if (this.options.maxDate.getFullYear() < year) {
validMax = false;
}
else if (this.options.maxDate.getFullYear() === year) {
if (this.options.maxDate.getMonth() < month) {
validMax = false;
}
else if (this.options.maxDate.getMonth() === month) {
if (this.options.maxDate.getDate() < day) {
validMax = false;
}
}
}
}
if (this.options.disabledDates) {
validDate = !this.isDateDisabled(day, month, year);
}
if (this.options.disabledDays) {
validDay = !this.isDayDisabled(day, month, year);
}
if (this.options.selectOtherMonths === false && otherMonth) {
validMonth = false;
}
return validMin && validMax && validDate && validDay && validMonth;
},
isSelected: function (dateMeta) {
if (this.value) {
if (this.isSingleSelection()) {
return this.isDateEquals(this.value, dateMeta);
}
else if (this.isMultipleSelection()) {
var selected = false;
for (var i = 0; i < this.value.length; i++) {
var date = this.value[i];
selected = this.isDateEquals(date, dateMeta);
if (selected) {
break;
}
}
return selected;
}
else if (this.isRangeSelection()) {
if (this.value[1])
return this.isDateEquals(this.value[0], dateMeta) || this.isDateEquals(this.value[1], dateMeta) || this.isDateBetween(this.value[0], this.value[1], dateMeta);
else
return this.isDateEquals(this.value[0], dateMeta);
}
}
else {
return false;
}
},
isMonthSelected: function (month) {
if (this.value) {
if (this.isRangeSelection()) {
var dateMeta = { year: this.viewDate.getFullYear(), month: month, day: 1, selectable: true };
if (this.value[1])
return this.isDateEquals(this.value[0], dateMeta) || this.isDateEquals(this.value[1], dateMeta) || this.isDateBetween(this.value[0], this.value[1], dateMeta);
else
return this.isDateEquals(this.value[0], dateMeta);
}
else {
return this.isDate(this.value) && this.value.getMonth() === month && this.value.getFullYear() === this.viewDate.getFullYear();
}
}
return false;
},
isDateEquals: function (value, dateMeta) {
if (this.isDate(value))
return value.getDate() === dateMeta.day && value.getMonth() === dateMeta.month && value.getFullYear() === dateMeta.year;
else
return false;
},
isDateBetween: function (start, end, dateMeta) {
var between = false;
if (this.isDate(start) && this.isDate(end)) {
var date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
return start.getTime() <= date.getTime() && end.getTime() >= date.getTime();
}
return between;
},
isSingleSelection: function () {
return this.options.selectionMode === 'single';
},
isRangeSelection: function () {
return this.options.selectionMode === 'range';
},
isMultipleSelection: function () {
return this.options.selectionMode === 'multiple';
},
isToday: function (today, day, month, year) {
return today.getDate() === day && today.getMonth() === month && today.getFullYear() === year;
},
isDateDisabled: function (day, month, year) {
if (this.options.disabledDates) {
for (var i = 0; i < this.options.disabledDates.length; i++) {
var disabledDate = this.options.disabledDates[i];
if (disabledDate.getFullYear() === year && disabledDate.getMonth() === month && disabledDate.getDate() === day) {
return true;
}
}
}
return false;
},
isDayDisabled: function (day, month, year) {
if (this.options.disabledDays) {
var weekday = new Date(year, month, day),
weekdayNumber = weekday.getDay();
return this.options.disabledDays.indexOf(weekdayNumber) !== -1;
}
return false;
},
getValueToRender: function () {
var formattedValue = '';
if (this.value) {
try {
if (this.isSingleSelection()) {
formattedValue = this.formatDateTime(this.value);
}
else if (this.isMultipleSelection()) {
for (var i = 0; i < this.value.length; i++) {
var dateAsString = this.formatDateTime(this.value[i]);
formattedValue += dateAsString;
if (i !== (this.value.length - 1)) {
formattedValue += ', ';
}
}
}
else if (this.isRangeSelection()) {
if (this.value && this.value.length) {
var startDate = this.value[0],
endDate = this.value[1];
formattedValue = this.formatDateTime(startDate);
if (endDate) {
formattedValue += ' ' + this.options.rangeSeparator + ' ' + this.formatDateTime(endDate);
}
}
}
}
catch (err) {
formattedValue = this.value;
}
}
return formattedValue;
},
formatDateTime: function (date) {
var formattedValue = null;
if (date) {
if (this.options.timeOnly) {
formattedValue = this.formatTime(date);
}
else {
formattedValue = this.formatDate(date, this.options.dateFormat);
if (this.options.showTime) {
formattedValue += ' ' + this.formatTime(date);
}
}
}
return formattedValue;
},
// Ported from jquery-ui datepicker formatDate
formatDate: function (date, format) {
if (!date) {
return '';
}
var iFormat,
lookAhead = function (match) {
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
if (matches) {
iFormat++;
}
return matches;
},
formatNumber = function (match, value, len) {
var num = '' + value;
if (lookAhead(match)) {
while (num.length < len) {
num = '0' + num;
}
}
return num;
},
formatName = function (match, value, shortNames, longNames) {
return (lookAhead(match) ? longNames[value] : shortNames[value]);
};
var output = '',
literal = false;
if (date) {
for (iFormat = 0; iFormat < format.length; iFormat++) {
if (literal) {
if (format.charAt(iFormat) === '\'' && !lookAhead('\'')) {
literal = false;
} else {
output += format.charAt(iFormat);
}
} else {
switch (format.charAt(iFormat)) {
case 'd':
output += formatNumber('d', date.getDate(), 2);
break;
case 'D':
output += formatName('D', date.getDay(), this.options.locale.dayNamesShort, this.options.locale.dayNames);
break;
case 'o':
output += formatNumber('o',
Math.round((
new Date(date.getFullYear(), date.getMonth(), date.getDate()).getTime() -
new Date(date.getFullYear(), 0, 0).getTime()) / 86400000), 3);
break;
case 'm':
output += formatNumber('m', date.getMonth() + 1, 2);
break;
case 'M':
output += formatName('M', date.getMonth(), this.options.locale.monthNamesShort, this.options.locale.monthNames);
break;
case 'y':
output += lookAhead('y') ? date.getFullYear() : (date.getFullYear() % 100 < 10 ? '0' : '') + (date.getFullYear() % 100);
break;
case '@':
output += date.getTime();
break;
case '!':
output += date.getTime() * 10000 + this.ticksTo1970;
break;
case '\'':
if (lookAhead('\'')) {
output += '\'';
} else {
literal = true;
}
break;
default:
output += format.charAt(iFormat);
}
}
}
}
return output;
},
formatTime: function (date) {
if (!date) {
return '';
}
var output = '',
hours = date.getHours(),
minutes = date.getMinutes(),
seconds = date.getSeconds(),
milliseconds = date.getMilliseconds();
if (this.options.hourFormat === '12' && hours > 11 && hours !== 12) {
hours -= 12;
}
if (this.options.hourFormat === '12') {
output += hours === 0 ? 12 : (hours < 10) ? '0' + hours : hours;
} else {
output += (hours < 10) ? '0' + hours : hours;
}
output += this.options.timeSeparator;
output += (minutes < 10) ? '0' + minutes : minutes;
if (this.options.showSeconds) {
output += this.options.timeSeparator;
output += (seconds < 10) ? '0' + seconds : seconds;
}
if (this.options.showMilliseconds) {
output += this.options.fractionSeparator;
output += (milliseconds < 10) ? '00' + milliseconds : (milliseconds < 100) ? '0' + milliseconds : milliseconds;
}
if (this.options.hourFormat === '12') {
output += date.getHours() > 11 ? ' ' + this.options.locale.pm : ' ' + this.options.locale.am;
}
return output;
},
parseTime: function (value, ampm) {
var val = value.replace(this.options.fractionSeparator, this.options.timeSeparator),
tokens = val.split(this.options.timeSeparator),
showSeconds = this.options.showSeconds || this.options.showMilliseconds,
validTokenLength = 2 + (showSeconds ? 1 : 0) + (this.options.showMilliseconds ? 1 : 0);
if (tokens.length !== validTokenLength) {
throw "Invalid time";
}
var h = parseInt(tokens[0]),
m = parseInt(tokens[1]),
s = showSeconds ? parseInt(tokens[2]) : null,
ms = this.options.showMilliseconds ? parseInt(tokens[3]) : null;
if (isNaN(h) || isNaN(m) || h > 23 || m > 59 || (this.options.hourFormat === '12' && h > 12) || (this.options.showSeconds && (isNaN(s) || s > 59)) || (this.options.showMilliseconds && (isNaN(ms) || ms > 999))) {
throw "Invalid time";
}
else {
if (this.options.hourFormat === '12' && h !== 12 && ampm === this.options.locale.pm) {
h += 12;
} else if (this.options.hourFormat === '12' && h === 12 && ampm === this.options.locale.am) {
h -= 12;
}
return { hour: h, minute: m, second: s, millisecond: ms };
}
},
// Ported from jquery-ui datepicker parseDate
parseDate: function (value, format) {
if (format == null || value == null) {
throw "Invalid arguments";
}
value = (typeof value === "object" ? value.toString() : value + "");
if (value === "") {
return null;
}
var iFormat, dim, extra,
iValue = 0,
shortYearCutoff = (typeof this.options.shortYearCutoff !== "string" ? this.options.shortYearCutoff : new Date().getFullYear() % 100 + parseInt(this.options.shortYearCutoff, 10)),
year = -1,
month = -1,
day = -1,
doy = -1,
literal = false,
date,
lookAhead = function (match) {
var matches = (iFormat + 1 < format.length && format.charAt(iFormat + 1) === match);
if (matches) {
iFormat++;
}
return matches;
},
getNumber = function (match) {
var isDoubled = lookAhead(match),
size = (match === "@" ? 14 : (match === "!" ? 20 :
(match === "y" && isDoubled ? 4 : (match === "o" ? 3 : 2)))),
minSize = (match === "y" ? size : 1),
digits = new RegExp("^\\d{" + minSize + "," + size + "}"),
num = value.substring(iValue).match(digits);
if (!num && match === "y" && isDoubled) {
//allow 2 digit-inputs for 4-digit-year-pattern (gets reformated to 4 digits onBlur)
digits = new RegExp("^\\d{" + 2 + "," + size + "}"),
num = value.substring(iValue).match(digits);
}
if (!num) {
throw "Missing number at position " + iValue;
}
iValue += num[0].length;
return parseInt(num[0], 10);
},
getName = function (match, shortNames, longNames) {
var index = -1,
arr = lookAhead(match) ? longNames : shortNames,
names = [];
for (var i = 0; i < arr.length; i++) {
names.push([i, arr[i]]);
}
names.sort(function (a, b) {
return -(a[1].length - b[1].length);
});
for (var i = 0; i < names.length; i++) {
var name = names[i][1];
if (value.substr(iValue, name.length).toLowerCase() === name.toLowerCase()) {
index = names[i][0];
iValue += name.length;
break;
}
}
if (index !== -1) {
return index + 1;
} else {
throw "Unknown name at position " + iValue;
}
},
checkLiteral = function() {
if (value.charAt(iValue) !== format.charAt(iFormat)) {
throw "Unexpected literal at position " + iValue;
}
iValue++;
};
if (this.options.view === 'month') {
day = 1;
}
for (iFormat = 0; iFormat < format.length; iFormat++) {
if (literal) {
if (format.charAt(iFormat) === "'" && !lookAhead("'")) {
literal = false;
} else {
checkLiteral();
}
} else {
switch (format.charAt(iFormat)) {
case "d":
day = getNumber("d");
break;
case "D":
getName("D", this.options.locale.dayNamesShort, this.options.locale.dayNames);
break;
case "o":
doy = getNumber("o");
break;
case "m":
month = getNumber("m");
break;
case "M":
month = getName("M", this.options.locale.monthNamesShort, this.options.locale.monthNames);
break;
case "y":
year = getNumber("y");
break;
case "@":
date = new Date(getNumber("@"));
year = date.getFullYear();
month = date.getMonth() + 1;
day = date.getDate();
break;
case "!":
date = new Date((getNumber("!") - this.ticksTo1970) / 10000);
year = date.getFullYear();
month = date.getMonth() + 1;
day = date.getDate();
break;
case "'":
if (lookAhead("'")) {
checkLiteral();
} else {
literal = true;
}
break;
default:
checkLiteral();
}
}
}
if (iValue < value.length) {
extra = value.substr(iValue);
if (!/^\s+/.test(extra)) {
throw "Extra/unparsed characters found in date: " + extra;
}
}
if (year === -1) {
year = new Date().getFullYear();
} else if (year < 100) {
year += new Date().getFullYear() - new Date().getFullYear() % 100 +
(year <= shortYearCutoff ? 0 : -100);
}
if (doy > -1) {
month = 1;
day = doy;
do {
dim = this.getDaysCountInMonth(year, month - 1);
if (day <= dim) {
break;
}
month++;
day -= dim;
} while (true);
}
date = this.daylightSavingAdjust(new Date(year, month - 1, day));
if (date.getFullYear() !== year || date.getMonth() + 1 !== month || date.getDate() !== day) {
throw "Invalid date"; // E.g. 31/02/00
}
return date;
},
parseValueFromString: function (text) {
if (!text || text.trim().length === 0) {
return null;
}
var value;
try {
if (this.isSingleSelection()) {
value = this.parseDateTime(text);
}
else if (this.isMultipleSelection()) {
var tokens = text.split(',');
value = [];
for (var i = 0; i < tokens.length; i++) {
value.push(this.parseDateTime(tokens[i].trim()));
}
}
else if (this.isRangeSelection()) {
var tokens = text.split(new RegExp(this.options.rangeSeparator + '| ' + this.options.rangeSeparator + ' ', 'g'));
value = [];
for (var i = 0; i < tokens.length; i++) {
value[i] = this.parseDateTime(tokens[i].trim());
}
}
} catch (error) {
PrimeFaces.error("DatePicker Error: " + error);
}
return value;
},
parseDateTime: function (text) {
var date,
parts = text.split(' ');
if (this.options.timeOnly) {
date = new Date();
this.populateTime(date, parts[0], parts[1]);
}
else {
if (this.options.showTime) {
var ampm = this.options.hourFormat === '12' ? parts.pop() : null;
var timeString = parts.pop();
// #9559 some locales are "a. m." with a space
if (/\d/.test(timeString) === false) {
ampm = timeString + ' ' + ampm;
timeString = parts.pop();
}
date = this.parseDate(parts.join(' '), this.options.dateFormat);
this.populateTime(date, timeString, ampm);
}
else {
date = this.parseDate(text, this.options.dateFormat);
}
}
return date;
},
populateTime: function (value, timeString, ampm) {
if (this.options.hourFormat === '12' && (ampm !== this.options.locale.pm && ampm !== this.options.locale.am)) {
throw new Error('Invalid Time');
}
var time = this.parseTime(timeString, ampm);
value.setHours(time.hour);
value.setMinutes(this.stepMinute(time.minute));
if (this.options.showSeconds || this.options.showMilliseconds) {
value.setSeconds(time.second);
}
else {
value.setSeconds(0);
}
if (this.options.showMilliseconds) {
value.setMilliseconds(time.millisecond);
}
else {
value.setMilliseconds(0);
}
},
isInMinYear: function() {
return this.options.minDate && this.options.minDate.getFullYear() === this.viewDate.getFullYear();
},
isInMaxYear: function() {
return this.options.maxDate && this.options.maxDate.getFullYear() === this.viewDate.getFullYear();
},
_destroy: function () {
this.hideOverlay();
},
/**
* @override
* @protected
*/
_render: function () {
if (this.options.styleClass) {
this.container.addClass(this.options.styleClass);
}
if (this.options.style) {
this.container.attr('style', this.options.style);
}
if (!this.options.inline) {
if (this.options.inputStyleClass) {
this.inputfield.addClass(this.options.inputStyleClass);
}
if (this.options.inputStyle) {
this.inputfield.attr('style', this.options.inputStyle);
}
}
if (this.options.showIcon && !this.options.inline) {
if (this.triggerButton) {
this.triggerButton.remove();
}
this.renderTriggerButton();
this.container.append(this.triggerButton);
this.container.addClass('ui-trigger-calendar');
}
if (this.panel) {
this.panel.remove();
}
this.renderDatePickerPanel();
if (this.options.panelStyleClass) {
this.panel.addClass(this.options.panelStyleClass);
}
if (this.options.panelStyle) {
this.panel.attr('style', this.options.panelStyle);
}
if (!this.options.inline && this.options.appendTo) {
// remove old overlay first
// See PrimeFaces.utils.appendDynamicOverlay
$(this.options.appendTo)
.children("[id='" + $(this.container).attr('id') + "_panel']")
.not(this.panel)
.remove();
this.panel.appendTo(this.options.appendTo);
}
else {
this.panel.appendTo(this.container);
}
this._setInitOptionValues();
this._bindEvents();
this.transition = PrimeFaces.utils.registerCSSTransition(this.panel, 'ui-connected-overlay');
},
_setInitOptionValues: function () {
if (this.options.yearNavigator) {
var year = this.viewDate.getFullYear();
var month = this.viewDate.getMonth();
var yearElts = this.panel.find('.ui-datepicker-header > .ui-datepicker-title > .ui-datepicker-year');
yearElts.each(function( index, yearElt ) {
$(yearElt).val(year);
month = month + 1;
if (month === 12) {
month = 0;
year = year + 1;
}
});
}
if (this.options.monthNavigator && this.options.view !== 'month') {
var month = this.viewDate.getMonth();
var monthElts = this.panel.find('.ui-datepicker-header > .ui-datepicker-title > .ui-datepicker-month');
monthElts.each(function( index, monthElt ) {
$(monthElt).val(month);
month = month + 1;
if (month === 12) {
month = 0;
}
});
}
// #6379 set state of navigator buttons
this.setNavigationState(this.viewDate);
},
renderTriggerButton: function () {
this.triggerButton = $('');
},
renderDatePickerPanel: function () {
//add classes according to conditions
var _classes = this.getClassesToAdd({
'ui-datepicker-inline': this.options.inline,
'ui-shadow': !this.options.inline,
'ui-input-overlay': !this.options.inline,
'ui-state-disabled': this.options.disabled,
'ui-state-error': this.options.inline && !this.options.valid,
'ui-datepicker-timeonly': this.options.timeOnly,
'ui-datepicker-multiple-month': this.options.numberOfMonths > 1,
'ui-datepicker-monthpicker': (this.options.view === 'month'),
'ui-datepicker-touch-ui': this.options.touchUI
});
var panelId = this.container.attr('id') + '_panel';
this.panel = $('');
//render inner elements
this.panel.get(0).innerHTML = this.renderPanelElements();
this.panel.css({
'display': this.options.inline ? 'block' : 'none',
'position': this.options.inline || this.options.touchUI ? '' : 'absolute'
});
if (this.options.onPanelCreate) {
this.options.onPanelCreate.call(this);
}
},
renderPanelElements: function () {
var elementsHtml = '';
if(this.options.disabled) {
this.panel.addClass('ui-state-disabled');
}
else {
this.panel.removeClass('ui-state-disabled');
}
if (!this.options.timeOnly) {
if (this.options.view === 'date') {
elementsHtml += this.renderDateView();
}
else if (this.options.view === 'month') {
elementsHtml += this.renderMonthView();
}
}
if (this.options.showTime || this.options.timeOnly) {
elementsHtml += this.renderTimePicker();
}
if (this.options.showButtonBar) {
elementsHtml += this.renderButtonBar();
}
return elementsHtml;
},
renderDateView: function () {
this.monthsMetadata = this.createMonths(this.viewDate.getMonth(), this.viewDate.getFullYear());
var months = this.renderMonths(this.monthsMetadata);
return months;
},
renderMonthView: function () {
var backwardNavigator = this.renderBackwardNavigator(),
forwardNavigator = this.renderForwardNavigator(),
yearElement = this.renderTitleYearElement(this.viewDate.getFullYear()),
months = this.renderMonthViewMonths();
return ('' +
months +
'' +
'
' +
'
' + content + '
';
},
renderDayNames: function (weekDaysMin, weekDays) {
var dayNamesHtml = '';
if(this.options.showWeek) {
dayNamesHtml += '' +
'' +
'' +
'
' +
'
'
);
},
renderHourPicker: function () {
var hour = this.isDate(this.value) ? this.value.getHours() : this.viewDate.getHours();
if (this.options.hourFormat === '12') {
if (hour === 0)
hour = 12;
else if (hour > 11 && hour !== 12)
hour = hour - 12;
}
var hourDisplay = hour < 10 ? '0' + hour : hour;
//type="number" min="' + minHour + '" max="' + maxHour + '" - does not work well on Firefox 70, so we don´t use it
var tabindex = this.options.inline ? '0' : '1';
var html = this.options.timeInput ? '' : '' + hourDisplay + '';
return this.renderTimeElements("ui-hour-picker", html, 0);
},
renderMinutePicker: function () {
var minute = this.isDate(this.value) ? this.value.getMinutes() : this.viewDate.getMinutes(),
minuteDisplay = minute < 10 ? '0' + minute : minute;
//type="number" min="0" max="59" does not work well on Firefox 70, so we don´t use it
var tabindex = this.options.inline ? '0' : '2';
var html = this.options.timeInput ? '' : '' + minuteDisplay + '';
return this.renderTimeElements("ui-minute-picker", html, 1);
},
renderSecondPicker: function () {
if (this.options.showSeconds) {
var second = this.isDate(this.value) ? this.value.getSeconds() : this.viewDate.getSeconds(),
secondDisplay = second < 10 ? '0' + second : second;
//type="number" min="0" max="59" does not work well on Firefox 70, so we don´t use it
var tabindex = this.options.inline ? '0' : '3';
var html = this.options.timeInput ? '' : '' + secondDisplay + '';
return this.renderTimeElements("ui-second-picker", html, 2);
}
return '';
},
renderMillisecondPicker: function () {
if (this.options.showMilliseconds) {
var millisecond = this.isDate(this.value) ? this.value.getMilliseconds() : this.viewDate.getMilliseconds(),
millisecondDisplay = millisecond < 10 ? '00' + millisecond : millisecond < 100 ? '0' + millisecond : millisecond;
//type="number" min="0" max="999" does not work well on Firefox 70, so we don´t use it
var tabindex = this.options.inline ? '0' : '4';
var html = this.options.timeInput ? '' : '' + millisecondDisplay + '';
return this.renderTimeElements("ui-millisecond-picker", html, 3);
}
return '';
},
renderAmPmPicker: function () {
if (this.options.hourFormat === '12') {
var hour = this.isDate(this.value) ? this.value.getHours() : this.viewDate.getHours(),
display = hour > 11 ? this.options.locale.pm : this.options.locale.am;
return this.renderTimeElements("ui-ampm-picker", '' + display + '', 4);
}
return '';
},
renderSeparator: function () {
return this.renderTimeElements("ui-separator", ':', -1);
},
renderFractionSeparator: function () {
return this.renderTimeElements("ui-separator", '.', -1);
},
renderTimeElements: function (containerClass, text, type) {
var container = '';
//up
container += this.renderTimePickerUpButton();
//text
container += text;
//down
container += this.renderTimePickerDownButton();
//end
container += '
';
return container;
},
renderTimePickerUpButton: function () {
return '' +
'' +
'';
},
renderTimePickerDownButton: function () {
return '' +
'' +
'';
},
getClassesToAdd: function (classes) {
var _classes = '';
$.each(classes, function (key, value) {
if (value) {
_classes += ' ' + key;
}
});
return _classes;
},
toISODateString: function (date) {
return new Date(date.getTime() - (date.getTimezoneOffset() * 60000)).toISOString().substring(0, 10);
},
_bindEvents: function () {
var $this = this;
if (!this.options.inline) {
this.inputfield.off('focus.datePicker blur.datePicker keydown.datePicker input.datePicker click.datePicker')
.on('focus.datePicker', this.onInputFocus.bind($this))
.on('blur.datePicker', this.onInputBlur.bind($this))
.on('change.datePicker', this.onInputChange.bind($this))
.on('keydown.datePicker', this.onInputKeyDown.bind($this))
.on('input.datePicker', this.onUserInput.bind($this))
.on('click.datePicker', this.onInputClick.bind($this));
if (this.triggerButton) {
this.triggerButton.off('click.datePicker-triggerButton').on('click.datePicker-triggerButton', this.onButtonClick.bind($this));
}
}
this.panel.off('click.datePicker').on('click.datePicker', this.onPanelClick.bind($this));
var navBackwardSelector = '.ui-datepicker-header > .ui-datepicker-prev',
navForwardSelector = '.ui-datepicker-header > .ui-datepicker-next';
this.panel.off('click.datePicker-navBackward', navBackwardSelector).on('click.datePicker-navBackward', navBackwardSelector, null, this.navBackward.bind($this));
this.panel.off('click.datePicker-navForward', navForwardSelector).on('click.datePicker-navForward', navForwardSelector, null, this.navForward.bind($this));
var monthNavigatorSelector = '.ui-datepicker-header > .ui-datepicker-title > .ui-datepicker-month',
yearNavigatorSelector = '.ui-datepicker-header > .ui-datepicker-title > .ui-datepicker-year';
this.panel.off('change.datePicker-monthNav', monthNavigatorSelector).on('change.datePicker-monthNav', monthNavigatorSelector, null, this.onMonthDropdownChange.bind($this));
this.panel.off('change.datePicker-yearNav', yearNavigatorSelector).on('change.datePicker-yearNav', yearNavigatorSelector, null, this.onYearDropdownChange.bind($this));
var monthViewMonthSelector = '.ui-monthpicker > .ui-monthpicker-month';
this.panel.off('change.datePicker-monthViewMonth', monthViewMonthSelector).on('click.datePicker-monthViewMonth', monthViewMonthSelector, null, function (e) {
$this.onMonthSelect(e, $(this).index());
});
var timeSelector = '.ui-hour-picker > a, .ui-minute-picker > a, .ui-second-picker > a, .ui-millisecond-picker > a',
ampmSelector = '.ui-ampm-picker > a';
this.panel.off('mousedown.datePicker-time mouseup.datePicker-time mouseleave.datePicker-time', timeSelector).off('click.datePicker-ampm', ampmSelector)
.on('mousedown.datePicker-time', timeSelector, null, function (event) {
var button = $(this),
parentEl = button.parent();
$this.onTimePickerElementMouseDown(event, parseInt(parentEl.data('type'), 10), button.hasClass('ui-picker-up') ? 1 : -1);
})
.on('mouseup.datePicker-time', timeSelector, null, function (event) {
$this.onTimePickerElementMouseUp(event);
})
.on('mouseleave.datePicker-time', timeSelector, null, function (event) {
if ($this.timePickerTimer) {
$this.onTimePickerElementMouseUp(event);
}
})
.on('click.datePicker-ampm', ampmSelector, null, function (event) {
$this.toggleAmPm(event);
});
if (this.options.timeInput) {
this.panel.off('focus', '.ui-hour-picker input').on('focus', '.ui-hour-picker input', null, function (event) {
$this.oldHours = this.value;
}).off('focus', '.ui-minute-picker input').on('focus', '.ui-minute-picker input', null, function (event) {
$this.oldMinutes = this.value;
}).off('focus', '.ui-second-picker input').on('focus', '.ui-second-picker input', null, function (event) {
$this.oldSeconds = this.value;
}).off('focus', '.ui-millisecond-picker input').on('focus', '.ui-millisecond-picker input', null, function (event) {
$this.oldMilliseconds = this.value;
}).off('change', '.ui-hour-picker input').on('change', '.ui-hour-picker input', null, function (event) {
$this.handleHoursInput(this, event);
}).off('change', '.ui-minute-picker input').on('change', '.ui-minute-picker input', null, function (event) {
$this.handleMinutesInput(this, event);
}).off('change', '.ui-second-picker input').on('change', '.ui-second-picker input', null, function (event) {
$this.handleSecondsInput(this, event);
}).off('change', '.ui-millisecond-picker input').on('change', '.ui-millisecond-picker input', null, function (event) {
$this.handleMillisecondsInput(this, event);
});
}
var todayButtonSelector = '.ui-datepicker-buttonbar .ui-today-button',
clearButtonSelector = '.ui-datepicker-buttonbar .ui-clear-button';
this.panel.off('click.datePicker-todayButton', todayButtonSelector).on('click.datePicker-todayButton', todayButtonSelector, null, this.onTodayButtonClick.bind($this));
this.panel.off('click.datePicker-clearButton', clearButtonSelector).on('click.datePicker-clearButton', clearButtonSelector, null, this.onClearButtonClick.bind($this));
var dateSelector = '.ui-datepicker-calendar td a';
this.panel.off('click.datePicker-date', dateSelector).on('click.datePicker-date', dateSelector, null, function (event) {
if ($this.monthsMetadata) {
var dayEl = $(this),
calendarIndex = dayEl.closest('.ui-datepicker-group').index(),
weekIndex = dayEl.closest('tr').index(),
dayIndex = dayEl.closest('td').index() - ($this.options.showWeek ? 1 : 0);
$this.onDateSelect(event, $this.monthsMetadata[calendarIndex].dates[weekIndex][dayIndex]);
}
});
},
onInputClick: function (event) {
if (this.documentClickListener) {
this.datepickerClick = true;
}
if (this.options.showOnFocus && !this.isPanelVisible()) {
this.showOverlay();
}
},
onInputFocus: function (event) {
if (this.options.showOnFocus && !this.isPanelVisible()) {
this.showOverlay();
}
if (this.options.onFocus) {
this.options.onFocus.call(this, event);
}
this.inputfield.addClass('ui-state-focus');
this.container.addClass('ui-inputwrapper-focus');
},
onInputBlur: function (event) {
if (this.options.onBlur) {
this.options.onBlur.call(this, event);
}
this.inputfield.removeClass('ui-state-focus');
this.container.removeClass('ui-inputwrapper-focus');
},
onInputChange: function(event) {
// TODO: The following code block will be rearranged according to PrimeNG/React/Vue library in future versions.
if ((this.options.autoMonthFormat || !this.inputfield.val() || this.options.showMinMaxRange) && this.options.monthNavigator && this.options.view !== 'month') {
var viewMonth = this.viewDate.getMonth();
viewMonth = (this.isInMaxYear() && Math.min(this.options.maxDate.getMonth(), viewMonth)) || (this.isInMinYear() && Math.max(this.options.minDate.getMonth(), viewMonth)) || viewMonth;
this.viewDate.setMonth(viewMonth);
}
!this.options.keepInvalid && this.inputfield.val(this.getValueToRender());
if (this.options.onChange) {
this.options.onChange.call(this, event);
}
},
onInputKeyDown: function (event) {
if (event.keyCode === 13) {
this.inputfield.val(this.getValueToRender());
}
if (event.keyCode === 27) {
//put the focus back to the inputfield
this.inputfield.trigger('focus');
}
if (event.keyCode === 9 || event.keyCode === 27) {
if (this.options.touchUI) {
this.disableModality();
}
this.hideOverlay();
}
},
onUserInput: function (event) {
var rawValue = event.target.value;
try {
var value = this.parseValueFromString(rawValue);
this.updateModel(event, value, false);
this.updateViewDate(event, value.length ? value[0] : value);
}
catch (err) {
//invalid date - TODO: Update according to PrimeNG/React/Vue library in future versions.
// var value = this.options.keepInvalid ? rawValue : null;
if (!this.options.mask) {
this.updateModel(event, rawValue, false);
}
}
if (this.options.onInput) {
this.options.onInput.call(this, event);
}
},
onButtonClick: function (event) {
if (!this.isPanelVisible()) {
this.inputfield.trigger('focus');
this.showOverlay();
}
else {
this.hideOverlay();
}
},
onPanelClick: function (event) {
if (this.documentClickListener) {
this.datepickerClick = true;
}
},
onMonthDropdownChange: function (event) {
var newViewDate = new Date(this.viewDate.getTime());
newViewDate.setDate(1); //always set to first of month
newViewDate.setMonth(parseInt(event.target.value, 10));
if (this.options.onMonthChange) {
this.options.onMonthChange.call(this, newViewDate.getMonth() + 1, newViewDate.getFullYear());
}
this.updateViewDate(event, newViewDate);
},
onYearDropdownChange: function (event) {
var newViewDate = new Date(this.viewDate.getTime());
newViewDate.setFullYear(parseInt(event.target.value, 10));
if (this.options.onYearChange) {
this.options.onYearChange.call(this, newViewDate.getMonth(), newViewDate.getFullYear());
}
this.updateViewDate(event, newViewDate);
},
onMonthSelect: function (event, month) {
this.onDateSelect(event, { year: this.viewDate.getFullYear(), month: month, day: 1, selectable: true });
event.preventDefault();
},
navBackward: function (event) {
if (this.options.disabled) {
event.preventDefault();
event.stopPropagation();
return;
}
var newViewDate = new Date(this.viewDate.getTime());
if (this.options.view === 'date') {
if (newViewDate.getMonth() === 0) {
newViewDate.setMonth(11, 1);
newViewDate.setFullYear(newViewDate.getFullYear() - 1);
}
else {
newViewDate.setMonth(newViewDate.getMonth() - 1, 1);
}
// previous (check first day of month at 00:00:00)
newViewDate.setHours(0);
newViewDate.setMinutes(0);
newViewDate.setSeconds(0);
// #5967 check if month can be navigated to by checking last day in month
var testDate = new Date(newViewDate.getTime()),
minDate = this.options.minDate;
testDate.setMonth(testDate.getMonth()+1);
testDate.setHours(-1);
if (this.options.showMinMaxRange && minDate && minDate > testDate) {
this.setNavigationState(newViewDate);
event.preventDefault();
event.stopPropagation();
return;
}
if (this.options.onMonthChange) {
this.options.onMonthChange.call(this, newViewDate.getMonth() + 1, newViewDate.getFullYear());
}
}
else if (this.options.view === 'month') {
var currentYear = newViewDate.getFullYear(),
newYear = currentYear - 1;
if (this.options.yearNavigator) {
var minYear = parseInt(this.options.yearRange.split(':')[0], 10);
if (newYear < minYear) {
newYear = minYear;
}
}
newViewDate.setFullYear(newYear);
if (this.options.onYearChange) {
this.options.onYearChange.call(this, newViewDate.getMonth(), newViewDate.getFullYear());
}
}
this.updateViewDate(event, newViewDate);
event.preventDefault();
event.stopPropagation();
},
navForward: function (event) {
if (this.options.disabled) {
event.preventDefault();
event.stopPropagation();
return;
}
var newViewDate = new Date(this.viewDate.getTime());
if (this.options.view === 'date') {
if (newViewDate.getMonth() === 11) {
newViewDate.setMonth(0, 1);
newViewDate.setFullYear(newViewDate.getFullYear() + 1);
}
else {
newViewDate.setMonth(newViewDate.getMonth() + 1, 1);
}
// next (check last day of month)
newViewDate.setHours(0);
newViewDate.setMinutes(0);
newViewDate.setSeconds(0);
// #5967 check if month can be navigated to by checking first day next month
var maxDate = this.options.maxDate;
if (this.options.showMinMaxRange && maxDate && maxDate < newViewDate) {
this.setNavigationState(newViewDate);
event.preventDefault();
event.stopPropagation();
return;
}
if (this.options.onMonthChange) {
this.options.onMonthChange.call(this, newViewDate.getMonth() + 1, newViewDate.getFullYear());
}
}
else if (this.options.view === 'month') {
var currentYear = newViewDate.getFullYear(),
newYear = currentYear + 1;
if (this.options.yearNavigator) {
var maxYear = parseInt(this.options.yearRange.split(':')[1], 10);
if (newYear > maxYear) {
newYear = maxYear;
}
}
newViewDate.setFullYear(newYear);
if (this.options.onYearChange) {
this.options.onYearChange.call(this, newViewDate.getMonth(), newViewDate.getFullYear());
}
}
this.updateViewDate(event, newViewDate);
event.preventDefault();
event.stopPropagation();
},
setNavigationState: function(newViewDate) {
if (!newViewDate || !this.options.showMinMaxRange || this.options.view !== 'date') {
return;
}
var navPrev = this.panel.find('.ui-datepicker-header > .ui-datepicker-prev');
var navNext = this.panel.find('.ui-datepicker-header > .ui-datepicker-next');
if (this.options.disabled) {
navPrev.addClass('ui-state-disabled');
navNext.addClass('ui-state-disabled');
return;
}
// previous
if (this.options.minDate) {
let firstDayOfMonth = new Date(newViewDate.getTime());
if (firstDayOfMonth.getMonth() === 0) {
firstDayOfMonth.setMonth(11, 1);
firstDayOfMonth.setFullYear(firstDayOfMonth.getFullYear() - 1);
} else {
firstDayOfMonth.setMonth(firstDayOfMonth.getMonth(), 1);
}
firstDayOfMonth.setHours(0);
firstDayOfMonth.setMinutes(0);
firstDayOfMonth.setSeconds(0);
if (this.options.minDate > firstDayOfMonth) {
navPrev.addClass('ui-state-disabled');
} else {
navPrev.removeClass('ui-state-disabled');
}
}
// next (check last day of month at 11:59:59)
if (this.options.maxDate) {
let lastDayOfMonth = new Date(newViewDate.getTime());
if (lastDayOfMonth.getMonth() === 11) {
lastDayOfMonth.setMonth(0, 1);
lastDayOfMonth.setFullYear(lastDayOfMonth.getFullYear() + 1);
} else {
lastDayOfMonth.setMonth(lastDayOfMonth.getMonth() + 1, 1);
}
lastDayOfMonth.setHours(0);
lastDayOfMonth.setMinutes(0);
lastDayOfMonth.setSeconds(0);
lastDayOfMonth.setSeconds(-1);
if (this.options.maxDate < lastDayOfMonth) {
navNext.addClass('ui-state-disabled');
} else {
navNext.removeClass('ui-state-disabled');
}
}
},
onTimePickerElementMouseDown: function (event, type, direction) {
if (!this.options.disabled && event.button === 0) { // left button
this.repeat(event, null, type, direction);
event.preventDefault();
}
},
onTimePickerElementMouseUp: function (event) {
if (!this.options.disabled) {
this.clearTimePickerTimer();
if (this.options.onSelect) {
this.options.onSelect.call(this, event, this.value);
}
}
},
repeat: function (event, interval, type, direction) {
var i = interval || 500,
$this = this;
this.clearTimePickerTimer();
this.timePickerTimer = setTimeout(function () {
$this.repeat(event, 100, type, direction);
}, i);
switch (type) {
case 0:
if (direction === 1)
this.incrementHour(event);
else
this.decrementHour(event);
break;
case 1:
if (direction === 1)
this.incrementMinute(event);
else
this.decrementMinute(event);
break;
case 2:
if (direction === 1)
this.incrementSecond(event);
else
this.decrementSecond(event);
break;
case 3:
if (direction === 1)
this.incrementMillisecond(event);
else
this.decrementMillisecond(event);
break;
}
},
clearTimePickerTimer: function () {
if (this.timePickerTimer) {
clearTimeout(this.timePickerTimer);
this.timePickerTimer = null;
}
},
showOverlay: function () {
if (!this.options.inline && !this.isPanelVisible() && this.transition) {
var $this = this;
this.transition.show({
onEnter: function() {
if ($this.options.onBeforeShow) {
$this.options.onBeforeShow.call($this);
}
$this.alignPanel();
},
onEntered: function() {
if (!$this.options.touchUI) {
$this.datepickerClick = true;
setTimeout(function () {$this.datepickerClick = false;}, 200);
$this.bindDocumentClickListener();
$this.bindWindowResizeListener();
if (!$this.options.inline) {
$this.bindScrollListener();
}
}
if (($this.options.showTime || $this.options.timeOnly) && $this.options.timeInput) {
$this.panel.find('.ui-hour-picker input').trigger('focus');
}
}
});
}
},
hideOverlay: function () {
if (!this.options.inline && this.isPanelVisible() && this.transition) {
var $this = this;
this.transition.hide({
onExit: function() {
if ($this.options.onBeforeHide) {
$this.options.onBeforeHide.call($this);
}
$this.unbindDocumentClickListener();
$this.unbindWindowResizeListener();
if (!$this.options.inline) {
$this.unbindScrollListener();
}
$this.datepickerClick = false;
},
onExited: function() {
var viewDate = $this.options.viewDate && !$this.value ?
$this.parseValue($this.options.viewDate)
:
(((($this.isMultipleSelection() || $this.isRangeSelection()) && $this.value instanceof Array) ? $this.value[0] : $this.value) || $this.parseValue(new Date()));
if (viewDate instanceof Date) {
$this.updateViewDate(null, viewDate);
}
}
});
}
},
bindDocumentClickListener: function () {
var $this = this;
if (!this.documentClickListener) {
this.documentClickListener = function () {
if (!$this.datepickerClick) {
$this.hideOverlay();
}
$this.datepickerClick = false;
};
$(document).on('click', this.documentClickListener);
}
},
unbindDocumentClickListener: function () {
if (this.documentClickListener) {
$(document).off('click', this.documentClickListener);
this.documentClickListener = null;
}
},
bindResponsiveResizeListener: function() {
var $this = this;
if (this.options.autoDetectDisplay && !this.options.inline) {
var namespace = 'resize.responsive' + this.options.id;
$(window).off(namespace).on(namespace, function() {
$this.updateResponsiveness();
});
}
},
bindWindowResizeListener: function () {
if (this.options.inline) {
return;
}
var $this = this;
$(window).on('resize.' + this.options.id, function() {
if (PrimeFaces.env.mobile) {
$this.alignPanel();
} else {
$this.hideOverlay();
}
});
},
unbindWindowResizeListener: function () {
$(window).off('resize.'+ this.options.id);
},
bindScrollListener: function() {
var $this = this;
this.scrollableParents = PrimeFaces.utils.getScrollableParents(this.element.get(0));
this.scrollableListener = function() {
$this.hideOverlay();
};
for (var i = 0; i < this.scrollableParents.length; i++) {
$(this.scrollableParents[i]).on('scroll', this.scrollableListener);
}
},
unbindScrollListener: function() {
if (this.scrollableParents && this.scrollableListener) {
for (var i = 0; i < this.scrollableParents.length; i++) {
$(this.scrollableParents[i]).off('scroll', this.scrollableListener);
}
this.scrollableListener = null;
}
},
updateResponsiveness: function() {
if (this.options.autoDetectDisplay && this.options.responsiveBreakpoint && !this.options.inline) {
var currentUI = this.options.touchUI;
var newUi = PrimeFaces.env.mobile || PrimeFaces.env.isScreenSizeLessThan(this.options.responsiveBreakpoint);
if (currentUI !== newUi) {
this.options.touchUI = newUi;
this._render();
}
}
},
isPanelVisible: function () {
return !this.options.disabled && this.panel && this.panel.is(":visible");
},
isDate: function (value) {
return value && Object.prototype.toString.call(value) === "[object Date]" && !isNaN(value);
},
alignPanel: function () {
if (!this.isPanelVisible()) {
return;
}
if (this.options.touchUI) {
this.enableModality();
}
else {
if (this.options.appendTo) {
this.panel.css('min-width', this.container.outerWidth() + 'px');
}
if (this.panel.parent().is(this.container)) {
this.panel.css({
left: '0px',
top: String(this.container.innerHeight()),
'transform-origin': 'center top'
});
}
else {
this.panel.css({ left: '', top: '', 'transform-origin': 'center top' }).position({
my: 'left top'
,at: 'left bottom'
,of: this.container
,collision: 'flipfit'
,using: function(pos, directions) {
$(this).css('transform-origin', 'center ' + directions.vertical).css(pos);
}
});
}
}
},
enableModality: function () {
if (!this.mask) {
this.mask = $('');
this.mask.css('z-index', String(parseInt(this.panel.css('z-index'), 10) - 1));
var $this = this;
this.mask.on('click.datePicker-mask', function () {
$this.disableModality();
});
$(document.body).append(this.mask).addClass('ui-overflow-hidden');
}
},
disableModality: function () {
if (this.mask) {
this.mask.off('click.datePicker-mask');
this.mask.remove();
this.mask = null;
var bodyChildren = $(document.body).children('.ui-datepicker-mask-scrollblocker');
if (!bodyChildren.length) {
$(document.body).removeClass('ui-overflow-hidden');
}
this.hideOverlay();
}
},
onDateSelect: function (event, dateMeta) {
if (this.options.disabled || !dateMeta.selectable) {
if(event) {
event.preventDefault();
}
return;
}
var $this = this;
if (this.isMultipleSelection()) {
if (this.isSelected(dateMeta)) {
var value = this.value.filter(function (date, i) {
return !$this.isDateEquals(date, dateMeta);
});
this.updateModel(event, value);
}
else if (!this.options.maxDateCount || !this.value || this.options.maxDateCount > this.value.length) {
this.selectDate(event, dateMeta);
}
}
else {
this.selectDate(event, dateMeta);
}
if (!this.options.inline && this.isSingleSelection() && (!this.options.showTime || this.options.hideOnDateTimeSelect)) {
setTimeout(function () {
$this.hideOverlay();
}, 100);
if (this.mask) {
this.disableModality();
}
}
if(event) {
event.preventDefault();
}
},
selectDate: function (event, dateMeta) {
var date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);
if (this.options.showTime) {
var time = this.isDate(this.value) ? this.value : new Date();
date.setHours(time.getHours());
date.setMinutes(this.stepMinute(time.getMinutes()));
date.setSeconds(time.getSeconds());
date.setMilliseconds(time.getMilliseconds());
}
if (this.options.minDate && this.options.minDate > date) {
date = this.options.minDate;
}
if (this.options.maxDate && this.options.maxDate < date) {
date = this.options.maxDate;
}
if (this.isSingleSelection()) {
this.updateModel(event, date);
}
else if (this.isMultipleSelection()) {
this.updateModel(event, this.value ? this.value.concat(date) : [date]);
}
else if (this.isRangeSelection()) {
if (this.value && this.value.length) {
var startDate = this.value[0],
endDate = this.value[1];
if (!endDate && date.getTime() >= startDate.getTime()) {
endDate = date;
}
else {
startDate = date;
endDate = null;
}
this.updateModel(event, [startDate, endDate]);
}
else {
this.updateModel(event, [date, null]);
}
}
if (this.options.onSelect) {
this.options.onSelect.call(this, event, date);
}
},
incrementHour: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentHour = currentTime.getHours(),
newHour = currentHour + this.options.stepHour;
newHour = (newHour >= 24) ? (newHour - 24) : newHour;
if (this.validateTime(newHour, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime, "INCREMENT")) {
this.updateTime(event, newHour, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds());
}
event.preventDefault();
},
decrementHour: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentHour = currentTime.getHours(),
newHour = currentHour - this.options.stepHour;
newHour = (newHour < 0) ? (newHour + 24) : newHour;
if (this.validateTime(newHour, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime, "DECREMENT")) {
this.updateTime(event, newHour, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds());
}
event.preventDefault();
},
incrementMinute: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentMinute = currentTime.getMinutes(),
newMinute = this.stepMinute(currentMinute, this.options.stepMinute);
newMinute = (newMinute > 59) ? (newMinute - 60) : newMinute;
if (this.validateTime(currentTime.getHours(), newMinute, currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime, "INCREMENT")) {
this.updateTime(event, currentTime.getHours(), newMinute, currentTime.getSeconds(), currentTime.getMilliseconds());
}
event.preventDefault();
},
decrementMinute: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentMinute = currentTime.getMinutes(),
newMinute = this.stepMinute(currentMinute, -this.options.stepMinute);
newMinute = (newMinute < 0) ? (newMinute + 60) : newMinute;
if (this.validateTime(currentTime.getHours(), newMinute, currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime, "DECREMENT")) {
this.updateTime(event, currentTime.getHours(), newMinute, currentTime.getSeconds(), currentTime.getMilliseconds());
}
event.preventDefault();
},
stepMinute: function(currentMinute, step) {
if (this.options.stepMinute <= 1) {
if (!step) {
return currentMinute;
} else {
return currentMinute + step;
}
}
if (!step) {
step = this.options.stepMinute;
if (currentMinute % step === 0) {
return currentMinute;
}
}
var newMinute = currentMinute + step;
newMinute = Math.floor(newMinute / step) * step;
return newMinute;
},
incrementSecond: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentSecond = currentTime.getSeconds(),
newSecond = currentSecond + this.options.stepSecond;
newSecond = (newSecond > 59) ? (newSecond - 60) : newSecond;
if (this.validateTime(currentTime.getHours(), currentTime.getMinutes(), newSecond, currentTime.getMilliseconds(), currentTime, "INCREMENT")) {
this.updateTime(event, currentTime.getHours(), currentTime.getMinutes(), newSecond, currentTime.getMilliseconds());
}
event.preventDefault();
},
decrementSecond: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentSecond = currentTime.getSeconds(),
newSecond = currentSecond - this.options.stepSecond;
newSecond = (newSecond < 0) ? (newSecond + 60) : newSecond;
if (this.validateTime(currentTime.getHours(), currentTime.getMinutes(), newSecond, currentTime.getMilliseconds(), currentTime, "DECREMENT")) {
this.updateTime(event, currentTime.getHours(), currentTime.getMinutes(), newSecond, currentTime.getMilliseconds());
}
event.preventDefault();
},
incrementMillisecond: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentMillisecond = currentTime.getMilliseconds(),
newMillisecond = currentMillisecond + this.options.stepMillisecond;
newMillisecond = (newMillisecond > 999) ? (newMillisecond - 1000) : newMillisecond;
if (this.validateTime(currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds(), newMillisecond, currentTime, "INCREMENT")) {
this.updateTime(event, currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds(), newMillisecond);
}
event.preventDefault();
},
decrementMillisecond: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentMillisecond = currentTime.getMilliseconds(),
newMillisecond = currentMillisecond - this.options.stepMillisecond;
newMillisecond = (newMillisecond < 0) ? (newMillisecond + 1000) : newMillisecond;
if (this.validateTime(currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds(), newMillisecond, currentTime, "DECREMENT")) {
this.updateTime(event, currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds(), newMillisecond);
}
event.preventDefault();
},
toggleAmPm: function (event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
currentHour = currentTime.getHours(),
newHour = (currentHour >= 12) ? currentHour - 12 : currentHour + 12;
this.updateTime(event, newHour, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds());
event.preventDefault();
},
handleHoursInput: function(input, event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
value = input.value,
valid = false,
newHours;
var reg = new RegExp('^([0-9]){1,2}$');
if (reg.test(value)) {
newHours = parseInt(value);
if (this.options.hourFormat === '12') {
if (newHours >= 1 && newHours <= 12) {
valid = this.validateTime(newHours, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime);
}
} else {
if (newHours >= 0 && newHours <= 23) {
valid = this.validateTime(newHours, currentTime.getMinutes(), currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime);
}
}
}
if (!valid) {
event.preventDefault();
input.value = this.oldHours;
return;
}
var newDateTime = this.isDate(this.value) ? new Date(this.value) : new Date();
newDateTime.setHours(newHours);
this.updateTimeAfterInput(event, newDateTime);
},
handleMinutesInput: function(input, event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
value = input.value,
valid = false,
newMinutes;
var reg = new RegExp('^([0-9]){1,2}$');
if (reg.test(value)) {
newMinutes = parseInt(value);
if (newMinutes >= 0 && newMinutes <= 59) {
valid = this.validateTime(currentTime.getHours(), newMinutes, currentTime.getSeconds(), currentTime.getMilliseconds(), currentTime);
}
}
if (!valid) {
event.preventDefault();
input.value = this.oldMinutes;
return;
}
var newDateTime = this.isDate(this.value) ? new Date(this.value) : new Date();
newDateTime.setMinutes(newMinutes);
this.updateTimeAfterInput(event, newDateTime);
},
handleSecondsInput: function(input, event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
value = input.value,
valid = false,
newSeconds;
var reg = new RegExp('^([0-9]){1,2}$');
if (reg.test(value)) {
newSeconds = parseInt(value);
if (newSeconds >= 0 && newSeconds <= 59) {
valid = this.validateTime(currentTime.getHours(), currentTime.getMinutes(), newSeconds, currentTime.getMilliseconds(), currentTime);
}
}
if (!valid) {
event.preventDefault();
input.value = this.oldSeconds;
return;
}
var newDateTime = this.isDate(this.value) ? new Date(this.value) : new Date();
newDateTime.setSeconds(newSeconds);
this.updateTimeAfterInput(event, newDateTime);
},
handleMillisecondsInput: function(input, event) {
var currentTime = this.isDate(this.value) ? this.value : this.viewDate,
value = input.value,
valid = false,
newMilliseconds;
var reg = new RegExp('^([0-9]){1,3}$');
if (reg.test(value)) {
newMilliseconds = parseInt(value);
if (newMilliseconds >= 0 && newMilliseconds <= 999) {
valid = this.validateTime(currentTime.getHours(), currentTime.getMinutes(), currentTime.getSeconds(), newMilliseconds, currentTime);
}
}
if (!valid) {
event.preventDefault();
input.value = this.oldMilliseconds;
return;
}
var newDateTime = this.isDate(this.value) ? new Date(this.value) : new Date();
newDateTime.setMilliseconds(newMilliseconds);
this.updateTimeAfterInput(event, newDateTime);
},
validateTime: function(hour, minute, second, millisecond, value, direction) {
var valid = true;
var dateNew = new Date(value.getFullYear(), value.getMonth(), value.getDate(), hour, minute, second, millisecond);
if (this.options.minDate && value) {
if (this.options.minDate > dateNew) {
if (direction === "INCREMENT" && this.options.minDate > value) {
; //the new time is still outside the allowed range, but we come nearer to it
}
else {
valid = false;
}
}
}
if (this.options.maxDate && value) {
if (this.options.maxDate < dateNew) {
if (direction === "DECREMENT" && this.options.maxDate < value) {
; //the new time is still outside the allowed range, but we come nearer to it
}
else {
valid = false;
}
}
}
return valid;
},
updateTime: function (event, hour, minute, second, millisecond) {
var newDateTime = this.isDate(this.value) ? new Date(this.value) : new Date();
newDateTime.setHours(hour);
newDateTime.setMinutes(minute);
newDateTime.setSeconds(second);
newDateTime.setMilliseconds(millisecond);
this.updateModel(event, newDateTime);
if (this.options.onSelect) {
if (this.timePickerTimer === 'undefined' || this.timePickerTimer === null) {
this.options.onSelect.call(this, event, newDateTime);
}
}
},
updateTimeAfterInput: function (event, newDateTime) {
this.value = newDateTime;
this.inputfield.val(this.getValueToRender());
if (this.options.onSelect) {
this.options.onSelect.call(this, event, newDateTime);
}
},
onTodayButtonClick: function (event) {
var today = new Date(),
dateMeta = { day: today.getDate(), month: today.getMonth(), year: today.getFullYear(), today: true, selectable: true };
this.updateViewDate(event, today);
if (this.options.showTime) {
this.updateTime(event, today, today.getMinutes(), today.getSeconds(), today.getMilliseconds());
}
this.onDateSelect(event, dateMeta);
if (this.options.onTodayButtonClick) {
this.options.onTodayButtonClick.call(this, event);
}
},
onClearButtonClick: function (event) {
this.updateViewDate(event, new Date());
this.updateModel(event, null);
if (this.options.onClearButtonClick) {
this.options.onClearButtonClick.call(this, event);
}
this.hideOverlay();
},
escapeHTML: function(value) {
var entityMap = {
'&': '&',
'<': '<',
'>': '>',
'"': '"',
"'": ''',
'/': '/',
'`': '`',
'=': '='
};
return String(value).replace(/[&<>"'`=\/]/g, function (s) {
return entityMap[s];
});
},
updateYearNavigator: function() {
if (this.hasCustomYearRange) {
return;
}
if (this.options.yearNavigator) {
var viewYear = this.viewDate.getFullYear();
this.options.yearRange = (viewYear - 10) + ':' + (viewYear + 10);
}
},
updateViewDate: function (event, value) {
if (this.options.onViewDateChange) {
this.options.onViewDateChange.call(this, event, value);
}
this.viewDate = value;
if ((this.options.autoMonthFormat || !this.inputfield.val() || this.options.showMinMaxRange) && this.options.monthNavigator && this.options.view !== 'month') {
var viewMonth = this.viewDate.getMonth();
viewMonth = (this.isInMaxYear() && Math.min(this.options.maxDate.getMonth(), viewMonth)) || (this.isInMinYear() && Math.max(this.options.minDate.getMonth(), viewMonth)) || viewMonth;
this.viewDate.setMonth(viewMonth);
}
this.panel.get(0).innerHTML = this.renderPanelElements();
this._setInitOptionValues();
},
updateModel: function (event, value, updateInput) {
this.value = (value === '' ? null : value);
if (updateInput != false) {
this.inputfield.val(this.getValueToRender());
}
this.panel.get(0).innerHTML = this.renderPanelElements();
this._setInitOptionValues();
}
});
}));