UNPKG

primeng

Version:

[![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT) [![npm version](https://badge.fury.io/js/primeng.svg)](https://badge.fury.io/js/primeng) [![npm downloads](https://img.shields.io/npm/dm/primeng.sv

1 lines 202 kB
{"version":3,"file":"primeng-calendar.mjs","sources":["../../src/app/components/calendar/calendar.ts","../../src/app/components/calendar/primeng-calendar.ts"],"sourcesContent":["import { animate, AnimationEvent, state, style, transition, trigger } from '@angular/animations';\nimport { CommonModule } from '@angular/common';\nimport {\n ChangeDetectionStrategy,\n ChangeDetectorRef,\n Component,\n ContentChildren,\n ElementRef,\n EventEmitter,\n forwardRef,\n Input,\n NgModule,\n NgZone,\n OnDestroy,\n OnInit,\n Output,\n QueryList,\n Renderer2,\n TemplateRef,\n ViewChild,\n ViewEncapsulation\n} from '@angular/core';\nimport { ControlValueAccessor, NG_VALUE_ACCESSOR } from '@angular/forms';\nimport { OverlayService, PrimeNGConfig, PrimeTemplate, SharedModule, TranslationKeys } from 'primeng/api';\nimport { ButtonModule } from 'primeng/button';\nimport { ConnectedOverlayScrollHandler, DomHandler } from 'primeng/dom';\nimport { RippleModule } from 'primeng/ripple';\nimport { ObjectUtils, UniqueComponentId, ZIndexUtils } from 'primeng/utils';\nimport { Subscription } from 'rxjs';\n\nexport const CALENDAR_VALUE_ACCESSOR: any = {\n provide: NG_VALUE_ACCESSOR,\n useExisting: forwardRef(() => Calendar),\n multi: true\n};\n\nexport interface LocaleSettings {\n firstDayOfWeek?: number;\n dayNames?: string[];\n dayNamesShort?: string[];\n dayNamesMin?: string[];\n monthNames?: string[];\n monthNamesShort?: string[];\n today?: string;\n clear?: string;\n dateFormat?: string;\n weekHeader?: string;\n}\n\nexport type CalendarTypeView = 'date' | 'month' | 'year';\n\n@Component({\n selector: 'p-calendar',\n template: `\n <span #container [ngClass]=\"{ 'p-calendar': true, 'p-calendar-w-btn': showIcon, 'p-calendar-timeonly': timeOnly, 'p-calendar-disabled': disabled, 'p-focus': focus }\" [ngStyle]=\"style\" [class]=\"styleClass\">\n <ng-template [ngIf]=\"!inline\">\n <input\n #inputfield\n type=\"text\"\n [attr.id]=\"inputId\"\n [attr.name]=\"name\"\n [attr.required]=\"required\"\n [attr.aria-required]=\"required\"\n [value]=\"inputFieldValue\"\n (focus)=\"onInputFocus($event)\"\n (keydown)=\"onInputKeydown($event)\"\n (click)=\"onInputClick()\"\n (blur)=\"onInputBlur($event)\"\n [readonly]=\"readonlyInput\"\n (input)=\"onUserInput($event)\"\n [ngStyle]=\"inputStyle\"\n [class]=\"inputStyleClass\"\n [placeholder]=\"placeholder || ''\"\n [disabled]=\"disabled\"\n [attr.tabindex]=\"tabindex\"\n [attr.inputmode]=\"touchUI ? 'off' : null\"\n [ngClass]=\"'p-inputtext p-component'\"\n autocomplete=\"off\"\n [attr.aria-labelledby]=\"ariaLabelledBy\"\n />\n <i *ngIf=\"showClear && !disabled && value != null\" class=\"p-calendar-clear-icon pi pi-times\" (click)=\"clear()\"></i>\n <button type=\"button\" [attr.aria-label]=\"iconAriaLabel\" [icon]=\"icon\" pButton pRipple *ngIf=\"showIcon\" (click)=\"onButtonClick($event, inputfield)\" class=\"p-datepicker-trigger\" [disabled]=\"disabled\" tabindex=\"0\"></button>\n </ng-template>\n <div\n #contentWrapper\n [class]=\"panelStyleClass\"\n [ngStyle]=\"panelStyle\"\n [ngClass]=\"{\n 'p-datepicker p-component': true,\n 'p-datepicker-inline': inline,\n 'p-disabled': disabled,\n 'p-datepicker-timeonly': timeOnly,\n 'p-datepicker-multiple-month': this.numberOfMonths > 1,\n 'p-datepicker-monthpicker': view === 'month',\n 'p-datepicker-touch-ui': touchUI\n }\"\n [@overlayAnimation]=\"\n touchUI\n ? { value: 'visibleTouchUI', params: { showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions } }\n : { value: 'visible', params: { showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions } }\n \"\n [@.disabled]=\"inline === true\"\n (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\"\n (@overlayAnimation.done)=\"onOverlayAnimationDone($event)\"\n (click)=\"onOverlayClick($event)\"\n *ngIf=\"inline || overlayVisible\"\n >\n <ng-content select=\"p-header\"></ng-content>\n <ng-container *ngTemplateOutlet=\"headerTemplate\"></ng-container>\n <ng-container *ngIf=\"!timeOnly\">\n <div class=\"p-datepicker-group-container\">\n <div class=\"p-datepicker-group\" *ngFor=\"let month of months; let i = index\">\n <div class=\"p-datepicker-header\">\n <button (keydown)=\"onContainerButtonKeydown($event)\" class=\"p-datepicker-prev p-link\" (click)=\"onPrevButtonClick($event)\" *ngIf=\"i === 0\" type=\"button\" pRipple>\n <span class=\"p-datepicker-prev-icon pi pi-chevron-left\"></span>\n </button>\n <div class=\"p-datepicker-title\">\n <button type=\"button\" (click)=\"switchToMonthView($event)\" (keydown)=\"onContainerButtonKeydown($event)\" *ngIf=\"currentView === 'date'\" class=\"p-datepicker-month p-link\" [disabled]=\"switchViewButtonDisabled()\">\n {{ getMonthName(month.month) }}\n </button>\n <button type=\"button\" (click)=\"switchToYearView($event)\" (keydown)=\"onContainerButtonKeydown($event)\" *ngIf=\"currentView !== 'year'\" class=\"p-datepicker-year p-link\" [disabled]=\"switchViewButtonDisabled()\">\n {{ getYear(month) }}\n </button>\n <span class=\"p-datepicker-decade\" *ngIf=\"currentView === 'year'\">\n <ng-container *ngIf=\"!decadeTemplate\">{{ yearPickerValues()[0] }} - {{ yearPickerValues()[yearPickerValues().length - 1] }}</ng-container>\n <ng-container *ngTemplateOutlet=\"decadeTemplate; context: { $implicit: yearPickerValues }\"></ng-container>\n </span>\n </div>\n <button\n (keydown)=\"onContainerButtonKeydown($event)\"\n class=\"p-datepicker-next p-link\"\n (click)=\"onNextButtonClick($event)\"\n [style.display]=\"numberOfMonths === 1 ? 'inline-flex' : i === numberOfMonths - 1 ? 'inline-flex' : 'none'\"\n type=\"button\"\n pRipple\n >\n <span class=\"p-datepicker-next-icon pi pi-chevron-right\"></span>\n </button>\n </div>\n <div class=\"p-datepicker-calendar-container\" *ngIf=\"currentView === 'date'\">\n <table class=\"p-datepicker-calendar\">\n <thead>\n <tr>\n <th *ngIf=\"showWeek\" class=\"p-datepicker-weekheader p-disabled\">\n <span>{{ getTranslation('weekHeader') }}</span>\n </th>\n <th scope=\"col\" *ngFor=\"let weekDay of weekDays; let begin = first; let end = last\">\n <span>{{ weekDay }}</span>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let week of month.dates; let j = index\">\n <td *ngIf=\"showWeek\" class=\"p-datepicker-weeknumber\">\n <span class=\"p-disabled\">\n {{ month.weekNumbers[j] }}\n </span>\n </td>\n <td *ngFor=\"let date of week\" [ngClass]=\"{ 'p-datepicker-other-month': date.otherMonth, 'p-datepicker-today': date.today }\">\n <ng-container *ngIf=\"date.otherMonth ? showOtherMonths : true\">\n <span [ngClass]=\"{ 'p-highlight': isSelected(date), 'p-disabled': !date.selectable }\" (click)=\"onDateSelect($event, date)\" draggable=\"false\" (keydown)=\"onDateCellKeydown($event, date, i)\" pRipple>\n <ng-container *ngIf=\"!dateTemplate\">{{ date.day }}</ng-container>\n <ng-container *ngTemplateOutlet=\"dateTemplate; context: { $implicit: date }\"></ng-container>\n </span>\n </ng-container>\n </td>\n </tr>\n </tbody>\n </table>\n </div>\n </div>\n </div>\n <div class=\"p-monthpicker\" *ngIf=\"currentView === 'month'\">\n <span\n *ngFor=\"let m of monthPickerValues(); let i = index\"\n (click)=\"onMonthSelect($event, i)\"\n (keydown)=\"onMonthCellKeydown($event, i)\"\n class=\"p-monthpicker-month\"\n [ngClass]=\"{ 'p-highlight': isMonthSelected(i), 'p-disabled': isMonthDisabled(i) }\"\n pRipple\n >\n {{ m }}\n </span>\n </div>\n <div class=\"p-yearpicker\" *ngIf=\"currentView === 'year'\">\n <span *ngFor=\"let y of yearPickerValues()\" (click)=\"onYearSelect($event, y)\" (keydown)=\"onYearCellKeydown($event, y)\" class=\"p-yearpicker-year\" [ngClass]=\"{ 'p-highlight': isYearSelected(y) }\" pRipple>\n {{ y }}\n </span>\n </div>\n </ng-container>\n <div class=\"p-timepicker\" *ngIf=\"(showTime || timeOnly) && currentView === 'date'\">\n <div class=\"p-hour-picker\">\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"incrementHour($event)\"\n (keydown.space)=\"incrementHour($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 0, 1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentHour < 10\">0</ng-container>{{ currentHour }}</span>\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"decrementHour($event)\"\n (keydown.space)=\"decrementHour($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 0, -1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-down\"></span>\n </button>\n </div>\n <div class=\"p-separator\">\n <span>{{ timeSeparator }}</span>\n </div>\n <div class=\"p-minute-picker\">\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"incrementMinute($event)\"\n (keydown.space)=\"incrementMinute($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 1, 1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentMinute < 10\">0</ng-container>{{ currentMinute }}</span>\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"decrementMinute($event)\"\n (keydown.space)=\"decrementMinute($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 1, -1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-down\"></span>\n </button>\n </div>\n <div class=\"p-separator\" *ngIf=\"showSeconds\">\n <span>{{ timeSeparator }}</span>\n </div>\n <div class=\"p-second-picker\" *ngIf=\"showSeconds\">\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"incrementSecond($event)\"\n (keydown.space)=\"incrementSecond($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 2, 1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentSecond < 10\">0</ng-container>{{ currentSecond }}</span>\n <button\n class=\"p-link\"\n type=\"button\"\n (keydown)=\"onContainerButtonKeydown($event)\"\n (keydown.enter)=\"decrementSecond($event)\"\n (keydown.space)=\"decrementSecond($event)\"\n (mousedown)=\"onTimePickerElementMouseDown($event, 2, -1)\"\n (mouseup)=\"onTimePickerElementMouseUp($event)\"\n (keyup.enter)=\"onTimePickerElementMouseUp($event)\"\n (keyup.space)=\"onTimePickerElementMouseUp($event)\"\n (mouseleave)=\"onTimePickerElementMouseLeave()\"\n pRipple\n >\n <span class=\"pi pi-chevron-down\"></span>\n </button>\n </div>\n <div class=\"p-ampm-picker\" *ngIf=\"hourFormat == '12'\">\n <button class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (click)=\"toggleAMPM($event)\" (keydown.enter)=\"toggleAMPM($event)\" pRipple>\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span>{{ pm ? 'PM' : 'AM' }}</span>\n <button class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (click)=\"toggleAMPM($event)\" (keydown.enter)=\"toggleAMPM($event)\" pRipple>\n <span class=\"pi pi-chevron-down\"></span>\n </button>\n </div>\n </div>\n <div class=\"p-datepicker-buttonbar\" *ngIf=\"showButtonBar\">\n <button type=\"button\" [label]=\"getTranslation('today')\" (keydown)=\"onContainerButtonKeydown($event)\" (click)=\"onTodayButtonClick($event)\" pButton pRipple [ngClass]=\"[todayButtonStyleClass]\"></button>\n <button type=\"button\" [label]=\"getTranslation('clear')\" (keydown)=\"onContainerButtonKeydown($event)\" (click)=\"onClearButtonClick($event)\" pButton pRipple [ngClass]=\"[clearButtonStyleClass]\"></button>\n </div>\n <ng-content select=\"p-footer\"></ng-content>\n <ng-container *ngTemplateOutlet=\"footerTemplate\"></ng-container>\n </div>\n </span>\n `,\n animations: [\n trigger('overlayAnimation', [\n state(\n 'visibleTouchUI',\n style({\n transform: 'translate(-50%,-50%)',\n opacity: 1\n })\n ),\n transition('void => visible', [style({ opacity: 0, transform: 'scaleY(0.8)' }), animate('{{showTransitionParams}}', style({ opacity: 1, transform: '*' }))]),\n transition('visible => void', [animate('{{hideTransitionParams}}', style({ opacity: 0 }))]),\n transition('void => visibleTouchUI', [style({ opacity: 0, transform: 'translate3d(-50%, -40%, 0) scale(0.9)' }), animate('{{showTransitionParams}}')]),\n transition('visibleTouchUI => void', [\n animate(\n '{{hideTransitionParams}}',\n style({\n opacity: 0,\n transform: 'translate3d(-50%, -40%, 0) scale(0.9)'\n })\n )\n ])\n ])\n ],\n host: {\n class: 'p-element p-inputwrapper',\n '[class.p-inputwrapper-filled]': 'filled',\n '[class.p-inputwrapper-focus]': 'focus',\n '[class.p-calendar-clearable]': 'showClear && !disabled'\n },\n providers: [CALENDAR_VALUE_ACCESSOR],\n changeDetection: ChangeDetectionStrategy.OnPush,\n encapsulation: ViewEncapsulation.None,\n styleUrls: ['./calendar.css']\n})\nexport class Calendar implements OnInit, OnDestroy, ControlValueAccessor {\n @Input() style: any;\n\n @Input() styleClass: string;\n\n @Input() inputStyle: any;\n\n @Input() inputId: string;\n\n @Input() name: string;\n\n @Input() inputStyleClass: string;\n\n @Input() placeholder: string;\n\n @Input() ariaLabelledBy: string;\n\n @Input() iconAriaLabel: string;\n\n @Input() disabled: any;\n\n @Input() dateFormat: string;\n\n @Input() multipleSeparator: string = ',';\n\n @Input() rangeSeparator: string = '-';\n\n @Input() inline: boolean = false;\n\n @Input() showOtherMonths: boolean = true;\n\n @Input() selectOtherMonths: boolean;\n\n @Input() showIcon: boolean;\n\n @Input() icon: string = 'pi pi-calendar';\n\n @Input() appendTo: any;\n\n @Input() readonlyInput: boolean;\n\n @Input() shortYearCutoff: any = '+10';\n\n @Input() monthNavigator: boolean;\n\n @Input() yearNavigator: boolean;\n\n @Input() hourFormat: string = '24';\n\n @Input() timeOnly: boolean;\n\n @Input() stepHour: number = 1;\n\n @Input() stepMinute: number = 1;\n\n @Input() stepSecond: number = 1;\n\n @Input() showSeconds: boolean = false;\n\n @Input() required: boolean;\n\n @Input() showOnFocus: boolean = true;\n\n @Input() showWeek: boolean = false;\n\n @Input() showClear: boolean = false;\n\n @Input() dataType: string = 'date';\n\n @Input() selectionMode: string = 'single';\n\n @Input() maxDateCount: number;\n\n @Input() showButtonBar: boolean;\n\n @Input() todayButtonStyleClass: string = 'p-button-text';\n\n @Input() clearButtonStyleClass: string = 'p-button-text';\n\n @Input() autoZIndex: boolean = true;\n\n @Input() baseZIndex: number = 0;\n\n @Input() panelStyleClass: string;\n\n @Input() panelStyle: any;\n\n @Input() keepInvalid: boolean = false;\n\n @Input() hideOnDateTimeSelect: boolean = true;\n\n @Input() touchUI: boolean;\n\n @Input() timeSeparator: string = ':';\n\n @Input() focusTrap: boolean = true;\n\n @Input() showTransitionOptions: string = '.12s cubic-bezier(0, 0, 0.2, 1)';\n\n @Input() hideTransitionOptions: string = '.1s linear';\n\n @Output() onFocus: EventEmitter<any> = new EventEmitter();\n\n @Output() onBlur: EventEmitter<any> = new EventEmitter();\n\n @Output() onClose: EventEmitter<any> = new EventEmitter();\n\n @Output() onSelect: EventEmitter<any> = new EventEmitter();\n\n @Output() onClear: EventEmitter<any> = new EventEmitter();\n\n @Output() onInput: EventEmitter<any> = new EventEmitter();\n\n @Output() onTodayClick: EventEmitter<any> = new EventEmitter();\n\n @Output() onClearClick: EventEmitter<any> = new EventEmitter();\n\n @Output() onMonthChange: EventEmitter<any> = new EventEmitter();\n\n @Output() onYearChange: EventEmitter<any> = new EventEmitter();\n\n @Output() onClickOutside: EventEmitter<any> = new EventEmitter();\n\n @Output() onShow: EventEmitter<any> = new EventEmitter();\n\n @ContentChildren(PrimeTemplate) templates: QueryList<any>;\n\n @Input() tabindex: number;\n\n @ViewChild('container', { static: false }) containerViewChild: ElementRef;\n\n @ViewChild('inputfield', { static: false }) inputfieldViewChild: ElementRef;\n\n @ViewChild('contentWrapper', { static: false }) set content(content: ElementRef) {\n this.contentViewChild = content;\n\n if (this.contentViewChild) {\n if (this.isMonthNavigate) {\n Promise.resolve(null).then(() => this.updateFocus());\n this.isMonthNavigate = false;\n } else {\n if (!this.focus) {\n this.initFocusableCell();\n }\n }\n }\n }\n\n contentViewChild: ElementRef;\n\n value: any;\n\n dates: any[];\n\n months: any[];\n\n weekDays: string[];\n\n currentMonth: number;\n\n currentYear: number;\n\n currentHour: number;\n\n currentMinute: number;\n\n currentSecond: number;\n\n pm: boolean;\n\n mask: HTMLDivElement;\n\n maskClickListener: Function;\n\n overlay: HTMLDivElement;\n\n responsiveStyleElement: any;\n\n overlayVisible: boolean;\n\n onModelChange: Function = () => {};\n\n onModelTouched: Function = () => {};\n\n calendarElement: any;\n\n timePickerTimer: any;\n\n documentClickListener: any;\n\n animationEndListener: any;\n\n ticksTo1970: number;\n\n yearOptions: number[];\n\n focus: boolean;\n\n isKeydown: boolean;\n\n filled: boolean;\n\n inputFieldValue: string = null;\n\n _minDate: Date;\n\n _maxDate: Date;\n\n _showTime: boolean;\n\n _yearRange: string;\n\n preventDocumentListener: boolean;\n\n dateTemplate: TemplateRef<any>;\n\n headerTemplate: TemplateRef<any>;\n\n footerTemplate: TemplateRef<any>;\n\n disabledDateTemplate: TemplateRef<any>;\n\n decadeTemplate: TemplateRef<any>;\n\n _disabledDates: Array<Date>;\n\n _disabledDays: Array<number>;\n\n selectElement: any;\n\n todayElement: any;\n\n focusElement: any;\n\n scrollHandler: any;\n\n documentResizeListener: any;\n\n navigationState: any = null;\n\n isMonthNavigate: boolean;\n\n initialized: boolean;\n\n translationSubscription: Subscription;\n\n _locale: LocaleSettings;\n\n _responsiveOptions: any[];\n\n currentView: string;\n\n attributeSelector: string;\n\n _numberOfMonths: number = 1;\n\n _firstDayOfWeek: number;\n\n _view: CalendarTypeView = 'date';\n\n preventFocus: boolean;\n\n @Input() get view(): CalendarTypeView {\n return this._view;\n }\n\n set view(view: CalendarTypeView) {\n this._view = view;\n this.currentView = this._view;\n }\n\n @Input() get defaultDate(): Date {\n return this._defaultDate;\n }\n\n set defaultDate(defaultDate: Date) {\n this._defaultDate = defaultDate;\n\n if (this.initialized) {\n const date = defaultDate || new Date();\n this.currentMonth = date.getMonth();\n this.currentYear = date.getFullYear();\n this.initTime(date);\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n _defaultDate: Date;\n\n @Input() get minDate(): Date {\n return this._minDate;\n }\n\n set minDate(date: Date) {\n this._minDate = date;\n\n if (this.currentMonth != undefined && this.currentMonth != null && this.currentYear) {\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n @Input() get maxDate(): Date {\n return this._maxDate;\n }\n\n set maxDate(date: Date) {\n this._maxDate = date;\n\n if (this.currentMonth != undefined && this.currentMonth != null && this.currentYear) {\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n @Input() get disabledDates(): Date[] {\n return this._disabledDates;\n }\n\n set disabledDates(disabledDates: Date[]) {\n this._disabledDates = disabledDates;\n if (this.currentMonth != undefined && this.currentMonth != null && this.currentYear) {\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n @Input() get disabledDays(): number[] {\n return this._disabledDays;\n }\n\n set disabledDays(disabledDays: number[]) {\n this._disabledDays = disabledDays;\n\n if (this.currentMonth != undefined && this.currentMonth != null && this.currentYear) {\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n @Input() get yearRange(): string {\n return this._yearRange;\n }\n\n set yearRange(yearRange: string) {\n this._yearRange = yearRange;\n\n if (yearRange) {\n const years = yearRange.split(':');\n const yearStart = parseInt(years[0]);\n const yearEnd = parseInt(years[1]);\n\n this.populateYearOptions(yearStart, yearEnd);\n }\n }\n\n @Input() get showTime(): boolean {\n return this._showTime;\n }\n\n set showTime(showTime: boolean) {\n this._showTime = showTime;\n\n if (this.currentHour === undefined) {\n this.initTime(this.value || new Date());\n }\n this.updateInputfield();\n }\n\n get locale() {\n return this._locale;\n }\n\n @Input() get responsiveOptions(): any[] {\n return this._responsiveOptions;\n }\n\n set responsiveOptions(responsiveOptions: any[]) {\n this._responsiveOptions = responsiveOptions;\n\n this.destroyResponsiveStyleElement();\n this.createResponsiveStyle();\n }\n\n @Input() get numberOfMonths(): number {\n return this._numberOfMonths;\n }\n\n set numberOfMonths(numberOfMonths: number) {\n this._numberOfMonths = numberOfMonths;\n\n this.destroyResponsiveStyleElement();\n this.createResponsiveStyle();\n }\n\n @Input() get firstDayOfWeek(): number {\n return this._firstDayOfWeek;\n }\n\n set firstDayOfWeek(firstDayOfWeek: number) {\n this._firstDayOfWeek = firstDayOfWeek;\n\n this.createWeekDays();\n }\n\n @Input()\n set locale(newLocale: LocaleSettings) {\n console.warn('Locale property has no effect, use new i18n API instead.');\n }\n\n constructor(public el: ElementRef, public renderer: Renderer2, public cd: ChangeDetectorRef, private zone: NgZone, private config: PrimeNGConfig, public overlayService: OverlayService) {}\n\n ngOnInit() {\n this.attributeSelector = UniqueComponentId();\n const date = this.defaultDate || new Date();\n this.createResponsiveStyle();\n this.currentMonth = date.getMonth();\n this.currentYear = date.getFullYear();\n this.currentView = this.view;\n\n if (this.view === 'date') {\n this.createWeekDays();\n this.initTime(date);\n this.createMonths(this.currentMonth, this.currentYear);\n this.ticksTo1970 = ((1970 - 1) * 365 + Math.floor(1970 / 4) - Math.floor(1970 / 100) + Math.floor(1970 / 400)) * 24 * 60 * 60 * 10000000;\n }\n\n this.translationSubscription = this.config.translationObserver.subscribe(() => {\n this.createWeekDays();\n });\n\n this.initialized = true;\n }\n\n ngAfterContentInit() {\n this.templates.forEach((item) => {\n switch (item.getType()) {\n case 'date':\n this.dateTemplate = item.template;\n break;\n\n case 'decade':\n this.decadeTemplate = item.template;\n break;\n\n case 'disabledDate':\n this.disabledDateTemplate = item.template;\n break;\n\n case 'header':\n this.headerTemplate = item.template;\n break;\n\n case 'footer':\n this.footerTemplate = item.template;\n break;\n\n default:\n this.dateTemplate = item.template;\n break;\n }\n });\n }\n\n ngAfterViewInit() {\n if (this.inline) {\n this.contentViewChild && this.contentViewChild.nativeElement.setAttribute(this.attributeSelector, '');\n\n if (!this.disabled) {\n this.initFocusableCell();\n if (this.numberOfMonths === 1) {\n this.contentViewChild.nativeElement.style.width = DomHandler.getOuterWidth(this.containerViewChild.nativeElement) + 'px';\n }\n }\n }\n }\n\n getTranslation(option: string) {\n return this.config.getTranslation(option);\n }\n\n populateYearOptions(start, end) {\n this.yearOptions = [];\n\n for (let i = start; i <= end; i++) {\n this.yearOptions.push(i);\n }\n }\n\n createWeekDays() {\n this.weekDays = [];\n let dayIndex = this.getFirstDateOfWeek();\n let dayLabels = this.getTranslation(TranslationKeys.DAY_NAMES_MIN);\n for (let i = 0; i < 7; i++) {\n this.weekDays.push(dayLabels[dayIndex]);\n dayIndex = dayIndex == 6 ? 0 : ++dayIndex;\n }\n }\n\n monthPickerValues() {\n let monthPickerValues = [];\n for (let i = 0; i <= 11; i++) {\n monthPickerValues.push(this.config.getTranslation('monthNamesShort')[i]);\n }\n\n return monthPickerValues;\n }\n\n yearPickerValues() {\n let yearPickerValues = [];\n let base = this.currentYear - (this.currentYear % 10);\n for (let i = 0; i < 10; i++) {\n yearPickerValues.push(base + i);\n }\n\n return yearPickerValues;\n }\n\n createMonths(month: number, year: number) {\n this.months = this.months = [];\n for (let i = 0; i < this.numberOfMonths; i++) {\n let m = month + i;\n let y = year;\n if (m > 11) {\n m = (m % 11) - 1;\n y = year + 1;\n }\n\n this.months.push(this.createMonth(m, y));\n }\n }\n\n getWeekNumber(date: Date) {\n let checkDate = new Date(date.getTime());\n checkDate.setDate(checkDate.getDate() + 4 - (checkDate.getDay() || 7));\n let time = checkDate.getTime();\n checkDate.setMonth(0);\n checkDate.setDate(1);\n return Math.floor(Math.round((time - checkDate.getTime()) / 86400000) / 7) + 1;\n }\n\n createMonth(month: number, year: number) {\n let dates = [];\n let firstDay = this.getFirstDayOfMonthIndex(month, year);\n let daysLength = this.getDaysCountInMonth(month, year);\n let prevMonthDaysLength = this.getDaysCountInPrevMonth(month, year);\n let dayNo = 1;\n let today = new Date();\n let weekNumbers = [];\n let monthRows = Math.ceil((daysLength + firstDay) / 7);\n\n for (let i = 0; i < monthRows; i++) {\n let week = [];\n\n if (i == 0) {\n for (let j = prevMonthDaysLength - firstDay + 1; j <= prevMonthDaysLength; j++) {\n let prev = this.getPreviousMonthAndYear(month, year);\n 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) });\n }\n\n let remainingDaysLength = 7 - week.length;\n for (let j = 0; j < remainingDaysLength; j++) {\n week.push({ day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year), selectable: this.isSelectable(dayNo, month, year, false) });\n dayNo++;\n }\n } else {\n for (let j = 0; j < 7; j++) {\n if (dayNo > daysLength) {\n let next = this.getNextMonthAndYear(month, year);\n week.push({\n day: dayNo - daysLength,\n month: next.month,\n year: next.year,\n otherMonth: true,\n today: this.isToday(today, dayNo - daysLength, next.month, next.year),\n selectable: this.isSelectable(dayNo - daysLength, next.month, next.year, true)\n });\n } else {\n week.push({ day: dayNo, month: month, year: year, today: this.isToday(today, dayNo, month, year), selectable: this.isSelectable(dayNo, month, year, false) });\n }\n\n dayNo++;\n }\n }\n\n if (this.showWeek) {\n weekNumbers.push(this.getWeekNumber(new Date(week[0].year, week[0].month, week[0].day)));\n }\n\n dates.push(week);\n }\n\n return {\n month: month,\n year: year,\n dates: dates,\n weekNumbers: weekNumbers\n };\n }\n\n initTime(date: Date) {\n this.pm = date.getHours() > 11;\n\n if (this.showTime) {\n this.currentMinute = date.getMinutes();\n this.currentSecond = date.getSeconds();\n this.setCurrentHourPM(date.getHours());\n } else if (this.timeOnly) {\n this.currentMinute = 0;\n this.currentHour = 0;\n this.currentSecond = 0;\n }\n }\n\n navBackward(event) {\n if (this.disabled) {\n event.preventDefault();\n return;\n }\n\n this.isMonthNavigate = true;\n\n if (this.currentView === 'month') {\n this.decrementYear();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n } else if (this.currentView === 'year') {\n this.decrementDecade();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n } else {\n if (this.currentMonth === 0) {\n this.currentMonth = 11;\n this.decrementYear();\n } else {\n this.currentMonth--;\n }\n\n this.onMonthChange.emit({ month: this.currentMonth + 1, year: this.currentYear });\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n navForward(event) {\n if (this.disabled) {\n event.preventDefault();\n return;\n }\n\n this.isMonthNavigate = true;\n\n if (this.currentView === 'month') {\n this.incrementYear();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n } else if (this.currentView === 'year') {\n this.incrementDecade();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n } else {\n if (this.currentMonth === 11) {\n this.currentMonth = 0;\n this.incrementYear();\n } else {\n this.currentMonth++;\n }\n\n this.onMonthChange.emit({ month: this.currentMonth + 1, year: this.currentYear });\n this.createMonths(this.currentMonth, this.currentYear);\n }\n }\n\n decrementYear() {\n this.currentYear--;\n\n if (this.yearNavigator && this.currentYear < this.yearOptions[0]) {\n let difference = this.yearOptions[this.yearOptions.length - 1] - this.yearOptions[0];\n this.populateYearOptions(this.yearOptions[0] - difference, this.yearOptions[this.yearOptions.length - 1] - difference);\n }\n }\n\n decrementDecade() {\n this.currentYear = this.currentYear - 10;\n }\n\n incrementDecade() {\n this.currentYear = this.currentYear + 10;\n }\n\n incrementYear() {\n this.currentYear++;\n\n if (this.yearNavigator && this.currentYear > this.yearOptions[this.yearOptions.length - 1]) {\n let difference = this.yearOptions[this.yearOptions.length - 1] - this.yearOptions[0];\n this.populateYearOptions(this.yearOptions[0] + difference, this.yearOptions[this.yearOptions.length - 1] + difference);\n }\n }\n\n switchToMonthView(event) {\n this.setCurrentView('month');\n event.preventDefault();\n }\n\n switchToYearView(event) {\n this.setCurrentView('year');\n event.preventDefault();\n }\n\n onDateSelect(event, dateMeta) {\n if (this.disabled || !dateMeta.selectable) {\n event.preventDefault();\n return;\n }\n\n if (this.isMultipleSelection() && this.isSelected(dateMeta)) {\n this.value = this.value.filter((date, i) => {\n return !this.isDateEquals(date, dateMeta);\n });\n if (this.value.length === 0) {\n this.value = null;\n }\n this.updateModel(this.value);\n } else {\n if (this.shouldSelectDate(dateMeta)) {\n this.selectDate(dateMeta);\n }\n }\n\n if (this.isSingleSelection() && this.hideOnDateTimeSelect) {\n setTimeout(() => {\n event.preventDefault();\n this.hideOverlay();\n\n if (this.mask) {\n this.disableModality();\n }\n\n this.cd.markForCheck();\n }, 150);\n }\n\n this.updateInputfield();\n event.preventDefault();\n }\n\n shouldSelectDate(dateMeta) {\n if (this.isMultipleSelection()) return this.maxDateCount != null ? this.maxDateCount > (this.value ? this.value.length : 0) : true;\n else return true;\n }\n\n onMonthSelect(event, index) {\n if (this.view === 'month') {\n this.onDateSelect(event, { year: this.currentYear, month: index, day: 1, selectable: true });\n } else {\n this.currentMonth = index;\n this.createMonths(this.currentMonth, this.currentYear);\n this.setCurrentView('date');\n this.onMonthChange.emit({ month: this.currentMonth + 1, year: this.currentYear });\n }\n }\n\n onYearSelect(event, year) {\n if (this.view === 'year') {\n this.onDateSelect(event, { year: year, month: 0, day: 1, selectable: true });\n } else {\n this.currentYear = year;\n this.setCurrentView('month');\n this.onYearChange.emit({ month: this.currentMonth + 1, year: this.currentYear });\n }\n }\n\n updateInputfield() {\n let formattedValue = '';\n\n if (this.value) {\n if (this.isSingleSelection()) {\n formattedValue = this.formatDateTime(this.value);\n } else if (this.isMultipleSelection()) {\n for (let i = 0; i < this.value.length; i++) {\n let dateAsString = this.formatDateTime(this.value[i]);\n formattedValue += dateAsString;\n if (i !== this.value.length - 1) {\n formattedValue += this.multipleSeparator + ' ';\n }\n }\n } else if (this.isRangeSelection()) {\n if (this.value && this.value.length) {\n let startDate = this.value[0];\n let endDate = this.value[1];\n\n formattedValue = this.formatDateTime(startDate);\n if (endDate) {\n formattedValue += ' ' + this.rangeSeparator + ' ' + this.formatDateTime(endDate);\n }\n }\n }\n }\n\n this.inputFieldValue = formattedValue;\n this.updateFilledState();\n if (this.inputfieldViewChild && this.inputfieldViewChild.nativeElement) {\n this.inputfieldViewChild.nativeElement.value = this.inputFieldValue;\n }\n }\n\n formatDateTime(date) {\n let formattedValue = this.keepInvalid ? date : null;\n\n if (this.isValidDate(date)) {\n if (this.timeOnly) {\n formattedValue = this.formatTime(date);\n } else {\n formattedValue = this.formatDate(date, this.getDateFormat());\n if (this.showTime) {\n formattedValue += ' ' + this.formatTime(date);\n }\n }\n }\n\n return formattedValue;\n }\n\n setCurrentHourPM(hours: number) {\n if (this.hourFormat == '12') {\n this.pm = hours > 11;\n if (hours >= 12) {\n this.currentHour = hours == 12 ? 12 : hours - 12;\n } else {\n this.currentHour = hours == 0 ? 12 : hours;\n }\n } else {\n this.currentHour = hours;\n }\n }\n\n setCurrentView(currentView: CalendarTypeView) {\n this.currentView = currentView;\n this.cd.detectChanges();\n this.alignOverlay();\n }\n\n selectDate(dateMeta) {\n let date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);\n\n if (this.showTime) {\n if (this.hourFormat == '12') {\n if (this.currentHour === 12) date.setHours(this.pm ? 12 : 0);\n else date.setHours(this.pm ? this.currentHour + 12 : this.currentHour);\n } else {\n date.setHours(this.currentHour);\n }\n\n date.setMinutes(this.currentMinute);\n date.setSeconds(this.currentSecond);\n }\n\n if (this.minDate && this.minDate > date) {\n date = this.minDate;\n this.setCurrentHourPM(date.getHours());\n this.currentMinute = date.getMinutes();\n this.currentSecond = date.getSeconds();\n }\n\n if (this.maxDate && this.maxDate < date) {\n date = this.maxDate;\n this.setCurrentHourPM(date.getHours());\n this.currentMinute = date.getMinutes();\n this.currentSecond = date.getSeconds();\n }\n\n if (this.isSingleSelection()) {\n this.updateModel(date);\n } else if (this.isMultipleSelection()) {\n this.updateModel(this.value ? [...this.value, date] : [date]);\n } else if (this.isRangeSelection()) {\n if (this.value && this.value.length) {\n let startDate = this.value[0];\n let endDate = this.value[1];\n\n if (!endDate && date.getTime() >= startDate.getTime()) {\n endDate = date;\n } else {\n startDate = date;\n endDate = null;\n }\n\n this.updateModel([startDate, endDate]);\n } else {\n this.updateModel([date, null]);\n }\n }\n\n this.onSelect.emit(date);\n }\n\n updateModel(value) {\n this.value = value;\n\n if (this.dataType == 'date') {\n this.onModelChange(this.value);\n } else if (this.dataType == 'string') {\n if (this.isSingleSelection()) {\n this.onModelChange(this.formatDateTime(this.value));\n } else {\n let stringArrValue = null;\n if (this.value) {\n stringArrValue = this.value.map((date) => this.formatDateTime(date));\n }\n this.onModelChange(stringArrValue);\n }\n }\n }\n\n getFirstDayOfMonthIndex(month: number, year: number) {\n let day = new Date();\n day.setDate(1);\n day.setMonth(month);\n day.setFullYear(year);\n\n let dayIndex = day.getDay() + this.getSundayIndex();\n return dayIndex >= 7 ? dayIndex - 7 : dayIndex;\n }\n\n getDaysCountInMonth(month: number, year: number) {\n return 32 - this.daylightSavingAdjust(new Date(year, month, 32)).getDate();\n }\n\n getDaysCountInPrevMonth(month: number, year: number) {\n let prev = this.getPreviousMonthAndYear(month, year);\n return this.getDaysCountInMonth(prev.month, prev.year);\n }\n\n getPreviousMonthAndYear(month: number, year: number) {\n let m, y;\n\n if (month === 0) {\n m = 11;\n y = year - 1;\n } else {\n m = month - 1;\n y = year;\n }\n\n return { month: m, year: y };\n }\n\n getNextMonthAndYear(month: number, year: number) {\n let m, y;\n\n if (month === 11) {\n m = 0;\n y = year + 1;\n } else {\n m = month + 1;\n y = year;\n }\n\n return { month: m, year: y };\n }\n\n getSundayIndex() {\n let firstDayOfWeek = this.getFirstDateOfWeek();\n\n return firstDayOfWeek > 0 ? 7 - firstDayOfWeek : 0;\n }\n\n isSelected(dateMeta): boolean {\n if (this.value) {\n if (this.isSingleSelection()) {\n return this.isDateEquals(this.value, dateMeta);\n } else if (this.isMultipleSelection()) {\n let selected = false;\n for (let date of this.value) {\n selected = this.isDateEquals(date, dateMeta);\n if (selected) {\n break;\n }\n }\n\n return selected;\n } else if (this.isRangeSelection()) {\n if (this.value[1]) return this.isDateEquals(this.value[0], dateMeta) || thi