UNPKG

fundamental-ngx

Version:

SAP Fiori Fundamentals, implemented in Angular

1,394 lines (1,393 loc) 187 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, EventEmitter, Input, Output, HostListener, ElementRef, forwardRef, ChangeDetectorRef, HostBinding, ViewEncapsulation } from '@angular/core'; import { NG_VALUE_ACCESSOR } from '@angular/forms'; import { Subject } from 'rxjs'; import { CalendarI18n } from './i18n/calendar-i18n'; import { CalendarI18nLabels } from './i18n/calendar-i18n-labels'; import { DateFormatParser } from './format/date-parser'; /** * @record */ export function CalendarDay() { } if (false) { /** @type {?} */ CalendarDay.prototype.date; /** @type {?|undefined} */ CalendarDay.prototype.day; /** @type {?|undefined} */ CalendarDay.prototype.weekDay; /** @type {?|undefined} */ CalendarDay.prototype.monthStatus; /** @type {?|undefined} */ CalendarDay.prototype.disabled; /** @type {?|undefined} */ CalendarDay.prototype.blocked; /** @type {?|undefined} */ CalendarDay.prototype.selected; /** @type {?|undefined} */ CalendarDay.prototype.selectedFirst; /** @type {?|undefined} */ CalendarDay.prototype.selectedRange; /** @type {?|undefined} */ CalendarDay.prototype.selectedLast; /** @type {?|undefined} */ CalendarDay.prototype.today; /** @type {?|undefined} */ CalendarDay.prototype.isTabIndexed; /** @type {?|undefined} */ CalendarDay.prototype.ariaLabel; } /** * @record */ export function EmittedDate() { } if (false) { /** @type {?|undefined} */ EmittedDate.prototype.selectedDay; /** @type {?|undefined} */ EmittedDate.prototype.selectedFirstDay; /** @type {?|undefined} */ EmittedDate.prototype.selectedLastDay; } /** @type {?} */ var calendarUniqueId = 0; /** * Calendar component used for selecting dates, typically used by the DatePicker and DateTimePicker components. * Supports the Angular forms module, enabling form validity, ngModel, etc. */ var CalendarComponent = /** @class */ (function () { function CalendarComponent(eRef, cd, calendarI18nLabels, calendarI18n, dateAdapter) { this.eRef = eRef; this.cd = cd; this.calendarI18nLabels = calendarI18nLabels; this.calendarI18n = calendarI18n; this.dateAdapter = dateAdapter; /** * @hidden Used to check if this is the calendar being initialized. Internal use. */ this.init = false; /** * @hidden Applies the fd-calendar class to this component. Internal use. */ this.fdCalendarClass = true; /** * Id of the calendar. If none is provided, one will be generated. */ this.id = 'fd-calendar-' + calendarUniqueId++; /** * The type of calendar, 'single' for single date selection or 'range' for a range of dates. */ this.calType = 'single'; /** * The day of the week the calendar should start on. 0 represents Sunday, 1 is Monday, 2 is Tuesday, and so on. */ this.startingDayOfWeek = 0; /** * Fired when the date input value is invalid. */ this.isInvalidDateInput = new EventEmitter(); /** * Whether wants to allow escape focus, otherwise it resets on beginning. */ this.allowFocusEscape = false; /** * @hidden Whether the date is invalid. Internal use. */ this.invalidDate = false; /** * @hidden Whether to show the month selection grid on the calendar. Internal use. */ this.showCalendarMonths = false; /** * @hidden Whether to show the year selection grid on the calendar. Internal use. */ this.showCalendarYears = false; /** * @hidden Whether to show the date selection grid on the calendar. Internal use. */ this.showCalendarDates = true; /** * @hidden The typical number of days in each month. Internal use. */ this.daysPerMonth = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; /** * @hidden The displayed grid of calendar days. Internal use. */ this.calendarGrid = []; /** * @hidden The years to display in the year selection grid. Internal use. */ this.calendarYearsList = []; /** * @hidden Today's date. Internal use. */ this.today = new Date(); /** * @hidden Today's month. Internal use. */ this.todayMonth = this.today.getMonth(); /** * @hidden Today's year. Internal use. */ this.todayYear = this.today.getFullYear(); /** * @hidden Date used to navigate the calendar. Not to be confused with selectedDay which is the ngModel. Internal use. */ this.date = new Date(); /** * @hidden Month used to navigate the calendar.Internal use. */ this.month = this.date.getMonth(); /** * @hidden Year used to navigate the calendar. Internal use. */ this.year = this.date.getFullYear(); /** * @hidden Day of month used to navigate the calendar. Internal use. */ this.day = this.date.getDate(); /** * @hidden The first year to be displayed in the list of selectable years. Internal use. */ this.firstYearCalendarList = this.year; /** * @hidden The first year to be displayed in the list of selectable years. Internal use. */ this.selectCounter = 0; /** * The currently selected CalendarDay model. */ this.selectedDay = { date: null }; /** * Fired when a new date is selected. */ this.selectedDayChange = new EventEmitter(); /** * The currently selected first CalendarDay in a range type calendar. */ this.selectedRangeFirst = { date: null }; /** * Fired when the user selects a new first date in a range of dates is selected. */ this.selectedRangeFirstChange = new EventEmitter(); /** * The currently selected last CalendarDay in a range type calendar. */ this.selectedRangeLast = { date: null }; /** * Fired when the user selects a new last date in a range of dates is selected. */ this.selectedRangeLastChange = new EventEmitter(); /** * @hidden The date that gets emitted to the datePicker when the select day changes on the calendar. Internal use. */ this.emittedDate = { selectedDay: this.selectedDay, selectedFirstDay: this.selectedRangeFirst, selectedLastDay: this.selectedRangeLast }; /** * Fired when the calendar is closed. */ this.closeCalendar = new EventEmitter(); /** * Function used to disable certain dates in the calendar. * @param d Date */ this.disableFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * Function used to disable certain dates in the calendar for the range start selection. * @param d Date */ this.disableRangeStartFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * Function used to disable certain dates in the calendar for the range end selection. * @param d Date */ this.disableRangeEndFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * Function used to block certain dates in the calendar for the range start selection. * @param d Date */ this.blockRangeStartFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * Function used to block certain dates in the calendar for the range end selection. * @param d Date */ this.blockRangeEndFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * Function used to block certain dates in the calendar. * @param d Date */ this.blockFunction = (/** * @param {?} d * @return {?} */ function (d) { return false; }); /** * @hidden */ this.onChange = (/** * @return {?} */ function () { }); /** * @hidden */ this.onTouched = (/** * @return {?} */ function () { }); /** * @hidden */ this.determineDaysInMonth = (/** * @param {?} month * @param {?} year * @return {?} */ function (month, year) { if (month === 1) { if ((year % 100 !== 0 && year % 4 === 0) || year % 400 === 0) { return 29; } else { return this.daysPerMonth[month]; } } else { return this.daysPerMonth[month]; } }); } /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.setWeekDaysOrder = /** * @hidden * @return {?} */ function () { this.weekDays = this.calendarI18n.getAllShortWeekdays().map((/** * @param {?} item * @return {?} */ function (item) { return item[0]; })); if (this.startingDayOfWeek <= 6 && this.startingDayOfWeek >= 0) { for (var i = this.startingDayOfWeek; i > 0; i--) { this.weekDays.push(this.weekDays.shift()); } } }; /** @hidden */ /** * @hidden * @param {?} calendarMonth * @return {?} */ CalendarComponent.prototype.getPreviousMonthDays = /** * @hidden * @param {?} calendarMonth * @return {?} */ function (calendarMonth) { // Previous month days /** @type {?} */ var prevMonthLastDate; this.setWeekDaysOrder(); prevMonthLastDate = new Date(this.date.getFullYear(), this.date.getMonth(), 0); /** @type {?} */ var prevMonth = prevMonthLastDate.getMonth(); /** @type {?} */ var prevMonthYear = prevMonthLastDate.getFullYear(); /** @type {?} */ var prevMonthLastDay = prevMonthLastDate.getDate(); /** @type {?} */ var prevMonthLastWeekDay = prevMonthLastDate.getDay() - this.startingDayOfWeek; if (prevMonthLastWeekDay < 6) { while (prevMonthLastWeekDay >= 0) { /** @type {?} */ var prevMonthDay = prevMonthLastDay - prevMonthLastWeekDay; /** @type {?} */ var calDate = new Date(prevMonthYear, prevMonth, prevMonthDay); /** @type {?} */ var previousMonthCalendarDay = { date: calDate, day: calDate.getDate(), weekDay: calDate.getDay(), monthStatus: 'previous', disabled: this.disableFunction(calDate), blocked: this.blockFunction(calDate), selected: (this.selectedDay.date && calDate.toDateString() === this.selectedDay.date.toDateString()) || (this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString()) || (this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString()), selectedFirst: this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString(), selectedLast: this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString(), selectedRange: this.selectedRangeFirst.date && calDate.getTime() > this.selectedRangeFirst.date.getTime() && this.selectedRangeLast.date && calDate.getTime() < this.selectedRangeLast.date.getTime(), ariaLabel: this.calendarI18n.getDayAriaLabel(calDate) }; if (this.selectCounter === 0) { if (this.disableRangeStartFunction && !previousMonthCalendarDay.disabled) { previousMonthCalendarDay.disabled = this.disableRangeStartFunction(calDate); } if (this.blockRangeStartFunction && !previousMonthCalendarDay.blocked) { previousMonthCalendarDay.blocked = this.blockRangeStartFunction(calDate); } } else if (this.selectCounter === 1) { if (this.disableRangeEndFunction && !previousMonthCalendarDay.disabled) { previousMonthCalendarDay.disabled = this.disableRangeEndFunction(calDate); } if (this.blockRangeEndFunction && !previousMonthCalendarDay.blocked) { previousMonthCalendarDay.blocked = this.blockRangeEndFunction(calDate); } } calendarMonth.push(previousMonthCalendarDay); prevMonthLastWeekDay--; } } return calendarMonth; }; /** @hidden */ /** * @hidden * @param {?} calendarMonth * @return {?} */ CalendarComponent.prototype.getCurrentMonthDays = /** * @hidden * @param {?} calendarMonth * @return {?} */ function (calendarMonth) { /** @type {?} */ var numOfDaysInCurrentMonth = this.determineDaysInMonth(this.month, this.year); // Current month days /** @type {?} */ var foundSelected = false; for (var d = 1; d <= numOfDaysInCurrentMonth; d++) { /** @type {?} */ var calDate = new Date(this.date.getFullYear(), this.date.getMonth(), d); /** @type {?} */ var currMonthCalendarDay = { date: calDate, day: calDate.getDate(), weekDay: calDate.getDay(), monthStatus: 'current', disabled: this.disableFunction(calDate), blocked: this.blockFunction(calDate), selected: (this.selectedDay.date && calDate.toDateString() === this.selectedDay.date.toDateString()) || (this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString()) || (this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString()), selectedFirst: this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString(), selectedLast: this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString(), selectedRange: this.selectedRangeFirst.date && calDate.getTime() > this.selectedRangeFirst.date.getTime() && this.selectedRangeLast.date && calDate.getTime() < this.selectedRangeLast.date.getTime(), today: calDate.toDateString() === this.today.toDateString(), isTabIndexed: false, ariaLabel: this.calendarI18n.getDayAriaLabel(calDate) }; if (this.selectCounter === 0 || this.selectCounter === 2) { if (this.disableRangeStartFunction && !currMonthCalendarDay.disabled) { currMonthCalendarDay.disabled = this.disableRangeStartFunction(calDate); } if (this.blockRangeStartFunction && !currMonthCalendarDay.blocked) { currMonthCalendarDay.blocked = this.blockRangeStartFunction(calDate); } } else if (this.selectCounter === 1) { if (this.disableRangeEndFunction && !currMonthCalendarDay.disabled) { currMonthCalendarDay.disabled = this.disableRangeEndFunction(calDate); } if (this.blockRangeEndFunction && !currMonthCalendarDay.blocked) { currMonthCalendarDay.blocked = this.blockRangeEndFunction(calDate); } } // if a day is selected, it should be tab indexed if (currMonthCalendarDay.selected) { foundSelected = true; currMonthCalendarDay.isTabIndexed = true; } calendarMonth.push(currMonthCalendarDay); } if (!foundSelected) { /** @type {?} */ var foundToday = false; for (var d = 0; d < numOfDaysInCurrentMonth; d++) { // if no day is selected, tab index today if (calendarMonth[d] && calendarMonth[d].today) { foundToday = true; calendarMonth[d].isTabIndexed = true; } } // if today isn't present on the calendarGrid, tab index the first day if (!foundToday) { calendarMonth[0].isTabIndexed = true; } } return calendarMonth; }; /** @hidden */ /** * @hidden * @param {?} calendarMonth * @return {?} */ CalendarComponent.prototype.getNextMonthDays = /** * @hidden * @param {?} calendarMonth * @return {?} */ function (calendarMonth) { // Next month days /** @type {?} */ var nextMonthDisplayedDays = 0; // The calendar grid can have either 5 (35 days) or 6 (42 days) weeks // depending on the week day of the first day of the current month // and the number of days in the current month if (calendarMonth.length > 35) { nextMonthDisplayedDays = 42 - calendarMonth.length; } else { nextMonthDisplayedDays = 35 - calendarMonth.length; } for (var nextD = 1; nextD <= nextMonthDisplayedDays; nextD++) { /** @type {?} */ var nextMonthFirstDate = void 0; if (this.date.getMonth() === 11) { nextMonthFirstDate = new Date(this.date.getFullYear() + 1, 0, 1); } else { nextMonthFirstDate = new Date(this.date.getFullYear(), this.date.getMonth() + 1, 1); } /** @type {?} */ var nextMonth = nextMonthFirstDate.getMonth(); /** @type {?} */ var nextMonthYear = nextMonthFirstDate.getFullYear(); /** @type {?} */ var calDate = new Date(nextMonthYear, nextMonth, nextD); /** @type {?} */ var nextMonthCalendarDay = { date: calDate, day: calDate.getDate(), weekDay: calDate.getDay(), monthStatus: 'next', disabled: this.disableFunction(calDate), blocked: this.blockFunction(calDate), selected: (this.selectedDay.date && calDate.toDateString() === this.selectedDay.date.toDateString()) || (this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString()) || (this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString()), selectedFirst: this.selectedRangeFirst.date && calDate.toDateString() === this.selectedRangeFirst.date.toDateString(), selectedLast: this.selectedRangeLast.date && calDate.toDateString() === this.selectedRangeLast.date.toDateString(), selectedRange: this.selectedRangeFirst.date && calDate.getTime() > this.selectedRangeFirst.date.getTime() && this.selectedRangeLast.date && calDate.getTime() < this.selectedRangeLast.date.getTime(), ariaLabel: this.calendarI18n.getDayAriaLabel(calDate) }; if (this.selectCounter === 0) { if (this.disableRangeStartFunction && !nextMonthCalendarDay.disabled) { nextMonthCalendarDay.disabled = this.disableRangeStartFunction(calDate); } if (this.blockRangeStartFunction && !nextMonthCalendarDay.blocked) { nextMonthCalendarDay.blocked = this.blockRangeStartFunction(calDate); } } else if (this.selectCounter === 1) { if (this.disableRangeEndFunction && !nextMonthCalendarDay.disabled) { nextMonthCalendarDay.disabled = this.disableRangeEndFunction(calDate); } if (this.blockRangeEndFunction && !nextMonthCalendarDay.blocked) { nextMonthCalendarDay.blocked = this.blockRangeEndFunction(calDate); } } calendarMonth.push(nextMonthCalendarDay); } return calendarMonth; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.populateCalendar = /** * @hidden * @return {?} */ function () { /** @type {?} */ var calendarMonth = []; calendarMonth = this.getPreviousMonthDays(calendarMonth); calendarMonth = this.getCurrentMonthDays(calendarMonth); calendarMonth = this.getNextMonthDays(calendarMonth); return calendarMonth; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.constructCalendar = /** * @hidden * @return {?} */ function () { /** @type {?} */ var calendarDays = this.populateCalendar(); /** @type {?} */ var calendarGrid = []; while (calendarDays.length > 0) { calendarGrid.push(calendarDays.splice(0, 7)); } this.calendarGrid = calendarGrid; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.refreshSelected = /** * @hidden * @return {?} */ function () { var _this = this; this.calendarGrid.forEach((/** * @param {?} grid * @return {?} */ function (grid) { grid.forEach((/** * @param {?} day * @return {?} */ function (day) { day.selected = (_this.selectedDay.date && day.date && day.date.toDateString() === _this.selectedDay.date.toDateString()) || (_this.selectedRangeFirst.date && day.date.toDateString() === _this.selectedRangeFirst.date.toDateString()) || (_this.selectedRangeLast.date && day.date.toDateString() === _this.selectedRangeLast.date.toDateString()); day.selectedFirst = _this.selectedRangeFirst.date && day.date && day.date.toDateString() === _this.selectedRangeFirst.date.toDateString(); day.selectedLast = _this.selectedRangeLast.date && day.date && day.date.toDateString() === _this.selectedRangeLast.date.toDateString(); day.selectedRange = _this.selectedRangeFirst.date && day.date.getTime() > _this.selectedRangeFirst.date.getTime() && _this.selectedRangeLast.date && day.date.getTime() < _this.selectedRangeLast.date.getTime(); })); })); }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.updateDatePickerInputEmitter = /** * @hidden * @return {?} */ function () { if (this.calType === 'single') { this.emittedDate.selectedDay = this.selectedDay; } else { this.emittedDate.selectedFirstDay = this.selectedRangeFirst; this.emittedDate.selectedLastDay = this.selectedRangeLast; } if (this.dateFromDatePicker) { this.dateFromDatePicker.next(this.emittedDate); } }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.constructCalendarYearsList = /** * @hidden * @return {?} */ function () { this.calendarYearsList = []; for (var y = 0; y < 12; y++) { this.calendarYearsList.push(this.firstYearCalendarList + y); } }; /** @hidden */ /** * @hidden * @param {?} year * @param {?} i * @return {?} */ CalendarComponent.prototype.getYearTabIndex = /** * @hidden * @param {?} year * @param {?} i * @return {?} */ function (year, i) { var _this = this; /** @type {?} */ var retVal = -1; // tab index currently selected year if (year === this.year) { retVal = 0; } else { // if no year on the calendarYearsList is selected, tab index the first /** @type {?} */ var foundYear_1 = false; this.calendarYearsList.forEach((/** * @param {?} yearFromList * @return {?} */ function (yearFromList) { if (_this.year === yearFromList) { foundYear_1 = true; } })); if (!foundYear_1) { if (i === 0) { retVal = 0; } } } return retVal; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.goToPreviousMonth = /** * @hidden * @return {?} */ function () { this.setCurrentMonth(this.date.getMonth() - 1); this.selectedMonth = this.month; this.constructCalendar(); }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.goToNextMonth = /** * @hidden * @return {?} */ function () { this.setCurrentMonth(this.date.getMonth() + 1); this.selectedMonth = this.month; this.constructCalendar(); }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.loadNextYearsList = /** * @hidden * @return {?} */ function () { this.calendarYearsList = []; this.firstYearCalendarList += 12; this.constructCalendarYearsList(); }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.loadPrevYearsList = /** * @hidden * @return {?} */ function () { this.calendarYearsList = []; this.firstYearCalendarList -= 12; this.constructCalendarYearsList(); }; /** * Function for selecting a date on the calendar. Typically called when a date is clicked, but can also be called programmatically. * @param day CalendarDay object to be selected. * @param formEvent If this function should emit an ngModelChange. * @param event Event passed with this function call, typically the mouse click when selecting from the calendar grid. * @param closeCalendar If the calendar should be closed when a date is selected, used with DatePicker and DateTimePicker. */ /** * Function for selecting a date on the calendar. Typically called when a date is clicked, but can also be called programmatically. * @param {?} day CalendarDay object to be selected. * @param {?=} formEvent If this function should emit an ngModelChange. * @param {?=} event Event passed with this function call, typically the mouse click when selecting from the calendar grid. * @param {?=} closeCalendar If the calendar should be closed when a date is selected, used with DatePicker and DateTimePicker. * @return {?} */ CalendarComponent.prototype.selectDate = /** * Function for selecting a date on the calendar. Typically called when a date is clicked, but can also be called programmatically. * @param {?} day CalendarDay object to be selected. * @param {?=} formEvent If this function should emit an ngModelChange. * @param {?=} event Event passed with this function call, typically the mouse click when selecting from the calendar grid. * @param {?=} closeCalendar If the calendar should be closed when a date is selected, used with DatePicker and DateTimePicker. * @return {?} */ function (day, formEvent, event, closeCalendar) { if (formEvent === void 0) { formEvent = true; } if (event) { event.stopPropagation(); } if (!day.blocked && !day.disabled) { if (this.calType === 'single') { this.selectedDay = day; this.selectedDayChange.emit(this.selectedDay); this.refreshSelected(); if (this.init) { this.updateDatePickerInputEmitter(); } if (formEvent) { this.onChange({ date: day.date }); } if (closeCalendar) { this.closeCalendar.emit(); } } else { if (this.selectCounter === 2) { this.selectCounter = 0; } if (this.selectCounter === 1 && day.date !== this.selectedRangeLast.date) { this.selectedRangeLast = day; this.selectedRangeLastChange.emit(this.selectedRangeLast); this.selectCounter++; this.refreshSelected(); this.constructCalendar(); if (this.init) { this.updateDatePickerInputEmitter(); } if (formEvent) { this.onChange({ date: this.selectedRangeFirst.date, rangeEnd: day.date }); } } if (this.selectCounter === 0) { this.selectedRangeLast = day; this.selectedRangeLastChange.emit(this.selectedRangeLast); this.selectedRangeFirst = day; this.selectedRangeFirstChange.emit(this.selectedRangeFirst); this.selectCounter++; this.refreshSelected(); this.constructCalendar(); if (this.init) { this.updateDatePickerInputEmitter(); } if (formEvent) { this.onChange({ date: day.date, rangeEnd: day.date }); } } if (this.selectedRangeFirst.date > this.selectedRangeLast.date) { /** @type {?} */ var tempSelectedRangeFirst = this.selectedRangeFirst; this.selectedRangeFirst = this.selectedRangeLast; this.selectedRangeFirstChange.emit(this.selectedRangeFirst); this.selectedRangeLast = tempSelectedRangeFirst; this.selectedRangeLastChange.emit(this.selectedRangeLast); this.refreshSelected(); this.constructCalendar(); if (this.init) { this.updateDatePickerInputEmitter(); } if (formEvent) { this.onChange({ date: this.selectedRangeFirst.date, rangeEnd: this.selectedRangeLast.date }); } } } } this.isInvalidDateInput.emit(false); }; /** @hidden */ /** * @hidden * @param {?} month * @return {?} */ CalendarComponent.prototype.setCurrentMonth = /** * @hidden * @param {?} month * @return {?} */ function (month) { // get the current date of the month /** @type {?} */ var currentDate = this.date.getDate(); // get the number of days in the new month /** @type {?} */ var daysInNewMonth = new Date(this.date.getFullYear(), month + 1, 0).getDate(); /* if the currentDate > daysInNewMonth, set the date to the first for now, to prevent skipping a month in the event that the currentDate is 31 and the next month has 30 days */ if (currentDate > daysInNewMonth) { this.date.setDate(1); } // set the month this.date.setMonth(month); // if currentDate > daysInNewMonth, restore the date to whichever number is lower, today's date or the number of days in this month if (currentDate > daysInNewMonth) { this.date.setDate(Math.min(currentDate, daysInNewMonth)); } this.month = this.date.getMonth(); this.monthName = this.monthsFullName[this.date.getMonth()]; this.year = this.date.getFullYear(); }; /** @hidden */ /** * @hidden * @param {?} selectedMonth * @param {?=} event * @return {?} */ CalendarComponent.prototype.selectMonth = /** * @hidden * @param {?} selectedMonth * @param {?=} event * @return {?} */ function (selectedMonth, event) { if (event) { event.stopPropagation(); } this.selectedMonth = selectedMonth; this.setCurrentMonth(selectedMonth); this.constructCalendar(); this.openDaySelection(); }; /** @hidden */ /** * @hidden * @param {?} year * @return {?} */ CalendarComponent.prototype.setCurrentYear = /** * @hidden * @param {?} year * @return {?} */ function (year) { this.date.setFullYear(year); this.year = this.date.getFullYear(); }; /** @hidden */ /** * @hidden * @param {?} selectedYear * @param {?=} event * @return {?} */ CalendarComponent.prototype.selectYear = /** * @hidden * @param {?} selectedYear * @param {?=} event * @return {?} */ function (selectedYear, event) { if (event) { event.stopPropagation(); } this.selectedMonth = this.month; this.setCurrentYear(selectedYear); this.constructCalendar(); this.openDaySelection(); }; /** * Displays the month selection grid. */ /** * Displays the month selection grid. * @return {?} */ CalendarComponent.prototype.openMonthSelection = /** * Displays the month selection grid. * @return {?} */ function () { if (this.showCalendarYears) { this.showCalendarYears = false; this.showCalendarMonths = true; this.showCalendarDates = false; } else { this.showCalendarMonths = !this.showCalendarMonths; this.showCalendarYears = false; this.showCalendarDates = !this.showCalendarDates; } }; /** * Displays the year selection grid. */ /** * Displays the year selection grid. * @return {?} */ CalendarComponent.prototype.openYearSelection = /** * Displays the year selection grid. * @return {?} */ function () { if (this.showCalendarMonths) { this.showCalendarMonths = false; this.showCalendarYears = true; this.showCalendarDates = false; } else { this.showCalendarYears = !this.showCalendarYears; this.showCalendarMonths = false; this.showCalendarDates = !this.showCalendarDates; } }; /** * Displays the date selection grid. */ /** * Displays the date selection grid. * @return {?} */ CalendarComponent.prototype.openDaySelection = /** * Displays the date selection grid. * @return {?} */ function () { this.showCalendarMonths = false; this.showCalendarYears = false; this.showCalendarDates = true; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.onEscapeKeydownHandler = /** * @hidden * @return {?} */ function () { this.showCalendarDates = true; this.showCalendarMonths = false; this.showCalendarYears = false; }; /** @hidden */ /** * @hidden * @param {?} e * @return {?} */ CalendarComponent.prototype.onClickHandler = /** * @hidden * @param {?} e * @return {?} */ function (e) { /** @type {?} */ var target = e.target; if (!this.eRef.nativeElement.contains(target)) { this.showCalendarDates = true; this.showCalendarMonths = false; this.showCalendarYears = false; } }; /** @hidden */ /** * @hidden * @param {?} date * @return {?} */ CalendarComponent.prototype.validateDateFromDatePicker = /** * @hidden * @param {?} date * @return {?} */ function (date) { if (!date) { return true; } /** @type {?} */ var month = date.getMonth(); /** @type {?} */ var day = date.getDate(); /** @type {?} */ var year = date.getFullYear(); if (isNaN(month) || isNaN(day) || isNaN(year)) { return true; } if (year < 1000 || year > 3000 || month < 0 || month > 11) { return true; } if (day < 1 || day > this.determineDaysInMonth(month, year)) { return true; } return false; }; /** @hidden */ /** * @hidden * @return {?} */ CalendarComponent.prototype.resetSelection = /** * @hidden * @return {?} */ function () { if (this.calType === 'single') { this.selectedDay = { date: null }; this.selectedDayChange.emit(this.selectedDay); } else { this.selectedRangeFirst = { date: null }; this.selectedRangeFirstChange.emit(this.selectedRangeFirst); this.selectedRangeLast = { date: null }; this.selectedRangeLastChange.emit(this.selectedRangeLast); } this.date = new Date(); this.year = this.date.getFullYear(); this.month = this.date.getMonth(); this.monthName = this.monthsFullName[this.date.getMonth()]; this.day = this.date.getDate(); this.selectedMonth = null; this.firstYearCalendarList = this.year; this.selectCounter = 0; this.calendarYearsList = []; this.constructCalendarYearsList(); this.constructCalendar(); }; /** @hidden */ /** * @hidden * @param {?} event * @param {?} year * @return {?} */ CalendarComponent.prototype.onKeydownYearHandler = /** * @hidden * @param {?} event * @param {?} year * @return {?} */ function (event, year) { /** @type {?} */ var newFocusedYearId; if (event.code === 'Space' || event.code === 'Enter') { event.preventDefault(); this.selectYear(year); } else if (event.code === 'ArrowUp') { event.preventDefault(); if (this.calendarYearsList.indexOf(year) <= 3) { this.loadPrevYearsList(); this.cd.detectChanges(); } newFocusedYearId = '#' + this.id + '-fd-year-' + (year - 4); } else if (event.code === 'ArrowDown') { event.preventDefault(); if (this.calendarYearsList.indexOf(year) >= 8) { this.loadNextYearsList(); this.cd.detectChanges(); } newFocusedYearId = '#' + this.id + '-fd-year-' + (year + 4); } else if (event.code === 'ArrowLeft') { event.preventDefault(); if (year === this.calendarYearsList[0]) { this.loadPrevYearsList(); this.cd.detectChanges(); } newFocusedYearId = '#' + this.id + '-fd-year-' + (year - 1); } else if (event.code === 'ArrowRight') { event.preventDefault(); if (year === this.calendarYearsList[this.calendarYearsList.length - 1]) { this.loadNextYearsList(); this.cd.detectChanges(); } newFocusedYearId = '#' + this.id + '-fd-year-' + (year + 1); } else if (event.code === 'Tab' && !event.shiftKey) { if (!this.allowFocusEscape) { event.preventDefault(); this.focusElement('#arrowLeft'); } } if (newFocusedYearId) { this.focusElement(newFocusedYearId); } }; /** @hidden */ /** * @hidden * @param {?} event * @param {?} month * @return {?} */ CalendarComponent.prototype.onKeydownMonthHandler = /** * @hidden * @param {?} event * @param {?} month * @return {?} */ function (event, month) { /** @type {?} */ var newFocusedMonthId; if (event.code === 'Space' || event.code === 'Enter') { event.preventDefault(); this.selectMonth(month); } else if (event.code === 'ArrowUp') { event.preventDefault(); newFocusedMonthId = '#' + this.id + '-fd-month-' + (month - 4); } else if (event.code === 'ArrowDown') { event.preventDefault(); newFocusedMonthId = '#' + this.id + '-fd-month-' + (month + 4); } else if (event.code === 'ArrowLeft') { event.preventDefault(); if (month === 0) { newFocusedMonthId = '#' + this.id + '-fd-month-11'; } else { newFocusedMonthId = '#' + this.id + '-fd-month-' + (month - 1); } } else if (event.code === 'ArrowRight') { event.preventDefault(); if (month === 11) { newFocusedMonthId = '#' + this.id + '-fd-month-0'; } else { newFocusedMonthId = '#' + this.id + '-fd-month-' + (month + 1); } } else if (event.code === 'Tab' && !event.shiftKey) { if (!this.allowFocusEscape) { event.preventDefault(); this.focusElement('#arrowLeft'); } } if (newFocusedMonthId) { this.focusElement(newFocusedMonthId); } }; /** @hidden */ /** * @hidden * @param {?} event * @param {?} cell * @return {?} */ CalendarComponent.prototype.onKeydownDayHandler = /** * @hidden * @param {?} event * @param {?} cell * @return {?} */ function (event, cell) { if (event.code === 'Tab' && !event.shiftKey) { if (!this.allowFocusEscape) { event.preventDefault(); this.focusElement('#arrowLeft'); } } else { // if the grid has 6 rows, the last cell id is 66, if it has 5 rows it's 56 /** @type {?} */ var lastDay = this.calendarGrid.length === 6 ? 66 : 56; /** @type {?} */ var currentId = parseInt(event.currentTarget.id.split('-').pop(), 10); if (event.code === 'Space' || event.code === 'Enter') { event.preventDefault(); /** @type {?} */ var closeCalendarPopover = true; this.selectDate(cell, true, null, closeCalendarPopover); this.newFocusedDayId = '#' + this.id + '-fd-day-' + currentId; } else if (event.code === 'ArrowUp') { event.preventDefault(); if (currentId >= 10 && currentId <= 16) { // if first row, go to previous month this.goToPreviousMonth(); /** @type {?} */ var lastDigit = currentId.toString().split('').pop(); this.newFocusedDayId = '#' + this.id + '-fd-day-' + this.calendarGrid.length.toString() + lastDigit; } else { this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId - 10); } } else if (event.code === 'ArrowDown') { event.preventDefault(); if (currentId >= lastDay - 6 && currentId <= lastDay) { // if last row, go to next month this.goToNextMonth(); /** @type {?} */ var lastDigit = currentId.toString().split('').pop(); this.newFocusedDayId = '#' + this.id + '-fd-day-1' + lastDigit; } else { this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId + 10); } } else if (event.code === 'ArrowLeft') { event.preventDefault(); if (currentId === 10) { // if the first day is selected, go to the last day of the previous month this.goToPreviousMonth(); lastDay = this.calendarGrid.length === 6 ? 66 : 56; this.newFocusedDayId = '#' + this.id + '-fd-day-' + lastDay; } else if (currentId.toString().split('').pop() === '0') { // if the last digit is 0, skip to the last day of the previous week this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId - 4); } else { this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId - 1); } } else if (event.code === 'ArrowRight') { event.preventDefault(); if (currentId === lastDay) { // if the last day is selected, go to the first day of the next month this.goToNextMonth(); this.newFocusedDayId = '#' + this.id + '-fd-day-10'; } else if (currentId.toString().split('').pop() === '6') { // else if the last digit is 6, skip to the first day of the next week this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId + 4); } else { this.newFocusedDayId = '#' + this.id + '-fd-day-' + (currentId + 1); } } if (this.newFocusedDayId) { this.focusElement(this.newFocusedDayId); } } }; /** @hidden */ /** * @hidden * @param {?} elementSelector * @return {?} */ CalendarComponent.prototype.focusElement = /** * @hidden * @param {?} elementSelector * @return {?} */ function (elementSelector) { /** @type {?} */ var elementToFocus = this.eRef.nativeElement.querySelector(elementSelector); if (elementToFocus) { elementToFocus.focus(); } }; /** @hidden */ /** * @hidden * @param {?} date * @return {?} */ CalendarComponent.prototype.updateFromDatePicker = /** * @hidden * @param {?} date * @return {?} */ function (date) { if (this.calType === 'single') { /** @type {?} */ var singleDate = this.dateAdapter.parse(date); this.invalidDate = this.validateDateFromDatePicker(singleDate); if (!this.invalidDate) { this.selectedDay.date = new Date(singleDate.getFullYear(), singleDate.getMonth(), singleDate.getDate()); this.date = new Date(singleDate.getFullYear(), singleDate.getMonth(), singleDate.getDate()); this.year = this.date.getFullYear(); this.month = this.date.getMonth(); this.monthName = this.monthsFullName[this.date.getMonth()]; this.isInvalidDateInput.emit(this.invalidDate); this.constructCalendar(); this.constructCalendarYearsList(); this.updateDatePickerInputEmitter(); } else { this.isInvalidDateInput.emit(this.invalidDate); this.resetSelection(); } } else { /** @type {?} */ var currentDates = date.split(this.dateAdapter.rangeDelimiter);