ionic3-calendar3
Version:
Ionic3 calendar component
443 lines • 28.2 kB
JavaScript
"use strict";
Object.defineProperty(exports, "__esModule", { value: true });
var core_1 = require("@angular/core");
var common_1 = require("@angular/common");
var calendar_service_1 = require("./calendar.service");
var MonthViewComponent = (function () {
function MonthViewComponent(calendarService) {
this.calendarService = calendarService;
this.autoSelect = true;
this.dir = "";
this.onRangeChanged = new core_1.EventEmitter();
this.onEventSelected = new core_1.EventEmitter();
this.onTimeSelected = new core_1.EventEmitter(true);
this.onTitleChanged = new core_1.EventEmitter(true);
this.views = [];
this.currentViewIndex = 0;
this.mode = 'month';
this.direction = 0;
this.moveOnSelected = false;
this.inited = false;
this.callbackOnInit = true;
}
MonthViewComponent.prototype.ngOnInit = function () {
var _this = this;
if (this.dateFormatter && this.dateFormatter.formatMonthViewDay) {
this.formatDayLabel = this.dateFormatter.formatMonthViewDay;
}
else {
var dayLabelDatePipe = new common_1.DatePipe('en-US');
this.formatDayLabel = function (date) {
return dayLabelDatePipe.transform(date, this.formatDay);
};
}
if (this.dateFormatter && this.dateFormatter.formatMonthViewDayHeader) {
this.formatDayHeaderLabel = this.dateFormatter.formatMonthViewDayHeader;
}
else {
var datePipe = new common_1.DatePipe(this.locale);
this.formatDayHeaderLabel = function (date) {
return datePipe.transform(date, this.formatDayHeader);
};
}
if (this.dateFormatter && this.dateFormatter.formatMonthViewTitle) {
this.formatTitle = this.dateFormatter.formatMonthViewTitle;
}
else {
var datePipe = new common_1.DatePipe(this.locale);
this.formatTitle = function (date) {
return datePipe.transform(date, this.formatMonthTitle);
};
}
if (this.lockSwipeToPrev) {
this.slider.lockSwipeToPrev(true);
}
if (this.lockSwipes) {
this.slider.lockSwipes(true);
}
this.refreshView();
this.inited = true;
this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(function (currentDate) {
_this.refreshView();
});
this.eventSourceChangedSubscription = this.calendarService.eventSourceChanged$.subscribe(function () {
_this.onDataLoaded();
});
};
MonthViewComponent.prototype.ngOnDestroy = function () {
if (this.currentDateChangedFromParentSubscription) {
this.currentDateChangedFromParentSubscription.unsubscribe();
this.currentDateChangedFromParentSubscription = null;
}
if (this.eventSourceChangedSubscription) {
this.eventSourceChangedSubscription.unsubscribe();
this.eventSourceChangedSubscription = null;
}
};
MonthViewComponent.prototype.ngOnChanges = function (changes) {
if (!this.inited)
return;
var eventSourceChange = changes['eventSource'];
if (eventSourceChange && eventSourceChange.currentValue) {
this.onDataLoaded();
}
var lockSwipeToPrev = changes['lockSwipeToPrev'];
if (lockSwipeToPrev) {
this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue);
}
var lockSwipes = changes['lockSwipes'];
if (lockSwipes) {
this.slider.lockSwipes(lockSwipes.currentValue);
}
};
MonthViewComponent.prototype.ngAfterViewInit = function () {
var title = this.getTitle();
this.onTitleChanged.emit(title);
};
MonthViewComponent.prototype.onSlideChanged = function () {
if (this.callbackOnInit) {
this.callbackOnInit = false;
return;
}
var currentSlideIndex = this.slider.getActiveIndex(), direction = 0, currentViewIndex = this.currentViewIndex;
currentSlideIndex = (currentSlideIndex + 2) % 3;
if (currentSlideIndex - currentViewIndex === 1) {
direction = 1;
}
else if (currentSlideIndex === 0 && currentViewIndex === 2) {
direction = 1;
this.slider.slideTo(1, 0, false);
}
else if (currentViewIndex - currentSlideIndex === 1) {
direction = -1;
}
else if (currentSlideIndex === 2 && currentViewIndex === 0) {
direction = -1;
this.slider.slideTo(3, 0, false);
}
this.currentViewIndex = currentSlideIndex;
this.move(direction);
};
MonthViewComponent.prototype.move = function (direction) {
if (direction === 0)
return;
this.direction = direction;
if (!this.moveOnSelected) {
var adjacentDate = this.calendarService.getAdjacentCalendarDate(this.mode, direction);
this.calendarService.setCurrentDate(adjacentDate);
}
this.refreshView();
this.direction = 0;
this.moveOnSelected = false;
};
MonthViewComponent.prototype.createDateObject = function (date) {
var disabled = false;
if (this.markDisabled) {
disabled = this.markDisabled(date);
}
return {
date: date,
events: [],
label: this.formatDayLabel(date),
secondary: false,
disabled: disabled
};
};
MonthViewComponent.getDates = function (startDate, n) {
var dates = new Array(n), current = new Date(startDate.getTime()), i = 0;
current.setHours(12);
while (i < n) {
dates[i++] = new Date(current.getTime());
current.setDate(current.getDate() + 1);
}
return dates;
};
MonthViewComponent.prototype.getViewData = function (startTime) {
var startDate = startTime, date = startDate.getDate(), month = (startDate.getMonth() + (date !== 1 ? 1 : 0)) % 12;
var dates = MonthViewComponent.getDates(startDate, 42);
var days = [];
for (var i = 0; i < 42; i++) {
var dateObject = this.createDateObject(dates[i]);
dateObject.secondary = dates[i].getMonth() !== month;
days[i] = dateObject;
}
var dayHeaders = [];
for (var i = 0; i < 7; i++) {
dayHeaders.push(this.formatDayHeaderLabel(days[i].date));
}
return {
dates: days,
dayHeaders: dayHeaders
};
};
MonthViewComponent.prototype.getHighlightClass = function (date) {
var className = '';
if (date.hasEvent) {
if (date.secondary) {
className = 'monthview-secondary-with-event';
}
else {
className = 'monthview-primary-with-event';
}
}
if (date.selected) {
if (className) {
className += ' ';
}
className += 'monthview-selected';
}
if (date.current) {
if (className) {
className += ' ';
}
className += 'monthview-current';
}
if (date.secondary) {
if (className) {
className += ' ';
}
className += 'text-muted';
}
if (date.disabled) {
if (className) {
className += ' ';
}
className += 'monthview-disabled';
}
return className;
};
MonthViewComponent.prototype.getRange = function (currentDate) {
var year = currentDate.getFullYear(), month = currentDate.getMonth(), firstDayOfMonth = new Date(year, month, 1), difference = this.startingDayMonth - firstDayOfMonth.getDay(), numDisplayedFromPreviousMonth = (difference > 0) ? 7 - difference : -difference, startDate = new Date(firstDayOfMonth.getTime());
if (numDisplayedFromPreviousMonth > 0) {
startDate.setDate(-numDisplayedFromPreviousMonth + 1);
}
var endDate = new Date(startDate.getTime());
endDate.setDate(endDate.getDate() + 42);
return {
startTime: startDate,
endTime: endDate
};
};
MonthViewComponent.prototype.onDataLoaded = function () {
var range = this.range, eventSource = this.eventSource, len = eventSource ? eventSource.length : 0, startTime = range.startTime, endTime = range.endTime, utcStartTime = new Date(Date.UTC(startTime.getFullYear(), startTime.getMonth(), startTime.getDate())), utcEndTime = new Date(Date.UTC(endTime.getFullYear(), endTime.getMonth(), endTime.getDate())), currentViewIndex = this.currentViewIndex, dates = this.views[currentViewIndex].dates, oneDay = 86400000, eps = 0.0006;
for (var r = 0; r < 42; r += 1) {
if (dates[r].hasEvent) {
dates[r].hasEvent = false;
dates[r].events = [];
}
}
for (var i = 0; i < len; i += 1) {
var event_1 = eventSource[i], eventStartTime = new Date(event_1.startTime.getTime()), eventEndTime = new Date(event_1.endTime.getTime()), st = void 0, et = void 0;
if (event_1.allDay) {
if (eventEndTime <= utcStartTime || eventStartTime >= utcEndTime) {
continue;
}
else {
st = utcStartTime;
et = utcEndTime;
}
}
else {
if (eventEndTime <= startTime || eventStartTime >= endTime) {
continue;
}
else {
st = startTime;
et = endTime;
}
}
var timeDiff = void 0;
var timeDifferenceStart = void 0;
if (eventStartTime <= st) {
timeDifferenceStart = 0;
}
else {
timeDiff = eventStartTime.getTime() - st.getTime();
if (!event_1.allDay) {
timeDiff = timeDiff - (eventStartTime.getTimezoneOffset() - st.getTimezoneOffset()) * 60000;
}
timeDifferenceStart = timeDiff / oneDay;
}
var timeDifferenceEnd = void 0;
if (eventEndTime >= et) {
timeDiff = et.getTime() - st.getTime();
if (!event_1.allDay) {
timeDiff = timeDiff - (et.getTimezoneOffset() - st.getTimezoneOffset()) * 60000;
}
timeDifferenceEnd = timeDiff / oneDay;
}
else {
timeDiff = eventEndTime.getTime() - st.getTime();
if (!event_1.allDay) {
timeDiff = timeDiff - (eventEndTime.getTimezoneOffset() - st.getTimezoneOffset()) * 60000;
}
timeDifferenceEnd = timeDiff / oneDay;
}
var index = Math.floor(timeDifferenceStart);
while (index < timeDifferenceEnd - eps) {
dates[index].hasEvent = true;
var eventSet = dates[index].events;
if (eventSet) {
eventSet.push(event_1);
}
else {
eventSet = [];
eventSet.push(event_1);
dates[index].events = eventSet;
}
index += 1;
}
}
for (var r = 0; r < 42; r += 1) {
if (dates[r].hasEvent) {
dates[r].events.sort(this.compareEvent);
}
}
if (this.autoSelect) {
var findSelected = false;
for (var r = 0; r < 42; r += 1) {
if (dates[r].selected) {
this.selectedDate = dates[r];
findSelected = true;
break;
}
}
if (findSelected) {
this.onTimeSelected.emit({
selectedTime: this.selectedDate.date,
events: this.selectedDate.events,
disabled: this.selectedDate.disabled
});
}
}
};
;
MonthViewComponent.prototype.refreshView = function () {
this.range = this.getRange(this.calendarService.currentDate);
if (this.inited) {
var title = this.getTitle();
this.onTitleChanged.emit(title);
}
this.calendarService.populateAdjacentViews(this);
this.updateCurrentView(this.range.startTime, this.views[this.currentViewIndex]);
this.calendarService.rangeChanged(this);
};
MonthViewComponent.prototype.getTitle = function () {
var currentViewStartDate = this.range.startTime, date = currentViewStartDate.getDate(), month = (currentViewStartDate.getMonth() + (date !== 1 ? 1 : 0)) % 12, year = currentViewStartDate.getFullYear() + (date !== 1 && month === 0 ? 1 : 0), headerDate = new Date(year, month, 1, 12, 0, 0, 0);
return this.formatTitle(headerDate);
};
MonthViewComponent.prototype.compareEvent = function (event1, event2) {
if (event1.allDay) {
return 1;
}
else if (event2.allDay) {
return -1;
}
else {
return (event1.startTime.getTime() - event2.startTime.getTime());
}
};
MonthViewComponent.prototype.select = function (viewDate) {
if (!this.views)
return;
var selectedDate = viewDate.date, events = viewDate.events;
if (!viewDate.disabled) {
var dates = this.views[this.currentViewIndex].dates, currentCalendarDate = this.calendarService.currentDate, currentMonth = currentCalendarDate.getMonth(), currentYear = currentCalendarDate.getFullYear(), selectedMonth = selectedDate.getMonth(), selectedYear = selectedDate.getFullYear(), direction = 0;
if (currentYear === selectedYear) {
if (currentMonth !== selectedMonth) {
direction = currentMonth < selectedMonth ? 1 : -1;
}
}
else {
direction = currentYear < selectedYear ? 1 : -1;
}
this.calendarService.setCurrentDate(selectedDate);
if (direction === 0) {
var currentViewStartDate = this.range.startTime, oneDay = 86400000, selectedDayDifference = Math.floor((selectedDate.getTime() - currentViewStartDate.getTime() - (selectedDate.getTimezoneOffset() - currentViewStartDate.getTimezoneOffset()) * 60000) / oneDay);
for (var r = 0; r < 42; r += 1) {
dates[r].selected = false;
}
if (selectedDayDifference >= 0 && selectedDayDifference < 42) {
dates[selectedDayDifference].selected = true;
this.selectedDate = dates[selectedDayDifference];
}
}
else {
this.moveOnSelected = true;
this.slideView(direction);
}
}
this.onTimeSelected.emit({ selectedTime: selectedDate, events: events, disabled: viewDate.disabled });
};
MonthViewComponent.prototype.slideView = function (direction) {
if (direction === 1) {
this.slider.slideNext();
}
else if (direction === -1) {
this.slider.slidePrev();
}
};
MonthViewComponent.prototype.updateCurrentView = function (currentViewStartDate, view) {
var currentCalendarDate = this.calendarService.currentDate, today = new Date(), oneDay = 86400000, selectedDayDifference = Math.floor((currentCalendarDate.getTime() - currentViewStartDate.getTime() - (currentCalendarDate.getTimezoneOffset() - currentViewStartDate.getTimezoneOffset()) * 60000) / oneDay), currentDayDifference = Math.floor((today.getTime() - currentViewStartDate.getTime() - (today.getTimezoneOffset() - currentViewStartDate.getTimezoneOffset()) * 60000) / oneDay);
for (var r = 0; r < 42; r += 1) {
view.dates[r].selected = false;
}
if (selectedDayDifference >= 0 && selectedDayDifference < 42 && !view.dates[selectedDayDifference].disabled && (this.autoSelect || this.moveOnSelected)) {
view.dates[selectedDayDifference].selected = true;
this.selectedDate = view.dates[selectedDayDifference];
}
else {
this.selectedDate = {
date: null,
events: [],
label: null,
secondary: null,
disabled: false
};
}
if (currentDayDifference >= 0 && currentDayDifference < 42) {
view.dates[currentDayDifference].current = true;
}
};
MonthViewComponent.prototype.eventSelected = function (event) {
this.onEventSelected.emit(event);
};
return MonthViewComponent;
}());
MonthViewComponent.decorators = [
{ type: core_1.Component, args: [{
selector: 'monthview',
template: "\n <div>\n <ion-slides #monthSlider [loop]=\"true\" [dir]=\"dir\" [spaceBetween]=\"spaceBetween\" (ionSlideDidChange)=\"onSlideChanged()\">\n <ion-slide>\n <table *ngIf=\"0===currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr>\n <th *ngFor=\"let dayHeader of views[0].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\" tappable (click)=\"select(views[0].dates[row*7+col])\"\n [ngClass]=\"getHighlightClass(views[0].dates[row*7+col])\">\n <ng-template [ngTemplateOutlet]=\"monthviewDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[0], row: row, col: col}\">\n </ng-template>\n </td>\n </tr>\n </tbody>\n </table>\n <table *ngIf=\"0!==currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr class=\"text-center\">\n <th *ngFor=\"let dayHeader of views[0].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\">\n <ng-template [ngTemplateOutlet]=\"monthviewInactiveDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[0], row: row, col: col}\">\n </ng-template>\n </td>\n <tr>\n </tbody>\n </table>\n </ion-slide>\n <ion-slide>\n <table *ngIf=\"1===currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr>\n <th *ngFor=\"let dayHeader of views[1].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\" tappable (click)=\"select(views[1].dates[row*7+col])\"\n [ngClass]=\"getHighlightClass(views[1].dates[row*7+col])\">\n <ng-template [ngTemplateOutlet]=\"monthviewDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[1], row: row, col: col}\">\n </ng-template>\n </td>\n </tr>\n </tbody>\n </table>\n <table *ngIf=\"1!==currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr class=\"text-center\">\n <th *ngFor=\"let dayHeader of views[1].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\">\n <ng-template [ngTemplateOutlet]=\"monthviewInactiveDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[1], row: row, col: col}\">\n </ng-template>\n </td>\n <tr>\n </tbody>\n </table>\n </ion-slide>\n <ion-slide>\n <table *ngIf=\"2===currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr>\n <th *ngFor=\"let dayHeader of views[2].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\" tappable (click)=\"select(views[2].dates[row*7+col])\"\n [ngClass]=\"getHighlightClass(views[2].dates[row*7+col])\">\n <ng-template [ngTemplateOutlet]=\"monthviewDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[2], row: row, col: col}\">\n </ng-template>\n </td>\n </tr>\n </tbody>\n </table>\n <table *ngIf=\"2!==currentViewIndex\" class=\"table table-bordered table-fixed monthview-datetable\">\n <thead>\n <tr class=\"text-center\">\n <th *ngFor=\"let dayHeader of views[2].dayHeaders\">\n <small>{{dayHeader}}</small>\n </th>\n </tr>\n </thead>\n <tbody>\n <tr *ngFor=\"let row of [0,1,2,3,4,5]\">\n <td *ngFor=\"let col of [0,1,2,3,4,5,6]\">\n <ng-template [ngTemplateOutlet]=\"monthviewInactiveDisplayEventTemplate\"\n [ngTemplateOutletContext]=\"{view: views[2], row: row, col: col}\">\n </ng-template>\n </td>\n <tr>\n </tbody>\n </table>\n </ion-slide>\n </ion-slides>\n <ng-template [ngTemplateOutlet]=\"monthviewEventDetailTemplate\"\n [ngTemplateOutletContext]=\"{showEventDetail:showEventDetail, selectedDate: selectedDate, noEventsLabel: noEventsLabel}\">\n </ng-template>\n </div>\n ",
styles: ["\n .text-muted {\n color: #999;\n }\n\n .table-fixed {\n table-layout: fixed;\n }\n\n .table {\n width: 100%;\n max-width: 100%;\n background-color: transparent;\n }\n\n .table > thead > tr > th, .table > tbody > tr > th, .table > tfoot > tr > th, .table > thead > tr > td,\n .table > tbody > tr > td, .table > tfoot > tr > td {\n padding: 8px;\n line-height: 20px;\n vertical-align: top;\n }\n\n .table > thead > tr > th {\n vertical-align: bottom;\n border-bottom: 2px solid #ddd;\n }\n\n .table > thead:first-child > tr:first-child > th, .table > thead:first-child > tr:first-child > td {\n border-top: 0\n }\n\n .table > tbody + tbody {\n border-top: 2px solid #ddd;\n }\n\n .table-bordered {\n border: 1px solid #ddd;\n }\n\n .table-bordered > thead > tr > th, .table-bordered > tbody > tr > th, .table-bordered > tfoot > tr > th,\n .table-bordered > thead > tr > td, .table-bordered > tbody > tr > td, .table-bordered > tfoot > tr > td {\n border: 1px solid #ddd;\n }\n\n .table-bordered > thead > tr > th, .table-bordered > thead > tr > td {\n border-bottom-width: 2px;\n }\n\n .table-striped > tbody > tr:nth-child(odd) > td, .table-striped > tbody > tr:nth-child(odd) > th {\n background-color: #f9f9f9\n }\n\n .monthview-primary-with-event {\n background-color: #3a87ad;\n color: white;\n }\n\n .monthview-current {\n background-color: #f0f0f0;\n }\n\n .monthview-selected {\n background-color: #009900;\n color: white;\n }\n\n .monthview-datetable td.monthview-disabled {\n color: lightgrey;\n cursor: default;\n }\n\n .monthview-datetable th {\n text-align: center;\n }\n\n .monthview-datetable td {\n cursor: pointer;\n text-align: center;\n }\n\n .monthview-secondary-with-event {\n background-color: #d9edf7;\n }\n\n ::-webkit-scrollbar,\n *::-webkit-scrollbar {\n display: none;\n }\n "]
},] },
];
MonthViewComponent.ctorParameters = function () { return [
{ type: calendar_service_1.CalendarService, },
]; };
MonthViewComponent.propDecorators = {
'slider': [{ type: core_1.ViewChild, args: ['monthSlider',] },],
'monthviewDisplayEventTemplate': [{ type: core_1.Input },],
'monthviewInactiveDisplayEventTemplate': [{ type: core_1.Input },],
'monthviewEventDetailTemplate': [{ type: core_1.Input },],
'formatDay': [{ type: core_1.Input },],
'formatDayHeader': [{ type: core_1.Input },],
'formatMonthTitle': [{ type: core_1.Input },],
'eventSource': [{ type: core_1.Input },],
'startingDayMonth': [{ type: core_1.Input },],
'showEventDetail': [{ type: core_1.Input },],
'noEventsLabel': [{ type: core_1.Input },],
'autoSelect': [{ type: core_1.Input },],
'markDisabled': [{ type: core_1.Input },],
'locale': [{ type: core_1.Input },],
'dateFormatter': [{ type: core_1.Input },],
'dir': [{ type: core_1.Input },],
'lockSwipeToPrev': [{ type: core_1.Input },],
'lockSwipes': [{ type: core_1.Input },],
'spaceBetween': [{ type: core_1.Input },],
'onRangeChanged': [{ type: core_1.Output },],
'onEventSelected': [{ type: core_1.Output },],
'onTimeSelected': [{ type: core_1.Output },],
'onTitleChanged': [{ type: core_1.Output },],
};
exports.MonthViewComponent = MonthViewComponent;
//# sourceMappingURL=monthview.js.map