primeng
Version:
[](https://opensource.org/licenses/MIT) [](https://badge.fury.io/js/primeng) [
{"version":3,"file":"primeng-calendar.mjs","sources":["../../src/app/components/calendar/calendar.ts","../../src/app/components/calendar/primeng-calendar.ts"],"sourcesContent":["import {NgModule,Component,ElementRef,OnDestroy,OnInit,Input,Output,EventEmitter,forwardRef,Renderer2,\n ViewChild,ChangeDetectorRef,TemplateRef,ContentChildren,QueryList,NgZone,ChangeDetectionStrategy, ViewEncapsulation} from '@angular/core';\nimport {trigger,state,style,transition,animate,AnimationEvent} from '@angular/animations';\nimport {CommonModule} from '@angular/common';\nimport {ButtonModule} from 'primeng/button';\nimport {RippleModule} from 'primeng/ripple';\nimport {DomHandler, ConnectedOverlayScrollHandler} from 'primeng/dom';\nimport {SharedModule,PrimeTemplate,PrimeNGConfig,TranslationKeys, OverlayService} from 'primeng/api';\nimport {NG_VALUE_ACCESSOR, ControlValueAccessor} from '@angular/forms';\nimport {Subscription} from 'rxjs';\nimport {UniqueComponentId, ZIndexUtils, ObjectUtils} from 'primeng/utils';\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\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 #inputfield type=\"text\" [attr.id]=\"inputId\" [attr.name]=\"name\" [attr.required]=\"required\" [attr.aria-required]=\"required\" [value]=\"inputFieldValue\" (focus)=\"onInputFocus($event)\" (keydown)=\"onInputKeydown($event)\" (click)=\"onInputClick()\" (blur)=\"onInputBlur($event)\"\n [readonly]=\"readonlyInput\" (input)=\"onUserInput($event)\" [ngStyle]=\"inputStyle\" [class]=\"inputStyleClass\" [placeholder]=\"placeholder||''\" [disabled]=\"disabled\" [attr.tabindex]=\"tabindex\" [attr.inputmode]=\"touchUI ? 'off' : null\"\n [ngClass]=\"'p-inputtext p-component'\" autocomplete=\"off\" [attr.aria-labelledby]=\"ariaLabelledBy\"\n ><button type=\"button\" [attr.aria-label]=\"iconAriaLabel\" [icon]=\"icon\" pButton pRipple *ngIf=\"showIcon\" (click)=\"onButtonClick($event,inputfield)\" class=\"p-datepicker-trigger\"\n [disabled]=\"disabled\" tabindex=\"0\"></button>\n </ng-template>\n <div #contentWrapper [class]=\"panelStyleClass\" [ngStyle]=\"panelStyle\" [ngClass]=\"{'p-datepicker p-component': true, 'p-datepicker-inline':inline,\n 'p-disabled':disabled,'p-datepicker-timeonly':timeOnly,'p-datepicker-multiple-month': this.numberOfMonths > 1, 'p-datepicker-monthpicker': (view === 'month'), 'p-datepicker-touch-ui': touchUI}\"\n [@overlayAnimation]=\"touchUI ? {value: 'visibleTouchUI', params: {showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions}}:\n {value: 'visible', params: {showTransitionParams: showTransitionOptions, hideTransitionParams: hideTransitionOptions}}\"\n [@.disabled]=\"inline === true\" (@overlayAnimation.start)=\"onOverlayAnimationStart($event)\" (@overlayAnimation.done)=\"onOverlayAnimationDone($event)\" (click)=\"onOverlayClick($event)\" *ngIf=\"inline || overlayVisible\">\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 (keydown)=\"onContainerButtonKeydown($event)\" class=\"p-datepicker-next p-link\" (click)=\"onNextButtonClick($event)\" [style.display]=\"numberOfMonths === 1 ? 'inline-flex' : (i === numberOfMonths -1) ? 'inline-flex' : 'none'\" type=\"button\" pRipple>\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}\"\n (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 *ngFor=\"let m of monthPickerValues(); let i = index\" (click)=\"onMonthSelect($event, i)\" (keydown)=\"onMonthCellKeydown($event,i)\" class=\"p-monthpicker-month\" [ngClass]=\"{'p-highlight': isMonthSelected(i)}\" pRipple>\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 class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"incrementHour($event)\" (keydown.space)=\"incrementHour($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 0, 1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentHour < 10\">0</ng-container>{{currentHour}}</span>\n <button class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"decrementHour($event)\" (keydown.space)=\"decrementHour($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 0, -1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\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 class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"incrementMinute($event)\" (keydown.space)=\"incrementMinute($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 1, 1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentMinute < 10\">0</ng-container>{{currentMinute}}</span>\n <button class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"decrementMinute($event)\" (keydown.space)=\"decrementMinute($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 1, -1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\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 class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"incrementSecond($event)\" (keydown.space)=\"incrementSecond($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 2, 1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\n <span class=\"pi pi-chevron-up\"></span>\n </button>\n <span><ng-container *ngIf=\"currentSecond < 10\">0</ng-container>{{currentSecond}}</span>\n <button class=\"p-link\" type=\"button\" (keydown)=\"onContainerButtonKeydown($event)\" (keydown.enter)=\"decrementSecond($event)\" (keydown.space)=\"decrementSecond($event)\" (mousedown)=\"onTimePickerElementMouseDown($event, 2, -1)\" (mouseup)=\"onTimePickerElementMouseUp($event)\" (keyup.enter)=\"onTimePickerElementMouseUp($event)\" (keyup.space)=\"onTimePickerElementMouseUp($event)\" (mouseleave)=\"onTimePickerElementMouseLeave()\" pRipple>\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('visibleTouchUI', style({\n transform: 'translate(-50%,-50%)',\n opacity: 1\n })),\n transition('void => visible', [\n style({opacity: 0, transform: 'scaleY(0.8)'}),\n animate('{{showTransitionParams}}', style({ opacity: 1, transform: '*' }))\n ]),\n transition('visible => void', [\n animate('{{hideTransitionParams}}', style({ opacity: 0 }))\n ]),\n transition('void => visibleTouchUI', [\n style({opacity: 0, transform: 'translate3d(-50%, -40%, 0) scale(0.9)'}),\n animate('{{showTransitionParams}}')\n ]),\n transition('visibleTouchUI => void', [\n animate(('{{hideTransitionParams}}'),\n style({\n opacity: 0,\n transform: 'translate3d(-50%, -40%, 0) scale(0.9)'\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 },\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\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() 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() 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 }\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: string = 'date';\n\n preventFocus: boolean;\n\n @Input() get view(): string {\n return this._view;\n };\n\n set view(view: string) {\n this._view = view;\n this.currentView = this._view;\n }\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\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\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\t\tcheckDate.setDate(checkDate.getDate() + 4 - ( checkDate.getDay() || 7 ));\n\t\tlet time = checkDate.getTime();\n\t\tcheckDate.setMonth( 0 );\n\t\tcheckDate.setDate( 1 );\n\t\treturn 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,\n 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),\n selectable: this.isSelectable(dayNo, month, year, false)});\n dayNo++;\n }\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({day: dayNo - daysLength, month: next.month, year: next.year, 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),\n 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 }\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 }\n else if (this.currentView === 'year') {\n this.decrementDecade();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n }\n else {\n if (this.currentMonth === 0) {\n this.currentMonth = 11;\n this.decrementYear();\n }\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 }\n else if (this.currentView === 'year') {\n this.incrementDecade();\n setTimeout(() => {\n this.updateFocus();\n }, 1);\n }\n else {\n if (this.currentMonth === 11) {\n this.currentMonth = 0;\n this.incrementYear();\n }\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 }\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())\n return this.maxDateCount != null ? this.maxDateCount > (this.value ? this.value.length : 0) : true;\n else\n 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 }\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 }\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 }\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 }\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 }\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 }\n else {\n this.currentHour = (hours == 0) ? 12 : hours;\n }\n }\n else {\n this.currentHour = hours;\n }\n }\n\n setCurrentView(currentView: string) {\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)\n date.setHours(this.pm ? 12 : 0);\n else\n date.setHours(this.pm ? this.currentHour + 12 : this.currentHour);\n }\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 }\n else if (this.isMultipleSelection()) {\n this.updateModel(this.value ? [...this.value, date] : [date]);\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 if (!endDate && date.getTime() >= startDate.getTime()) {\n endDate = date;\n }\n else {\n startDate = date;\n endDate = null;\n }\n\n this.updateModel([startDate, endDate]);\n }\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 }\n else if (this.dataType == 'string') {\n if (this.isSingleSelection()) {\n this.onModelChange(this.formatDateTime(this.value));\n }\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 }\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 }\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 }\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 }\n else if (this.isRangeSelection()) {\n if (this.value[1])\n return this.isDateEquals(this.value[0], dateMeta) || this.isDateEquals(this.value[1], dateMeta) || this.isDateBetween(this.value[0], this.value[1], dateMeta);\n else\n return this.isDateEquals(this.value[0], dateMeta)\n }\n }\n else {\n return false;\n }\n }\n\n isComparable() {\n return this.value != null && typeof this.value !== 'string';\n }\n\n isMonthSelected(month) {\n if (this.isComparable()) {\n let value = this.isRangeSelection() ? this.value[0] : this.value;\n\n return !this.isMultipleSelection() ? (value.getMonth() === month && value.getFullYear() === this.currentYear) : false;\n }\n\n return false;\n }\n\n isYearSelected(year) {\n if (this.isComparable()) {\n let value = this.isRangeSelection() ? this.value[0] : this.value;\n\n return !this.isMultipleSelection() ? (value.getFullYear() === year) : false;\n }\n\n return false;\n }\n\n isDateEquals(value, dateMeta) {\n if (value && value instanceof Date)\n return value.getDate() === dateMeta.day && value.getMonth() === dateMeta.month && value.getFullYear() === dateMeta.year;\n else\n return false;\n }\n\n isDateBetween(start, end, dateMeta) {\n let between : boolean = false;\n if (start && end) {\n let date: Date = new Date(dateMeta.year, dateMeta.month, dateMeta.day);\n return start.getTime() <= date.getTime() && end.getTime() >= date.getTime();\n }\n\n return between;\n }\n\n isSingleSelection(): boolean {\n return this.selectionMode === 'single';\n }\n\n isRangeSelection(): boolean {\n return this.selectionMode === 'range';\n }\n\n isMultipleSelection(): boolean {\n return this.selectionMode === 'multiple';\n }\n\n isToday(today, day, month, year): boolean {\n return today.getDate() === day && today.getMonth() === month && today.getFullYear() === year;\n }\n\n isSelectable(day, month, year, otherMonth): boolean {\n let validMin = true;\n let validMax = true;\n let validDate = true;\n let validDay = true;\n\n if (otherMonth && !this.selectOtherMonths) {\n return false;\n }\n\n if (this.minDate) {\n if (this.minDate.getFullYear() > year) {\n validMin = false;\n }\n else if (this.minDate.getFullYear() === year) {\n if (this.minDate.getMonth() > month) {\n validMin = false;\n }\n else if (this.minDate.getMonth() === month) {\n if (this.minDate.getDate() > day) {\n validMin = false;\n }\n }\n }\n }\n\n if (this.maxDate) {\n if (this.maxDate.getFullYear() < year) {\n validMax = false;\n }\n else if (this.maxDate.getFullYear() === year) {\n if (this.maxDate.getMonth() < month) {\n validMax = false;\n }\n else if (this.maxDate.getMonth() === month) {\n if (this.maxDate.getDate() < day) {\n validMax = false;\n }\n }\n }\n }\n\n if (this.disabledDates) {\n validDate = !this.isDat