From 12ae5a302eb65c3aa2f414fcd7d75122957b64e0 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Mon, 8 May 2017 08:39:16 +0800 Subject: [PATCH 01/23] upgrade to Ionic3 and Angular4 --- package.json | 35 ++++++++++++++++------------------- src/calendar.module.ts | 3 ++- src/calendar.ts | 16 ++++++++-------- src/dayview.ts | 24 ++++++++++++------------ src/monthview.ts | 28 ++++++++++++++-------------- src/weekview.ts | 24 ++++++++++++------------ tsconfig.json | 9 ++++++--- typings.json | 2 +- 8 files changed, 71 insertions(+), 70 deletions(-) diff --git a/package.json b/package.json index 878e14fa..62a00d50 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.2.5", + "version": "0.3.0", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", @@ -15,31 +15,28 @@ "url": "git+https://github.com/twinssbc/Ionic2-Calendar.git" }, "scripts": { - "build": "rm -rf dist && tsc && npm run copy_package", + "build": "rm -rf dist && tsc && cp package.json dist/package.json", "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json && node_modules/.bin/ngc src && mv src/*ngfactory.ts aot && rm -r aot/waste", "copy_static_files": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings dist/", "copy_static_files_prod": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings aot/", - "dev": "tsc --watch", - "postinstall": "typings install" + "dev": "tsc --watch" }, "main": "./index.js", "dependencies": {}, "devDependencies": { - "tslint-ionic-rules": "0.0.5", - "typescript": "2.0.3", - "typings": "1.3.1", - "@angular/common": "2.2.1", - "@angular/compiler": "2.2.1", - "@angular/compiler-cli": "2.2.1", - "@angular/core": "2.2.1", - "@angular/forms": "2.2.1", - "@angular/http": "2.2.1", - "@angular/platform-browser": "2.2.1", - "@angular/platform-browser-dynamic": "2.2.1", - "@angular/platform-server": "2.2.1", - "ionic-angular": "2.1.0", - "rxjs": "5.0.0-beta.12", - "zone.js": "0.6.26", + "tslint-ionic-rules": "0.0.8", + "typescript": "~2.2.1", + "@angular/common": "4.0.2", + "@angular/compiler": "4.0.2", + "@angular/compiler-cli": "4.0.2", + "@angular/core": "4.0.2", + "@angular/forms": "4.0.2", + "@angular/http": "4.0.2", + "@angular/platform-browser": "4.0.2", + "@angular/platform-browser-dynamic": "4.0.2", + "ionic-angular": "3.1.1", + "rxjs": "5.1.1", + "zone.js": "^0.8.5", "intl": "^1.2.5" } } diff --git a/src/calendar.module.ts b/src/calendar.module.ts index c79d8163..461b99d6 100644 --- a/src/calendar.module.ts +++ b/src/calendar.module.ts @@ -1,4 +1,5 @@ import { NgModule } from '@angular/core'; +import { BrowserModule } from '@angular/platform-browser'; import { IonicModule } from 'ionic-angular'; import 'intl'; import 'intl/locale-data/jsonp/en'; @@ -12,7 +13,7 @@ import { CalendarService } from './calendar.service'; declarations: [ MonthViewComponent, WeekViewComponent, DayViewComponent, CalendarComponent ], - imports: [IonicModule], + imports: [BrowserModule, IonicModule], exports: [CalendarComponent], entryComponents: [CalendarComponent] }) diff --git a/src/calendar.ts b/src/calendar.ts index 382094cd..cbe99cb0 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -117,10 +117,10 @@ export enum Step { @Component({ selector: 'calendar', template: ` - - - - +
- +
@@ -50,9 +50,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -87,9 +87,9 @@ import { IDisplayAllDayEvent } from "./calendar"; class="calendar-event" tappable (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*eventIndex+'px',width: '100%',height:'25px'}"> - + @@ -112,9 +112,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -149,9 +149,9 @@ import { IDisplayAllDayEvent } from "./calendar"; class="calendar-event" tappable (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*eventIndex+'px',width: '100%',height:'25px'}"> - + @@ -174,9 +174,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
diff --git a/src/monthview.ts b/src/monthview.ts index 45f6c54f..2d26a5b9 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -25,9 +25,9 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + @@ -43,9 +43,9 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + @@ -64,9 +64,9 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + @@ -82,9 +82,9 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + @@ -103,9 +103,9 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + @@ -121,18 +121,18 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; - + - + `, styles: [` diff --git a/src/weekview.ts b/src/weekview.ts index 1386537d..b471174f 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -34,9 +34,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -57,9 +57,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -120,9 +120,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -143,9 +143,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -206,9 +206,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
@@ -229,9 +229,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- +
diff --git a/tsconfig.json b/tsconfig.json index 135dfa3f..b49de44b 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -9,7 +9,11 @@ "outDir": "dist", "removeComments": true, "sourceMap": true, - "target": "es5" + "target": "es5", + "lib": [ + "dom", + "es2015" + ] }, "files": [ "src/calendar.ts", @@ -18,8 +22,7 @@ "src/calendar.module.ts", "src/monthview.ts", "src/weekview.ts", - "src/dayview.ts", - "typings/globals/es6-shim/index.d.ts" + "src/dayview.ts" ], "exclude": [ "node_modules" diff --git a/typings.json b/typings.json index dd20a26d..4499dc24 100644 --- a/typings.json +++ b/typings.json @@ -2,4 +2,4 @@ "globalDependencies": { "es6-shim": "github:DefinitelyTyped/DefinitelyTyped/es6-shim/es6-shim.d.ts#6697d6f7dadbf5773cb40ecda35a76027e0783b2" } -} \ No newline at end of file +} From aab955473a32fca36d551389136d849674be197c Mon Sep 17 00:00:00 2001 From: twinssbc Date: Tue, 9 May 2017 08:31:02 +0800 Subject: [PATCH 02/23] remove dependency on BrowserModule --- README.md | 2 +- package.json | 4 ++-- src/calendar.module.ts | 3 +-- 3 files changed, 4 insertions(+), 5 deletions(-) diff --git a/README.md b/README.md index fc6023a0..255c3fd6 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ intl 1.2.5, due to issue https://github.com/angular/angular/issues/3333 version 0.1.x depends on Ionic 2.0.0-rc.1 ~ Ionic 2.0.0-rc.4 version 0.2.x depends on Ionic 2.0.0-rc.5 (rc.5 has breaking change on the slide API) and 2.0.0 final version onwards. - +version 0.3.x depends on Ionic 3.1.1 version onwards. # Usage diff --git a/package.json b/package.json index 62a00d50..cc0279dc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.0", + "version": "0.3.1", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", @@ -16,7 +16,7 @@ }, "scripts": { "build": "rm -rf dist && tsc && cp package.json dist/package.json", - "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json && node_modules/.bin/ngc src && mv src/*ngfactory.ts aot && rm -r aot/waste", + "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json && node_modules/.bin/ngc src && mv src/*ngfactory.ts aot && rm -r aot/waste && rm -r src/*.ngsummary.json", "copy_static_files": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings dist/", "copy_static_files_prod": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings aot/", "dev": "tsc --watch" diff --git a/src/calendar.module.ts b/src/calendar.module.ts index 461b99d6..c79d8163 100644 --- a/src/calendar.module.ts +++ b/src/calendar.module.ts @@ -1,5 +1,4 @@ import { NgModule } from '@angular/core'; -import { BrowserModule } from '@angular/platform-browser'; import { IonicModule } from 'ionic-angular'; import 'intl'; import 'intl/locale-data/jsonp/en'; @@ -13,7 +12,7 @@ import { CalendarService } from './calendar.service'; declarations: [ MonthViewComponent, WeekViewComponent, DayViewComponent, CalendarComponent ], - imports: [BrowserModule, IonicModule], + imports: [IonicModule], exports: [CalendarComponent], entryComponents: [CalendarComponent] }) From 45baf236e8c10c0cdd44121eaa9aaf598346a7f7 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Thu, 18 May 2017 22:04:04 +0800 Subject: [PATCH 03/23] add custom dateFormatter; optimize the hour column formatting logic; --- README.md | 52 +++++++++++++++++++++++++++++++++++ package.json | 2 +- src/calendar.ts | 15 ++++++++++ src/dayview.ts | 64 ++++++++++++++++++++++++++++++++----------- src/monthview.ts | 43 +++++++++++++++++++++++++---- src/weekview.ts | 71 ++++++++++++++++++++++++++++++++++++++---------- 6 files changed, 209 insertions(+), 38 deletions(-) diff --git a/README.md b/README.md index 255c3fd6..593ced13 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ version 0.1.x depends on Ionic 2.0.0-rc.1 ~ Ionic 2.0.0-rc.4 version 0.2.x depends on Ionic 2.0.0-rc.5 (rc.5 has breaking change on the slide API) and 2.0.0 final version onwards. version 0.3.x depends on Ionic 3.1.1 version onwards. + # Usage Install: `npm install ionic2-calendar --save` @@ -139,6 +140,42 @@ The callback function used to determine if the time should be marked as disabled return date < current; }; +* dateFormatter +The custom date formatter to transform date to text. +If the custom date formatter is not set, the default Angular DatePipe is used. +The format method in dateFormatter is optional, if omitted, the default Angular DatePipe is used. + + + + calendar = { + dateFormatter: { + formatMonthViewDay: function(date:Date) { + return date.getDate().toString(); + }, + formatMonthViewDayHeader: function(date:Date) { + return ‘testMDH’; + }, + formatMonthViewTitle: function(date:Date) { + return 'testMT'; + }, + formatWeekViewDayHeader: function(date:Date) { + return ‘testWDH’; + }, + formatWeekViewTitle: function(date:Date) { + return 'testWT’; + }, + formatWeekViewHourColumn: function(date:Date) { + return 'testWH’; + }, + formatDayViewHourColumn: function(date:Date) { + return 'testDH’; + }, + formatDayViewTitle: function(date:Date) { + return 'testDT’; + } + } + }; + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. @@ -297,6 +334,21 @@ import { NgModule, LOCALE_ID } from '@angular/core'; }) ``` +# Performance Tuning +In the CPU profile, the default Intl based localization code occupies a big portion of the execution time. If you don’t need localization on certain parts, you can use the custom dateFormatter to override the date transform method. For example, the date in month view usually doesn’t require localization, you could use below code to just display the date part. If the month view day header doesn’t need to include the date, you could also use a string array containing static labels to save the date calculation. + +``` + + +calendar = { + dateFormatter: { + formatMonthViewDay: function(date:Date) { + return date.getDate().toString(); + } + } +}; +``` + # Known issue This component updates the ion-slide dynamically so that only 3 looped slides are needed. The ion-slide in Ionic2 uses Swiper. It seems in the Swiper implementation, the next slide after the end of looped slide is a separate cached slide, instead of the first slide. diff --git a/package.json b/package.json index cc0279dc..84d6fc22 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.1", + "version": "0.3.2", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index cbe99cb0..68b22393 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -104,6 +104,17 @@ export interface IMonthViewEventDetailTemplateContext { noEventsLabel: string } +export interface IDateFormatter { + formatMonthViewDay?: { (date:Date): string; }; + formatMonthViewDayHeader?: { (date:Date): string; }; + formatMonthViewTitle?: { (date:Date): string; }; + formatWeekViewDayHeader?: { (date:Date): string; }; + formatWeekViewTitle?: { (date:Date): string; }; + formatWeekViewHourColumn?: { (date:Date): string; }; + formatDayViewTitle?: { (date:Date): string; }; + formatDayViewHourColumn?: { (date:Date): string; }; +} + export type CalendarMode = 'day' | 'month' | 'week'; export type QueryMode = 'local' | 'remote'; @@ -157,6 +168,7 @@ export enum Step { [monthviewInactiveDisplayEventTemplate]="monthviewInactiveDisplayEventTemplate||monthviewDefaultDisplayEventTemplate" [monthviewEventDetailTemplate]="monthviewEventDetailTemplate||monthviewDefaultEventDetailTemplate" [locale]="locale" + [dateFormatter]="dateFormatter" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -174,6 +186,7 @@ export enum Step { [weekviewAllDayEventTemplate]="weekviewAllDayEventTemplate||defaultAllDayEventTemplate" [weekviewNormalEventTemplate]="weekviewNormalEventTemplate||defaultNormalEventTemplate" [locale]="locale" + [dateFormatter]="dateFormatter" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -189,6 +202,7 @@ export enum Step { [dayviewAllDayEventTemplate]="dayviewAllDayEventTemplate||defaultAllDayEventTemplate" [dayviewNormalEventTemplate]="dayviewNormalEventTemplate||defaultNormalEventTemplate" [locale]="locale" + [dateFormatter]="dateFormatter" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -279,6 +293,7 @@ export class CalendarComponent implements OnInit { @Input() weekviewNormalEventTemplate:TemplateRef; @Input() dayviewAllDayEventTemplate:TemplateRef; @Input() dayviewNormalEventTemplate:TemplateRef; + @Input() dateFormatter:IDateFormatter; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index 01f4533e..9fed7649 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -3,7 +3,7 @@ import { Slides } from 'ionic-angular'; import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; -import { ICalendarComponent, IDayView, IDayViewRow, IDisplayEvent, IEvent, ITimeSelected, IRange, CalendarMode } from './calendar'; +import { ICalendarComponent, IDayView, IDayViewRow, IDisplayEvent, IEvent, ITimeSelected, IRange, CalendarMode, IDateFormatter } from './calendar'; import { CalendarService } from './calendar.service'; import { IDisplayAllDayEvent } from "./calendar"; @@ -41,9 +41,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - +
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -62,9 +62,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -103,9 +103,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
- +
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -124,9 +124,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -165,9 +165,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
- +
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -186,9 +186,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -372,6 +372,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() eventSource:IEvent[]; @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; + @Input() dateFormatter:IDateFormatter; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -391,12 +392,35 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private hourColumnLabels:string[]; + private formatTitle:(date:Date) => string; + private formatHourColumnLabel:(date:Date) => string; constructor(private calendarService:CalendarService) { } ngOnInit() { + if (this.dateFormatter && this.dateFormatter.formatDayViewTitle) { + this.formatTitle = this.dateFormatter.formatDayViewTitle; + } else { + var datePipe = new DatePipe(this.locale); + this.formatTitle = function (date:Date) { + return datePipe.transform(date, this.formatDayTitle); + }; + } + + if (this.dateFormatter && this.dateFormatter.formatDayViewHourColumn) { + this.formatHourColumnLabel = this.dateFormatter.formatDayViewHourColumn; + } else { + var datePipe = new DatePipe(this.locale); + this.formatHourColumnLabel = function (date:Date) { + return datePipe.transform(date, this.formatHourColumn); + }; + } + this.refreshView(); + this.hourColumnLabels = this.getHourColumnLabels(); + this.inited = true; this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(currentDate => { @@ -419,14 +443,14 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } ngOnDestroy() { - if(this.currentDateChangedFromParentSubscription) { + if (this.currentDateChangedFromParentSubscription) { this.currentDateChangedFromParentSubscription.unsubscribe(); this.currentDateChangedFromParentSubscription = null; } } onSlideChanged() { - if(this.callbackOnInit) { + if (this.callbackOnInit) { this.callbackOnInit = false; return; } @@ -479,6 +503,14 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { return rows; } + private getHourColumnLabels():string[] { + let hourColumnLabels:string[] = []; + for (let hour = 0, length = this.views[0].rows.length; hour < length; hour += 1) { + hourColumnLabels.push(this.formatHourColumnLabel(this.views[0].rows[hour].time)); + } + return hourColumnLabels; + } + getViewData(startTime:Date):IDayView { return { rows: DayViewComponent.createDateObjects(startTime), @@ -611,7 +643,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { getTitle():string { let startingDate = this.range.startTime; - return new DatePipe(this.locale).transform(startingDate, this.formatDayTitle); + return this.formatTitle(startingDate); } private static compareEventByStartOffset(eventA:IDisplayEvent, eventB:IDisplayEvent) { diff --git a/src/monthview.ts b/src/monthview.ts index 2d26a5b9..0fb4f119 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -3,7 +3,7 @@ import { Subscription } from 'rxjs/Subscription'; import { DatePipe } from '@angular/common'; import { Slides } from 'ionic-angular'; -import { ICalendarComponent, IEvent, IMonthView, IMonthViewRow, ITimeSelected, IRange, CalendarMode } from './calendar'; +import { ICalendarComponent, IEvent, IMonthView, IMonthViewRow, ITimeSelected, IRange, CalendarMode, IDateFormatter } from './calendar'; import { CalendarService } from './calendar.service'; import { IMonthViewDisplayEventTemplateContext } from "./calendar"; @@ -242,6 +242,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() autoSelect:boolean = true; @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; + @Input() dateFormatter:IDateFormatter; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -259,11 +260,41 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private formatDayLabel:(date:Date) => string; + private formatDayHeaderLabel:(date:Date) => string; + private formatTitle:(date:Date) => string; constructor(private calendarService:CalendarService) { } ngOnInit() { + if (this.dateFormatter && this.dateFormatter.formatMonthViewDay) { + this.formatDayLabel = this.dateFormatter.formatMonthViewDay; + } else { + var dayLabelDatePipe = new DatePipe('en-US'); + this.formatDayLabel = function (date:Date) { + return dayLabelDatePipe.transform(date, this.formatDay); + }; + } + + if (this.dateFormatter && this.dateFormatter.formatMonthViewDayHeader) { + this.formatDayHeaderLabel = this.dateFormatter.formatMonthViewDayHeader; + } else { + var datePipe = new DatePipe(this.locale); + this.formatDayHeaderLabel = function (date:Date) { + return datePipe.transform(date, this.formatDayHeader); + }; + } + + if (this.dateFormatter && this.dateFormatter.formatMonthViewTitle) { + this.formatTitle = this.dateFormatter.formatMonthViewTitle; + } else { + var datePipe = new DatePipe(this.locale); + this.formatTitle = function (date:Date) { + return datePipe.transform(date, this.formatMonthTitle); + }; + } + this.refreshView(); this.inited = true; @@ -332,7 +363,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges this.moveOnSelected = false; } - createDateObject(date:Date, format:string):IMonthViewRow { + createDateObject(date:Date):IMonthViewRow { var disabled = false; if (this.markDisabled) { disabled = this.markDisabled(date); @@ -341,7 +372,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges return { date: date, events: [], - label: new DatePipe('en-US').transform(date, format), + label: this.formatDayLabel(date), secondary: false, disabled: disabled }; @@ -367,14 +398,14 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges let dates = MonthViewComponent.getDates(startDate, 42); let days:IMonthViewRow[] = []; for (let i = 0; i < 42; i++) { - let dateObject = this.createDateObject(dates[i], this.formatDay); + let dateObject = this.createDateObject(dates[i]); dateObject.secondary = dates[i].getMonth() !== month; days[i] = dateObject; } let dayHeaders:string[] = []; for (let i = 0; i < 7; i++) { - dayHeaders.push(new DatePipe(this.locale).transform(days[i].date, this.formatDayHeader)); + dayHeaders.push(this.formatDayHeaderLabel(days[i].date)); } return { dates: days, @@ -573,7 +604,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges month = (currentViewStartDate.getMonth() + (date !== 1 ? 1 : 0)) % 12, year = currentViewStartDate.getFullYear() + (date !== 1 && month === 0 ? 1 : 0), headerDate = new Date(year, month, 1); - return new DatePipe(this.locale).transform(headerDate, this.formatMonthTitle); + return this.formatTitle(headerDate); } private compareEvent(event1:IEvent, event2:IEvent):number { diff --git a/src/weekview.ts b/src/weekview.ts index b471174f..7cf93fc7 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -3,7 +3,7 @@ import { Slides } from 'ionic-angular'; import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; -import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode } from './calendar'; +import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode, IDateFormatter } from './calendar'; import { CalendarService } from './calendar.service'; import { IDisplayAllDayEvent } from "./calendar"; @@ -48,9 +48,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- {{tm.time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
- +
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -85,9 +85,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -134,9 +134,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
- +
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -171,9 +171,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -220,9 +220,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
- +
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -257,9 +257,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -458,6 +458,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() eventSource:IEvent[]; @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; + @Input() dateFormatter:IDateFormatter; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -473,12 +474,44 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private hourColumnLabels:string[]; + private formatDayHeader:(date:Date) => string; + private formatTitle:(date:Date) => string; + private formatHourColumnLabel:(date:Date) => string; constructor(private calendarService:CalendarService) { } ngOnInit() { + if (this.dateFormatter && this.dateFormatter.formatWeekViewDayHeader) { + this.formatDayHeader = this.dateFormatter.formatWeekViewDayHeader; + } else { + var datePipe = new DatePipe(this.locale); + this.formatDayHeader = function (date:Date) { + return datePipe.transform(date, this.formatWeekViewDayHeader); + }; + } + + if (this.dateFormatter && this.dateFormatter.formatWeekViewTitle) { + this.formatTitle = this.dateFormatter.formatWeekViewTitle; + } else { + var datePipe = new DatePipe(this.locale); + this.formatTitle = function (date:Date) { + return datePipe.transform(date, this.formatWeekTitle); + }; + } + + if (this.dateFormatter && this.dateFormatter.formatWeekViewHourColumn) { + this.formatHourColumnLabel = this.dateFormatter.formatWeekViewHourColumn; + } else { + var datePipe = new DatePipe(this.locale); + this.formatHourColumnLabel = function (date:Date) { + return datePipe.transform(date, this.formatHourColumn); + }; + } + this.refreshView(); + this.hourColumnLabels = this.getHourColumnLabels(); this.inited = true; this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(currentDate => { @@ -580,11 +613,19 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges return dates; } + private getHourColumnLabels():string[] { + let hourColumnLabels:string[] = []; + for (let hour = 0, length = this.views[0].rows.length; hour < length; hour += 1) { + hourColumnLabels.push(this.formatHourColumnLabel(this.views[0].rows[hour][0].time)); + } + return hourColumnLabels; + } + getViewData(startTime:Date):IWeekView { let dates = WeekViewComponent.getDates(startTime, 7); let dayHeaders:string[] = []; for (let i = 0; i < 7; i++) { - dayHeaders.push(new DatePipe(this.locale).transform(dates[i].date, this.formatWeekViewDayHeader)); + dayHeaders.push(this.formatDayHeader(dates[i].date)); } return { @@ -793,7 +834,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges let firstDayOfWeek = this.range.startTime, weekFormat = '$n', weekNumberIndex = this.formatWeekTitle.indexOf(weekFormat), - title = new DatePipe(this.locale).transform(firstDayOfWeek, this.formatWeekTitle); + title = this.formatTitle(firstDayOfWeek); if (weekNumberIndex !== -1) { let weekNumber = String(WeekViewComponent.getISO8601WeekNumber(firstDayOfWeek)); From 043039253d5a60673accc3820083f75e1df5fa96 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Mon, 22 May 2017 00:01:32 +0800 Subject: [PATCH 04/23] add RTL support; --- README.md | 4 ++++ package.json | 2 +- src/calendar.ts | 4 ++++ src/dayview.ts | 24 +++++++++++++++++++++++- src/monthview.ts | 3 ++- src/weekview.ts | 28 +++++++++++++++++++++++++--- 6 files changed, 59 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index 593ced13..7c7ac935 100644 --- a/README.md +++ b/README.md @@ -176,6 +176,10 @@ The format method in dateFormatter is optional, if omitted, the default Angular } }; +* dir +If set to “rtl”, the calendar supports RTL language. This feature is only supported in Ionic 2.3.0 version onwards. +Default value: “” + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. diff --git a/package.json b/package.json index 84d6fc22..0f1d99e0 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.2", + "version": "0.3.3", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index 68b22393..581422ff 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -169,6 +169,7 @@ export enum Step { [monthviewEventDetailTemplate]="monthviewEventDetailTemplate||monthviewDefaultEventDetailTemplate" [locale]="locale" [dateFormatter]="dateFormatter" + [dir]="dir" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -187,6 +188,7 @@ export enum Step { [weekviewNormalEventTemplate]="weekviewNormalEventTemplate||defaultNormalEventTemplate" [locale]="locale" [dateFormatter]="dateFormatter" + [dir]="dir" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -203,6 +205,7 @@ export enum Step { [dayviewNormalEventTemplate]="dayviewNormalEventTemplate||defaultNormalEventTemplate" [locale]="locale" [dateFormatter]="dateFormatter" + [dir]="dir" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -294,6 +297,7 @@ export class CalendarComponent implements OnInit { @Input() dayviewAllDayEventTemplate:TemplateRef; @Input() dayviewNormalEventTemplate:TemplateRef; @Input() dateFormatter:IDateFormatter; + @Input() dir:string = ""; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index 9fed7649..5bf8cc5e 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -10,7 +10,7 @@ import { IDisplayAllDayEvent } from "./calendar"; @Component({ selector: 'dayview', template: ` - +
{{allDayLabel}}
@@ -278,12 +278,22 @@ import { IDisplayAllDayEvent } from "./calendar"; width: 50px; } + [dir="rtl"] .dayview-allday-label { + border-right: 1px solid #ddd; + float: right; + } + .dayview-allday-content-wrapper { margin-left: 50px; overflow: hidden; height: 51px; } + [dir="rtl"] .dayview-allday-content-wrapper { + margin-left: 0; + margin-right: 50px; + } + .dayview-allday-content-table { min-height: 50px; } @@ -354,6 +364,11 @@ import { IDisplayAllDayEvent } from "./calendar"; .dayview-allday-content-wrapper { margin-left: 31px; } + + [dir="rtl"] .dayview-allday-content-wrapper { + margin-left: 0; + margin-right: 31px; + } } `], encapsulation: ViewEncapsulation.None @@ -373,6 +388,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; @Input() dateFormatter:IDateFormatter; + @Input() dir:string = ""; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -713,6 +729,12 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { events[i].position = maxColumn++; } } + + if (this.dir === 'rtl') { + for (let i = 0; i < len; i += 1) { + events[i].position = maxColumn - 1 - events[i].position; + } + } } private static calculateWidth(orderedEvents:IDisplayEvent[]) { diff --git a/src/monthview.ts b/src/monthview.ts index 0fb4f119..9b778129 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -11,7 +11,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; selector: 'monthview', template: `
- +
- {{row[0].time | date: formatHourColumn}} + {{hourColumnLabels[i]}}
@@ -243,6 +243,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; @Input() dateFormatter:IDateFormatter; + @Input() dir:string = ""; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); diff --git a/src/weekview.ts b/src/weekview.ts index 7cf93fc7..125e57ef 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -10,7 +10,7 @@ import { IDisplayAllDayEvent } from "./calendar"; @Component({ selector: 'weekview', template: ` - +
@@ -350,12 +350,22 @@ import { IDisplayAllDayEvent } from "./calendar"; width: 50px; } + [dir="rtl"] .weekview-allday-label { + float: right; + border-right: 1px solid #ddd; + } + .weekview-allday-content-wrapper { margin-left: 50px; overflow: hidden; height: 51px; } + [dir="rtl"] .weekview-allday-content-wrapper { + margin-left: 0; + margin-right: 50px; + } + .weekview-allday-content-table { min-height: 50px; } @@ -438,6 +448,11 @@ import { IDisplayAllDayEvent } from "./calendar"; .weekview-allday-content-wrapper { margin-left: 31px; } + + [dir="rtl"] .weekview-allday-content-wrapper { + margin-left: 0; + margin-right: 31px; + } } `], encapsulation: ViewEncapsulation.None @@ -459,6 +474,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; @Input() dateFormatter:IDateFormatter; + @Input() dir:string = ""; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -534,14 +550,14 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } ngOnDestroy() { - if(this.currentDateChangedFromParentSubscription) { + if (this.currentDateChangedFromParentSubscription) { this.currentDateChangedFromParentSubscription.unsubscribe(); this.currentDateChangedFromParentSubscription = null; } } onSlideChanged() { - if(this.callbackOnInit) { + if (this.callbackOnInit) { this.callbackOnInit = false; return; } @@ -919,6 +935,12 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges events[i].position = maxColumn++; } } + + if (this.dir === 'rtl') { + for (let i = 0; i < len; i += 1) { + events[i].position = maxColumn - 1 - events[i].position; + } + } } private static calculateWidth(orderedEvents:IDisplayEvent[]) { From 5a2f711d98c5ece0ba73ffa4bf12444e00dea86c Mon Sep 17 00:00:00 2001 From: twinssbc Date: Thu, 1 Jun 2017 08:34:57 +0800 Subject: [PATCH 05/23] add scrolling feature --- README.md | 11 +++++++- demo/config.js | 6 ++-- demo/index.html | 2 +- demo/pages/home.ts | 28 ++++++++++++++++++- package.json | 2 +- src/calendar.module.ts | 3 +- src/calendar.ts | 6 ++++ src/dayview.ts | 55 +++++++++++++++++++++++-------------- src/init-position-scroll.ts | 55 +++++++++++++++++++++++++++++++++++++ src/weekview.ts | 43 +++++++++++++++++++---------- tsconfig.json | 3 +- 11 files changed, 171 insertions(+), 43 deletions(-) create mode 100644 src/init-position-scroll.ts diff --git a/README.md b/README.md index 7c7ac935..62b8b9c3 100644 --- a/README.md +++ b/README.md @@ -11,6 +11,7 @@ intl 1.2.5, due to issue https://github.com/angular/angular/issues/3333 version 0.1.x depends on Ionic 2.0.0-rc.1 ~ Ionic 2.0.0-rc.4 version 0.2.x depends on Ionic 2.0.0-rc.5 (rc.5 has breaking change on the slide API) and 2.0.0 final version onwards. +version 0.2.9+ depends on Ionic 2.3.0 version onwards. version 0.3.x depends on Ionic 3.1.1 version onwards. @@ -87,7 +88,7 @@ The format of the title displayed in the day view. Default value: 'MMMM dd, yyyy' * formatWeekTitle The format of the title displayed in the week view. -Default value: 'MMMM yyyy, Week w' +Default value: 'MMMM yyyy, Week $n’ * formatMonthTitle The format of the title displayed in the month view. Default value: 'MMMM yyyy' @@ -180,6 +181,14 @@ The format method in dateFormatter is optional, if omitted, the default Angular If set to “rtl”, the calendar supports RTL language. This feature is only supported in Ionic 2.3.0 version onwards. Default value: “” +* scrollToHour +Make weekview and dayview scroll to the specific hour after entering to the new view. +Default value: 0 + +* preserveScrollPosition +If set to true, the previous/next views in weekview and dayview will also scroll to the same position as the current active view. +Default value: false + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. diff --git a/demo/config.js b/demo/config.js index f38ef5ea..acf55906 100644 --- a/demo/config.js +++ b/demo/config.js @@ -1,13 +1,13 @@ (function (global) { - var ngVer = '@2.2.1'; // lock in the angular package version; do not let it float to current! + var ngVer = '@2.4.8'; // lock in the angular package version; do not let it float to current! //map tells the System loader where to look for things var map = { 'app': 'app', // 'dist', - 'rxjs': 'https://unpkg.com/rxjs@5.0.0-beta.12', + 'rxjs': 'https://unpkg.com/rxjs@5.0.1', 'angular2-in-memory-web-api': 'https://unpkg.com/angular2-in-memory-web-api', // get latest 'ionic2-calendar': '../src', - 'ionic-angular': 'https://unpkg.com/ionic-angular@2.1.0', + 'ionic-angular': 'https://unpkg.com/ionic-angular@2.3.0', 'pages': 'pages', 'intl': 'https://unpkg.com/intl@1.2.5' }; diff --git a/demo/index.html b/demo/index.html index aeb8ae51..668d55e2 100644 --- a/demo/index.html +++ b/demo/index.html @@ -14,7 +14,7 @@ - + diff --git a/demo/pages/home.ts b/demo/pages/home.ts index ad28e3aa..32426063 100644 --- a/demo/pages/home.ts +++ b/demo/pages/home.ts @@ -11,7 +11,33 @@ export class HomePage { isToday:boolean; calendar = { mode: 'month', - currentDate: new Date() + currentDate: new Date(), + dateFormatter: { + formatMonthViewDay: function(date:Date) { + return date.getDate().toString(); + }, + formatMonthViewDayHeader: function(date:Date) { + return 'MonMH'; + }, + formatMonthViewTitle: function(date:Date) { + return 'testMT'; + }, + formatWeekViewDayHeader: function(date:Date) { + return 'MonWH'; + }, + formatWeekViewTitle: function(date:Date) { + return 'testWT'; + }, + formatWeekViewHourColumn: function(date:Date) { + return 'testWH'; + }, + formatDayViewHourColumn: function(date:Date) { + return 'testDH'; + }, + formatDayViewTitle: function(date:Date) { + return 'testDT'; + } + } }; constructor(private navController:NavController) { diff --git a/package.json b/package.json index 0f1d99e0..e80de424 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.3", + "version": "0.3.4", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.module.ts b/src/calendar.module.ts index c79d8163..9f86099c 100644 --- a/src/calendar.module.ts +++ b/src/calendar.module.ts @@ -7,10 +7,11 @@ import { WeekViewComponent } from './weekview'; import { DayViewComponent } from './dayview'; import {CalendarComponent} from './calendar'; import { CalendarService } from './calendar.service'; +import { initPositionScrollComponent } from './init-position-scroll'; @NgModule({ declarations: [ - MonthViewComponent, WeekViewComponent, DayViewComponent, CalendarComponent + MonthViewComponent, WeekViewComponent, DayViewComponent, CalendarComponent, initPositionScrollComponent ], imports: [IonicModule], exports: [CalendarComponent], diff --git a/src/calendar.ts b/src/calendar.ts index 581422ff..883b20ca 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -189,6 +189,8 @@ export enum Step { [locale]="locale" [dateFormatter]="dateFormatter" [dir]="dir" + [scrollToHour]="scrollToHour" + [preserveScrollPosition]="preserveScrollPosition" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -206,6 +208,8 @@ export enum Step { [locale]="locale" [dateFormatter]="dateFormatter" [dir]="dir" + [scrollToHour]="scrollToHour" + [preserveScrollPosition]="preserveScrollPosition" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -298,6 +302,8 @@ export class CalendarComponent implements OnInit { @Input() dayviewNormalEventTemplate:TemplateRef; @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; + @Input() scrollToHour:number = 0; + @Input() preserveScrollPosition:boolean = false; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index 5bf8cc5e..b9ce887a 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -1,6 +1,6 @@ import { DatePipe } from '@angular/common'; import { Slides } from 'ionic-angular'; -import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef } from '@angular/core'; +import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef, ElementRef } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { ICalendarComponent, IDayView, IDayViewRow, IDisplayEvent, IEvent, ITimeSelected, IRange, CalendarMode, IDateFormatter } from './calendar'; @@ -37,9 +37,8 @@ import { IDisplayAllDayEvent } from "./calendar";
- - + +
@@ -59,8 +58,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- + + +
@@ -71,7 +71,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -99,9 +99,8 @@ import { IDisplayAllDayEvent } from "./calendar";
- - + +
@@ -121,8 +120,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- + + +
@@ -133,7 +133,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -161,9 +161,8 @@ import { IDisplayAllDayEvent } from "./calendar";
- - + +
@@ -183,8 +182,9 @@ import { IDisplayAllDayEvent } from "./calendar";
- + + +
@@ -195,7 +195,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+ `, @@ -389,6 +389,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() locale:string; @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; + @Input() scrollToHour:number = 0; + @Input() preserveScrollPosition:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -409,10 +411,11 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; private hourColumnLabels:string[]; + private initScrollPosition:number; private formatTitle:(date:Date) => string; private formatHourColumnLabel:(date:Date) => string; - constructor(private calendarService:CalendarService) { + constructor(private calendarService:CalendarService, private elm:ElementRef) { } ngOnInit() { @@ -447,6 +450,14 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { ngAfterViewInit() { let title = this.getTitle(); this.onTitleChanged.emit(title); + + if (this.scrollToHour > 0) { + let hourColumns = this.elm.nativeElement.querySelector('.dayview-normal-event-container').querySelectorAll('.calendar-hour-column'); + var me = this; + setTimeout(function () { + me.initScrollPosition = hourColumns[me.scrollToHour].offsetTop; + }, 0); + } } ngOnChanges(changes:SimpleChanges) { @@ -794,4 +805,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { eventSelected(event:IEvent) { this.onEventSelected.emit(event); } + + setScrollPosition(scrollPosition:number) { + this.initScrollPosition = scrollPosition; + } } diff --git a/src/init-position-scroll.ts b/src/init-position-scroll.ts new file mode 100644 index 00000000..ede4af10 --- /dev/null +++ b/src/init-position-scroll.ts @@ -0,0 +1,55 @@ +import { Scroll } from 'ionic-angular'; +import { Component, Input, Output, EventEmitter, ElementRef, SimpleChanges } from '@angular/core'; + +@Component({ + selector: 'init-position-scroll', + template: ` + + + + ` +}) +export class initPositionScrollComponent extends Scroll { + @Input() initPosition:number; + @Input() emitEvent:boolean; + @Output() onScroll = new EventEmitter(); + + private element:ElementRef; + private scrollContent:HTMLElement; + private handler:()=>void; + private listenerAttached:boolean = false; + + constructor(el:ElementRef) { + super(el); + this.element = el; + } + + ngOnChanges(changes:SimpleChanges) { + let initPosition = changes['initPosition']; + if (initPosition && initPosition.currentValue !== undefined && this.scrollContent) { + this.scrollContent.scrollTop = initPosition.currentValue; + } + } + + ngAfterViewInit() { + const scrollContent = this.scrollContent = this.element.nativeElement.querySelector('.scroll-content'); + if (this.initPosition !== undefined) { + scrollContent.scrollTop = this.initPosition; + } + + if (this.emitEvent && !this.listenerAttached) { + let onScroll = this.onScroll; + this.handler = function () { + onScroll.emit(scrollContent.scrollTop); + }; + this.listenerAttached = true; + scrollContent.addEventListener('scroll', this.handler); + } + } + + ngOnDestroy() { + if (this.listenerAttached) { + this.scrollContent.removeEventListener('scroll', this.handler); + } + } +} diff --git a/src/weekview.ts b/src/weekview.ts index 125e57ef..407b0d79 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -1,6 +1,6 @@ import { DatePipe } from '@angular/common'; import { Slides } from 'ionic-angular'; -import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef } from '@angular/core'; +import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef, ElementRef } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode, IDateFormatter } from './calendar'; @@ -45,7 +45,7 @@ import { IDisplayAllDayEvent } from "./calendar";
- + @@ -66,7 +66,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -82,7 +82,7 @@ import { IDisplayAllDayEvent } from "./calendar";
- + @@ -94,7 +94,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+ @@ -131,7 +131,7 @@ import { IDisplayAllDayEvent } from "./calendar";
- + @@ -152,7 +152,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -168,7 +168,7 @@ import { IDisplayAllDayEvent } from "./calendar";
- + @@ -180,7 +180,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+ @@ -217,7 +217,7 @@ import { IDisplayAllDayEvent } from "./calendar"; - + @@ -238,7 +238,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -254,7 +254,7 @@ import { IDisplayAllDayEvent } from "./calendar";
- + @@ -266,7 +266,7 @@ import { IDisplayAllDayEvent } from "./calendar";
-
+
@@ -475,6 +475,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() locale:string; @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; + @Input() scrollToHour:number = 0; + @Input() preserveScrollPosition:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -491,11 +493,12 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; private hourColumnLabels:string[]; + private initScrollPosition:number; private formatDayHeader:(date:Date) => string; private formatTitle:(date:Date) => string; private formatHourColumnLabel:(date:Date) => string; - constructor(private calendarService:CalendarService) { + constructor(private calendarService:CalendarService, private elm:ElementRef) { } ngOnInit() { @@ -538,6 +541,14 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges ngAfterViewInit() { let title = this.getTitle(); this.onTitleChanged.emit(title); + + if (this.scrollToHour > 0) { + let hourColumns = this.elm.nativeElement.querySelector('.weekview-normal-event-container').querySelectorAll('.calendar-hour-column'); + var me = this; + setTimeout(function () { + me.initScrollPosition = hourColumns[me.scrollToHour].offsetTop; + }, 0); + } } ngOnChanges(changes:SimpleChanges) { @@ -1000,4 +1011,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges eventSelected(event:IEvent) { this.onEventSelected.emit(event); } + + setScrollPosition(scrollPosition:number) { + this.initScrollPosition = scrollPosition; + } } diff --git a/tsconfig.json b/tsconfig.json index b49de44b..fa7760e4 100644 --- a/tsconfig.json +++ b/tsconfig.json @@ -22,7 +22,8 @@ "src/calendar.module.ts", "src/monthview.ts", "src/weekview.ts", - "src/dayview.ts" + "src/dayview.ts", + "src/init-position-scroll.ts" ], "exclude": [ "node_modules" From 24e1b674ca1375f3f3aa41e9159755e47dbf4882 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Thu, 8 Jun 2017 20:57:40 +0800 Subject: [PATCH 06/23] add lockSwipeToPrev option --- README.md | 21 +++++++++++++++++++++ package.json | 4 ++-- src/calendar.ts | 4 ++++ src/dayview.ts | 10 ++++++++++ src/monthview.ts | 10 ++++++++++ src/weekview.ts | 10 ++++++++++ 6 files changed, 57 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index 62b8b9c3..eba01ac7 100644 --- a/README.md +++ b/README.md @@ -189,6 +189,27 @@ Default value: 0 If set to true, the previous/next views in weekview and dayview will also scroll to the same position as the current active view. Default value: false +* lockSwipeToPrev +If set to true, swiping to previous view is disabled. +Default value: false + + + + onCurrentDateChanged(event:Date) { + var today = new Date(); + today.setHours(0, 0, 0, 0); + event.setHours(0, 0, 0, 0); + + if (this.calendar.mode === 'month') { + if (event.getFullYear() < today.getFullYear() || (event.getFullYear() === today.getFullYear() && event.getMonth() <= today.getMonth())) { + this.lockSwipeToPrev = true; + } else { + this.lockSwipeToPrev = false; + } + } + } + + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. diff --git a/package.json b/package.json index e80de424..375660c5 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.4", + "version": "0.3.5", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", @@ -18,7 +18,7 @@ "build": "rm -rf dist && tsc && cp package.json dist/package.json", "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json && node_modules/.bin/ngc src && mv src/*ngfactory.ts aot && rm -r aot/waste && rm -r src/*.ngsummary.json", "copy_static_files": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings dist/", - "copy_static_files_prod": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings aot/", + "copy_static_files_prod": "cp -r package.json README.md LICENSE tsconfig.json aot/", "dev": "tsc --watch" }, "main": "./index.js", diff --git a/src/calendar.ts b/src/calendar.ts index 883b20ca..da998faa 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -170,6 +170,7 @@ export enum Step { [locale]="locale" [dateFormatter]="dateFormatter" [dir]="dir" + [lockSwipeToPrev]="lockSwipeToPrev" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -191,6 +192,7 @@ export enum Step { [dir]="dir" [scrollToHour]="scrollToHour" [preserveScrollPosition]="preserveScrollPosition" + [lockSwipeToPrev]="lockSwipeToPrev" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -210,6 +212,7 @@ export enum Step { [dir]="dir" [scrollToHour]="scrollToHour" [preserveScrollPosition]="preserveScrollPosition" + [lockSwipeToPrev]="lockSwipeToPrev" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -304,6 +307,7 @@ export class CalendarComponent implements OnInit { @Input() dir:string = ""; @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean = false; + @Input() lockSwipeToPrev:boolean = false; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index b9ce887a..b24b6fea 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -391,6 +391,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() dir:string = ""; @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean; + @Input() lockSwipeToPrev:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -437,6 +438,10 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { }; } + if (this.lockSwipeToPrev) { + this.slider.lockSwipeToPrev(true); + } + this.refreshView(); this.hourColumnLabels = this.getHourColumnLabels(); @@ -467,6 +472,11 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (eventSourceChange && eventSourceChange.currentValue) { this.onDataLoaded(); } + + let lockSwipeToPrev = changes['lockSwipeToPrev']; + if (lockSwipeToPrev) { + this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); + } } ngOnDestroy() { diff --git a/src/monthview.ts b/src/monthview.ts index 9b778129..eb3843f5 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -244,6 +244,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() locale:string; @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; + @Input() lockSwipeToPrev:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -296,6 +297,10 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges }; } + if (this.lockSwipeToPrev) { + this.slider.lockSwipeToPrev(true); + } + this.refreshView(); this.inited = true; @@ -318,6 +323,11 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges if (eventSourceChange && eventSourceChange.currentValue) { this.onDataLoaded(); } + + let lockSwipeToPrev = changes['lockSwipeToPrev']; + if (lockSwipeToPrev) { + this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); + } } ngAfterViewInit() { diff --git a/src/weekview.ts b/src/weekview.ts index 407b0d79..0e034721 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -477,6 +477,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() dir:string = ""; @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean; + @Input() lockSwipeToPrev:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -529,6 +530,10 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges }; } + if (this.lockSwipeToPrev) { + this.slider.lockSwipeToPrev(true); + } + this.refreshView(); this.hourColumnLabels = this.getHourColumnLabels(); this.inited = true; @@ -558,6 +563,11 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (eventSourceChange && eventSourceChange.currentValue) { this.onDataLoaded(); } + + let lockSwipeToPrev = changes['lockSwipeToPrev']; + if (lockSwipeToPrev) { + this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); + } } ngOnDestroy() { From 65f52505cb70384fc0d7a8930c8566dee508c8d4 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 11 Jun 2017 23:55:09 +0800 Subject: [PATCH 07/23] add loadEvents instance method; --- README.md | 29 +++++++++++++++++++++++++++++ package.json | 2 +- src/calendar.service.ts | 9 ++++++++- src/calendar.ts | 4 ++++ src/dayview.ts | 10 ++++++++++ src/monthview.ts | 10 ++++++++++ src/weekview.ts | 10 ++++++++++ 7 files changed, 72 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index eba01ac7..a2231180 100644 --- a/README.md +++ b/README.md @@ -354,6 +354,35 @@ For example, if an allDay event ending to 2014-05-10, then endTime is * allDay Indicates the event is allDay event or regular event +**Note** The calendar only watches for the eventSource reference for performance consideration. That means only you manually reassign the eventSource value, the calendar gets notified, and this is usually fit to the scenario when the range is changed, you load a new data set from the backend. In case you want to manually insert/remove/update the element in the eventSource array, you can call instance method ‘loadEvents’ event to notify the calendar manually. + +# Instance Methods +* loadEvents +When this method is called, the calendar will be forced to reload the events in the eventSource array. This is only necessary when you directly modify the element in the eventSource array. + +``` +import { CalendarComponent } from "ionic2-calendar/calendar"; + +@Component({ + selector: 'page-home', + templateUrl: 'home.html' +}) +export class HomePage { + @ViewChild(CalendarComponent) myCalendar:CalendarComponent; + eventSource; + … + loadEvents: function() { + this.eventSource.push({ + title: ‘test’, + startTime: startTime, + endTime: endTime, + allDay: false + }); + this.myCalendar.loadEvents(); + } +} +``` + # Localization The DatePipe relies on LOCALE_ID to achieve localization. By default, the LOCALE_ID is **en-US**. You can override it in the module as below. If you pass **undefined**, the LOCALE_ID will be detected using the browser language setting. But using explicit value is recommended, as browser has different level of localization support. diff --git a/package.json b/package.json index 375660c5..cbea14c9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.5", + "version": "0.3.6", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.service.ts b/src/calendar.service.ts index 7be3e21a..17697f50 100644 --- a/src/calendar.service.ts +++ b/src/calendar.service.ts @@ -9,14 +9,17 @@ export class CalendarService { queryMode: QueryMode; currentDateChangedFromParent$: Observable; currentDateChangedFromChildren$: Observable; + eventSourceChanged$: Observable; private _currentDate: Date; private currentDateChangedFromParent = new Subject(); private currentDateChangedFromChildren = new Subject(); + private eventSourceChanged = new Subject(); constructor() { this.currentDateChangedFromParent$ = this.currentDateChangedFromParent.asObservable(); this.currentDateChangedFromChildren$ = this.currentDateChangedFromChildren.asObservable(); + this.eventSourceChanged$ = this.eventSourceChanged.asObservable(); } setCurrentDate(val: Date, fromParent: boolean = false) { @@ -86,7 +89,7 @@ export class CalendarService { getAdjacentViewStartTime(component: ICalendarComponent, direction: number): Date { let adjacentCalendarDate = this.getAdjacentCalendarDate(component.mode, direction); return component.getRange(adjacentCalendarDate).startTime; - }; + } populateAdjacentViews(component: ICalendarComponent) { let currentViewStartDate: Date, @@ -124,4 +127,8 @@ export class CalendarService { } } } + + loadEvents() { + this.eventSourceChanged.next(); + } } diff --git a/src/calendar.ts b/src/calendar.ts index da998faa..c37dc078 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -361,4 +361,8 @@ export class CalendarComponent implements OnInit { titleChanged(title:string) { this.onTitleChanged.emit(title); } + + loadEvents() { + this.calendarService.loadEvents(); + } } diff --git a/src/dayview.ts b/src/dayview.ts index b24b6fea..6bc9b1b9 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -411,6 +411,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private eventSourceChangedSubscription:Subscription; private hourColumnLabels:string[]; private initScrollPosition:number; private formatTitle:(date:Date) => string; @@ -450,6 +451,10 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(currentDate => { this.refreshView(); }); + + this.eventSourceChangedSubscription = this.calendarService.eventSourceChanged$.subscribe(() => { + this.onDataLoaded(); + }); } ngAfterViewInit() { @@ -484,6 +489,11 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { this.currentDateChangedFromParentSubscription.unsubscribe(); this.currentDateChangedFromParentSubscription = null; } + + if (this.eventSourceChangedSubscription) { + this.eventSourceChangedSubscription.unsubscribe(); + this.eventSourceChangedSubscription = null; + } } onSlideChanged() { diff --git a/src/monthview.ts b/src/monthview.ts index eb3843f5..6aeed275 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -262,6 +262,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private eventSourceChangedSubscription:Subscription; private formatDayLabel:(date:Date) => string; private formatDayHeaderLabel:(date:Date) => string; private formatTitle:(date:Date) => string; @@ -307,6 +308,10 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(currentDate => { this.refreshView(); }); + + this.eventSourceChangedSubscription = this.calendarService.eventSourceChanged$.subscribe(() => { + this.onDataLoaded(); + }); } ngOnDestroy() { @@ -314,6 +319,11 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges this.currentDateChangedFromParentSubscription.unsubscribe(); this.currentDateChangedFromParentSubscription = null; } + + if (this.eventSourceChangedSubscription) { + this.eventSourceChangedSubscription.unsubscribe(); + this.eventSourceChangedSubscription = null; + } } ngOnChanges(changes:SimpleChanges) { diff --git a/src/weekview.ts b/src/weekview.ts index 0e034721..e9e89918 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -493,6 +493,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges private inited = false; private callbackOnInit = true; private currentDateChangedFromParentSubscription:Subscription; + private eventSourceChangedSubscription:Subscription; private hourColumnLabels:string[]; private initScrollPosition:number; private formatDayHeader:(date:Date) => string; @@ -541,6 +542,10 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.currentDateChangedFromParentSubscription = this.calendarService.currentDateChangedFromParent$.subscribe(currentDate => { this.refreshView(); }); + + this.eventSourceChangedSubscription = this.calendarService.eventSourceChanged$.subscribe(() => { + this.onDataLoaded(); + }); } ngAfterViewInit() { @@ -575,6 +580,11 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.currentDateChangedFromParentSubscription.unsubscribe(); this.currentDateChangedFromParentSubscription = null; } + + if (this.eventSourceChangedSubscription) { + this.eventSourceChangedSubscription.unsubscribe(); + this.eventSourceChangedSubscription = null; + } } onSlideChanged() { From 11e396728f479d378dad910f6e6dcf28c4085f46 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Mon, 26 Jun 2017 23:02:21 +0800 Subject: [PATCH 08/23] add lockSwipes option --- README.md | 14 ++++++++++++++ package.json | 2 +- src/calendar.ts | 4 ++++ src/dayview.ts | 10 ++++++++++ src/monthview.ts | 10 ++++++++++ src/weekview.ts | 10 ++++++++++ 6 files changed, 49 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index a2231180..a0108d4f 100644 --- a/README.md +++ b/README.md @@ -209,6 +209,20 @@ Default value: false } } +* lockSwipes +If set to true, swiping is disabled. +Default value: false +*Note:* Since swiping is disabled, you could set currentDate to move the calendar to previous/next view. Do not set lockSwipeToPrev in the constructor phase. It will cause the view not updating when changing the currentDate. You could either set it in some callback function after initialization phase or use setTimeout to trigger some delay. + + + + ngAfterViewInit() { + var me = this; + setTimeout(function() { + me.lockSwipes = true; + },100); + } + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. diff --git a/package.json b/package.json index cbea14c9..532d5ffd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.6", + "version": "0.3.7", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index c37dc078..42cbd198 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -171,6 +171,7 @@ export enum Step { [dateFormatter]="dateFormatter" [dir]="dir" [lockSwipeToPrev]="lockSwipeToPrev" + [lockSwipes]="lockSwipes" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -193,6 +194,7 @@ export enum Step { [scrollToHour]="scrollToHour" [preserveScrollPosition]="preserveScrollPosition" [lockSwipeToPrev]="lockSwipeToPrev" + [lockSwipes]="lockSwipes" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -213,6 +215,7 @@ export enum Step { [scrollToHour]="scrollToHour" [preserveScrollPosition]="preserveScrollPosition" [lockSwipeToPrev]="lockSwipeToPrev" + [lockSwipes]="lockSwipes" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -308,6 +311,7 @@ export class CalendarComponent implements OnInit { @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean = false; @Input() lockSwipeToPrev:boolean = false; + @Input() lockSwipes:boolean = false; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index 6bc9b1b9..eb1cd67c 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -392,6 +392,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean; @Input() lockSwipeToPrev:boolean; + @Input() lockSwipes:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -443,6 +444,10 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { this.slider.lockSwipeToPrev(true); } + if (this.lockSwipes) { + this.slider.lockSwipes(true); + } + this.refreshView(); this.hourColumnLabels = this.getHourColumnLabels(); @@ -482,6 +487,11 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (lockSwipeToPrev) { this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); } + + let lockSwipes = changes['lockSwipes']; + if (lockSwipes) { + this.slider.lockSwipes(lockSwipes.currentValue); + } } ngOnDestroy() { diff --git a/src/monthview.ts b/src/monthview.ts index 6aeed275..f9776428 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -245,6 +245,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; @Input() lockSwipeToPrev:boolean; + @Input() lockSwipes:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -302,6 +303,10 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges this.slider.lockSwipeToPrev(true); } + if (this.lockSwipes) { + this.slider.lockSwipes(true); + } + this.refreshView(); this.inited = true; @@ -338,6 +343,11 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges if (lockSwipeToPrev) { this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); } + + let lockSwipes = changes['lockSwipes']; + if (lockSwipes) { + this.slider.lockSwipes(lockSwipes.currentValue); + } } ngAfterViewInit() { diff --git a/src/weekview.ts b/src/weekview.ts index e9e89918..51743787 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -478,6 +478,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() scrollToHour:number = 0; @Input() preserveScrollPosition:boolean; @Input() lockSwipeToPrev:boolean; + @Input() lockSwipes:boolean; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -535,6 +536,10 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.slider.lockSwipeToPrev(true); } + if (this.lockSwipes) { + this.slider.lockSwipes(true); + } + this.refreshView(); this.hourColumnLabels = this.getHourColumnLabels(); this.inited = true; @@ -573,6 +578,11 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (lockSwipeToPrev) { this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); } + + let lockSwipes = changes['lockSwipesv']; + if (lockSwipes) { + this.slider.lockSwipes(lockSwipes.currentValue); + } } ngOnDestroy() { From 60d7c8e75a5c58bb7b24108afff8fbe7f3d85faf Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 27 Aug 2017 22:45:16 +0800 Subject: [PATCH 09/23] fix duplicate allday event bug in dayview; --- package.json | 2 +- src/dayview.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/package.json b/package.json index 532d5ffd..a676aeab 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.7", + "version": "0.3.8", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/dayview.ts b/src/dayview.ts index eb1cd67c..47f4a99c 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -597,7 +597,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { utcEndTime = new Date(Date.UTC(endTime.getFullYear(), endTime.getMonth(), endTime.getDate())), currentViewIndex = this.currentViewIndex, rows = this.views[currentViewIndex].rows, - allDayEvents = this.views[currentViewIndex].allDayEvents, + allDayEvents:IDisplayAllDayEvent[] = this.views[currentViewIndex].allDayEvents = [], oneHour = 3600000, eps = 0.016, normalEventInRange = false; From ec62ee9c79b3da0d65ac375fed83f49c0188ccfe Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 27 Aug 2017 23:38:19 +0800 Subject: [PATCH 10/23] increase version due to invalid 0.3.8 version --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index a676aeab..d2ec8a12 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.8", + "version": "0.3.9", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", From 253d0e162c41d6af333924873eb70521e295d56f Mon Sep 17 00:00:00 2001 From: twinssbc Date: Tue, 19 Sep 2017 00:30:04 +0800 Subject: [PATCH 11/23] add locale option; --- README.md | 36 ++++++++++++++++++++++++++++++++++-- package.json | 2 +- src/calendar.ts | 4 +++- 3 files changed, 38 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index a0108d4f..06193201 100644 --- a/README.md +++ b/README.md @@ -44,6 +44,25 @@ import { NgCalendarModule } from 'ionic2-calendar'; export class AppModule {} ``` +If you are using PageModule, you need to import the NgCalendarModule in your page module +``` +import { NgCalendarModule } from 'ionic2-calendar'; + +@NgModule({ + declarations: [ + MyPage + ], + imports: [ + IonicPageModule.forChild(MyPage), + NgCalendarModule + ], + entryComponents: [ + MyPage + ] +}) +export class MyPageModule {} +``` + Add the directive in the html page ``` @@ -131,6 +150,16 @@ Default value: 60 * autoSelect If set to true, the current calendar date will be auto selected when calendar is loaded or swiped in the month view. Default value: true +* locale +The locale used to display text in the calendar. +Default value: undefined (which means the local language) + + + + calendar = { + locale: 'en-GB' + }; + * markDisabled The callback function used to determine if the time should be marked as disabled. @@ -398,8 +427,10 @@ export class HomePage { ``` # Localization -The DatePipe relies on LOCALE_ID to achieve localization. By default, the LOCALE_ID is **en-US**. You can override it in the module as below. If you pass **undefined**, the LOCALE_ID will be detected using the browser language setting. But using explicit value is recommended, as browser has different level of localization support. - +You could use *locale* option to achieve the localization. +If locale option is not specified, the calendar will use the LOCALE_ID set at the module level. +By default, the LOCALE_ID is **en-US**. You can override it in the module as below. If you pass **undefined**, the LOCALE_ID will be detected using the browser language setting. But using explicit value is recommended, as browser has different level of localization support. +Note that the event detail section in the month view doesn't support *locale* option, only LOCALE_ID takes effect. This is because it uses DatePipe in html directly. You could easily leverage customized event detail template to switch to other locale. ``` import { NgModule, LOCALE_ID } from '@angular/core'; @@ -410,6 +441,7 @@ import { NgModule, LOCALE_ID } from '@angular/core'; ] }) ``` +If you want to change the locale dynamically, you should use *locale* option instead of LOCALE_ID. # Performance Tuning In the CPU profile, the default Intl based localization code occupies a big portion of the execution time. If you don’t need localization on certain parts, you can use the custom dateFormatter to override the date transform method. For example, the date in month view usually doesn’t require localization, you could use below code to just display the date part. If the month view day header doesn’t need to include the date, you could also use a string array containing static labels to save the date calculation. diff --git a/package.json b/package.json index d2ec8a12..ff0f5e44 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.9", + "version": "0.3.10", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index 42cbd198..d749a5f6 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -312,6 +312,7 @@ export class CalendarComponent implements OnInit { @Input() preserveScrollPosition:boolean = false; @Input() lockSwipeToPrev:boolean = false; @Input() lockSwipes:boolean = false; + @Input() locale:string = ""; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); @@ -323,7 +324,8 @@ export class CalendarComponent implements OnInit { private hourParts = 1; private currentDateChangedFromChildrenSubscription:Subscription; - constructor(private calendarService:CalendarService, @Inject(LOCALE_ID) private locale:string) { + constructor(private calendarService:CalendarService, @Inject(LOCALE_ID) private appLocale:string) { + this.locale = appLocale; } ngOnInit() { From fcca9787c138a3b285207ddd450c5bcb8d8f70c8 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Thu, 26 Oct 2017 23:05:08 +0800 Subject: [PATCH 12/23] add startHour and endHour option; fix bug when placing events within one hour; --- README.md | 11 +++++++ package.json | 2 +- src/calendar.ts | 8 +++++ src/dayview.ts | 86 +++++++++++++++++++++++++++++++------------------ src/weekview.ts | 78 ++++++++++++++++++++++++++++---------------- 5 files changed, 126 insertions(+), 59 deletions(-) diff --git a/README.md b/README.md index 06193201..b3e09981 100644 --- a/README.md +++ b/README.md @@ -252,6 +252,17 @@ Default value: false },100); } +* startHour +Limit the weekview and dayview starts from which hour (0-23). +Default value: 0 + + + +* endHour +Limit the weekview and dayview ends until which hour (1-24). +Default value: 24 + + * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. diff --git a/package.json b/package.json index ff0f5e44..bbc345f1 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.10", + "version": "0.3.11", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index d749a5f6..0efe08cf 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -195,6 +195,8 @@ export enum Step { [preserveScrollPosition]="preserveScrollPosition" [lockSwipeToPrev]="lockSwipeToPrev" [lockSwipes]="lockSwipes" + [startHour]="startHour" + [endHour]="endHour" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -216,6 +218,8 @@ export enum Step { [preserveScrollPosition]="preserveScrollPosition" [lockSwipeToPrev]="lockSwipeToPrev" [lockSwipes]="lockSwipes" + [startHour]="startHour" + [endHour]="endHour" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -313,6 +317,8 @@ export class CalendarComponent implements OnInit { @Input() lockSwipeToPrev:boolean = false; @Input() lockSwipes:boolean = false; @Input() locale:string = ""; + @Input() startHour:number = 0; + @Input() endHour:number = 24; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); @@ -337,6 +343,8 @@ export class CalendarComponent implements OnInit { } } this.hourParts = 60 / this.step; + this.startHour = parseInt(this.startHour.toString()); + this.endHour = parseInt(this.endHour.toString()); this.calendarService.queryMode = this.queryMode; this.currentDateChangedFromChildrenSubscription = this.calendarService.currentDateChangedFromChildren$.subscribe(currentDate => { diff --git a/src/dayview.ts b/src/dayview.ts index 47f4a99c..be075c1e 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -393,6 +393,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() preserveScrollPosition:boolean; @Input() lockSwipeToPrev:boolean; @Input() lockSwipes:boolean; + @Input() startHour:number; + @Input() endHour:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -417,11 +419,13 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { private initScrollPosition:number; private formatTitle:(date:Date) => string; private formatHourColumnLabel:(date:Date) => string; + private hourRange:number; constructor(private calendarService:CalendarService, private elm:ElementRef) { } ngOnInit() { + this.hourRange = this.endHour - this.startHour; if (this.dateFormatter && this.dateFormatter.formatDayViewTitle) { this.formatTitle = this.dateFormatter.formatDayViewTitle; } else { @@ -470,7 +474,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { let hourColumns = this.elm.nativeElement.querySelector('.dayview-normal-event-container').querySelectorAll('.calendar-hour-column'); var me = this; setTimeout(function () { - me.initScrollPosition = hourColumns[me.scrollToHour].offsetTop; + me.initScrollPosition = hourColumns[me.scrollToHour - me.startHour].offsetTop; }, 0); } } @@ -542,13 +546,13 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { this.direction = 0; } - static createDateObjects(startTime:Date):IDayViewRow[] { + static createDateObjects(startTime:Date, startHour: number, endHour: number):IDayViewRow[] { let rows:IDayViewRow[] = [], time:Date, currentHour = startTime.getHours(), currentDate = startTime.getDate(); - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = startHour; hour < endHour; hour += 1) { time = new Date(startTime.getTime()); time.setHours(currentHour + hour); time.setDate(currentDate); @@ -570,7 +574,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { getViewData(startTime:Date):IDayView { return { - rows: DayViewComponent.createDateObjects(startTime), + rows: DayViewComponent.createDateObjects(startTime, this.startHour, this.endHour), allDayEvents: [] }; } @@ -602,7 +606,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { eps = 0.016, normalEventInRange = false; - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = 0; hour < this.hourRange; hour += 1) { rows[hour].events = []; } @@ -626,8 +630,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { normalEventInRange = true; } - let timeDiff:number; - let timeDifferenceStart:number; + let timeDiff: number; + let timeDifferenceStart: number; if (eventStartTime <= startTime) { timeDifferenceStart = 0; } else { @@ -635,7 +639,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { timeDifferenceStart = timeDiff / oneHour; } - let timeDifferenceEnd:number; + let timeDifferenceEnd: number; if (eventEndTime >= endTime) { timeDiff = endTime.getTime() - startTime.getTime() - (endTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; timeDifferenceEnd = timeDiff / oneHour; @@ -649,32 +653,52 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { let startOffset = 0; let endOffset = 0; if (this.hourParts !== 1) { - startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); - endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); + if (startIndex < this.startHour) { + startOffset = 0; + } else { + startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); + } + if (endIndex > this.endHour) { + endOffset = 0; + } else { + endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); + } } - let displayEvent = { - event: event, - startIndex: startIndex, - endIndex: endIndex, - startOffset: startOffset, - endOffset: endOffset - }; - - let eventSet = rows[startIndex].events; - if (eventSet) { - eventSet.push(displayEvent); + if (startIndex < this.startHour) { + startIndex = 0; } else { - eventSet = []; - eventSet.push(displayEvent); - rows[startIndex].events = eventSet; + startIndex -= this.startHour; + } + if (endIndex > this.endHour) { + endIndex = this.endHour; + } + endIndex -= this.startHour; + + if (startIndex < endIndex) { + let displayEvent = { + event: event, + startIndex: startIndex, + endIndex: endIndex, + startOffset: startOffset, + endOffset: endOffset + }; + + let eventSet = rows[startIndex].events; + if (eventSet) { + eventSet.push(displayEvent); + } else { + eventSet = []; + eventSet.push(displayEvent); + rows[startIndex].events = eventSet; + } } } } if (normalEventInRange) { let orderedEvents:IDisplayEvent[] = []; - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = 0; hour < this.hourRange; hour += 1) { if (rows[hour].events) { rows[hour].events.sort(DayViewComponent.compareEventByStartOffset); @@ -708,7 +732,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } select(selectedTime:Date, events:IDisplayEvent[]) { - var disabled = false; + let disabled = false; if (this.markDisabled) { disabled = this.markDisabled(selectedTime); } @@ -722,7 +746,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { placeEvents(orderedEvents:IDisplayEvent[]) { this.calculatePosition(orderedEvents); - DayViewComponent.calculateWidth(orderedEvents); + DayViewComponent.calculateWidth(orderedEvents, this.hourRange); } placeAllDayEvents(orderedEvents:IDisplayEvent[]) { @@ -740,7 +764,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (earlyEvent.endIndex <= lateEvent.startIndex) { return false; } else { - return !(earlyEvent.endIndex - lateEvent.startIndex === 1 && earlyEvent.endOffset + lateEvent.startOffset > this.hourParts); + return !(earlyEvent.endIndex - lateEvent.startIndex === 1 && earlyEvent.endOffset + lateEvent.startOffset >= this.hourParts); } } @@ -778,14 +802,14 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } } - private static calculateWidth(orderedEvents:IDisplayEvent[]) { - let cells:{ calculated: boolean; events: IDisplayEvent[]; }[] = new Array(24); + private static calculateWidth(orderedEvents:IDisplayEvent[], size:number) { + let cells:{ calculated: boolean; events: IDisplayEvent[]; }[] = new Array(size); // sort by position in descending order, the right most columns should be calculated first orderedEvents.sort((eventA, eventB) => { return eventB.position - eventA.position; }); - for (let i = 0; i < 24; i += 1) { + for (let i = 0; i < size; i += 1) { cells[i] = { calculated: false, events: [] diff --git a/src/weekview.ts b/src/weekview.ts index 51743787..0ad0fe0c 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -479,6 +479,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() preserveScrollPosition:boolean; @Input() lockSwipeToPrev:boolean; @Input() lockSwipes:boolean; + @Input() startHour:number; + @Input() endHour:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -500,11 +502,13 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges private formatDayHeader:(date:Date) => string; private formatTitle:(date:Date) => string; private formatHourColumnLabel:(date:Date) => string; + private hourRange:number; constructor(private calendarService:CalendarService, private elm:ElementRef) { } ngOnInit() { + this.hourRange = this.endHour - this.startHour; if (this.dateFormatter && this.dateFormatter.formatWeekViewDayHeader) { this.formatDayHeader = this.dateFormatter.formatWeekViewDayHeader; } else { @@ -561,7 +565,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges let hourColumns = this.elm.nativeElement.querySelector('.weekview-normal-event-container').querySelectorAll('.calendar-hour-column'); var me = this; setTimeout(function () { - me.initScrollPosition = hourColumns[me.scrollToHour].offsetTop; + me.initScrollPosition = hourColumns[me.scrollToHour - me.startHour].offsetTop; }, 0); } } @@ -634,12 +638,12 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.direction = 0; } - static createDateObjects(startTime:Date):IWeekViewRow[][] { + static createDateObjects(startTime:Date, startHour: number, endHour: number):IWeekViewRow[][] { let times:IWeekViewRow[][] = [], currentHour = startTime.getHours(), currentDate = startTime.getDate(); - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = startHour; hour < endHour; hour += 1) { let row:IWeekViewRow[] = []; for (let day = 0; day < 7; day += 1) { let time = new Date(startTime.getTime()); @@ -686,7 +690,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } return { - rows: WeekViewComponent.createDateObjects(startTime), + rows: WeekViewComponent.createDateObjects(startTime, this.startHour, this.endHour), dates: dates, dayHeaders: dayHeaders }; @@ -734,7 +738,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } for (let day = 0; day < 7; day += 1) { - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = 0; hour < this.hourRange; hour += 1) { rows[hour][day].events = []; } } @@ -811,7 +815,11 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges endOffset = 0; if (this.hourParts !== 1) { - startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); + if (startRowIndex < this.startHour) { + startOffset = 0; + } else { + startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); + } } do { @@ -822,23 +830,39 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } else { endRowIndex = endIndex % 24; if (this.hourParts !== 1) { - endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); + if (endRowIndex > this.endHour) { + endOffset = 0; + } else { + endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); + } } } - let displayEvent = { - event: event, - startIndex: startRowIndex, - endIndex: endRowIndex, - startOffset: startOffset, - endOffset: endOffset - }; - let eventSet = rows[startRowIndex][dayIndex].events; - if (eventSet) { - eventSet.push(displayEvent); + if(startRowIndex < this.startHour) { + startRowIndex = 0; } else { - eventSet = []; - eventSet.push(displayEvent); - rows[startRowIndex][dayIndex].events = eventSet; + startRowIndex -= this.startHour; + } + if(endRowIndex > this.endHour) { + endRowIndex = this.endHour; + } + endRowIndex -= this.startHour; + + if(startRowIndex < endRowIndex) { + let displayEvent = { + event: event, + startIndex: startRowIndex, + endIndex: endRowIndex, + startOffset: startOffset, + endOffset: endOffset + }; + let eventSet = rows[startRowIndex][dayIndex].events; + if (eventSet) { + eventSet.push(displayEvent); + } else { + eventSet = []; + eventSet.push(displayEvent); + rows[startRowIndex][dayIndex].events = eventSet; + } } startRowIndex = 0; startOffset = 0; @@ -851,7 +875,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (normalEventInRange) { for (let day = 0; day < 7; day += 1) { let orderedEvents:IDisplayEvent[] = []; - for (let hour = 0; hour < 24; hour += 1) { + for (let hour = 0; hour < this.hourRange; hour += 1) { if (rows[hour][day].events) { rows[hour][day].events.sort(WeekViewComponent.compareEventByStartOffset); orderedEvents = orderedEvents.concat(rows[hour][day].events); @@ -914,7 +938,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } select(selectedTime:Date, events:IDisplayEvent[]) { - var disabled = false; + let disabled = false; if (this.markDisabled) { disabled = this.markDisabled(selectedTime); } @@ -928,7 +952,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges placeEvents(orderedEvents:IDisplayEvent[]) { this.calculatePosition(orderedEvents); - WeekViewComponent.calculateWidth(orderedEvents); + WeekViewComponent.calculateWidth(orderedEvents, this.hourRange); } placeAllDayEvents(orderedEvents:IDisplayEvent[]) { @@ -946,7 +970,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (earlyEvent.endIndex <= lateEvent.startIndex) { return false; } else { - return !(earlyEvent.endIndex - lateEvent.startIndex === 1 && earlyEvent.endOffset + lateEvent.startOffset > this.hourParts); + return !(earlyEvent.endIndex - lateEvent.startIndex === 1 && earlyEvent.endOffset + lateEvent.startOffset >= this.hourParts); } } @@ -984,14 +1008,14 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } } - private static calculateWidth(orderedEvents:IDisplayEvent[]) { - let cells = new Array(24); + private static calculateWidth(orderedEvents:IDisplayEvent[], size:number) { + let cells = new Array(size); // sort by position in descending order, the right most columns should be calculated first orderedEvents.sort((eventA, eventB) => { return eventB.position - eventA.position; }); - for (let i = 0; i < 24; i += 1) { + for (let i = 0; i < size; i += 1) { cells[i] = { calculated: false, events: [] From 71bb81629a57281ebdb534dae34da647e005c96a Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 12 Nov 2017 23:42:22 +0800 Subject: [PATCH 13/23] Support Ionic 3.9.2 and Angular 5.0 --- package.json | 29 +++++++++++++------------- src/calendar.ts | 4 ++-- src/dayview.ts | 18 ++++++++-------- src/init-position-scroll.ts | 2 +- src/monthview.ts | 20 +++++++++--------- src/weekview.ts | 41 +++++++++++-------------------------- tsconfig-aot.json | 6 +----- 7 files changed, 49 insertions(+), 71 deletions(-) diff --git a/package.json b/package.json index bbc345f1..de1751ae 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.3.11", + "version": "0.4.0", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", @@ -16,7 +16,7 @@ }, "scripts": { "build": "rm -rf dist && tsc && cp package.json dist/package.json", - "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json && node_modules/.bin/ngc src && mv src/*ngfactory.ts aot && rm -r aot/waste && rm -r src/*.ngsummary.json", + "build-prod": "rm -rf aot && node_modules/.bin/ngc -p tsconfig-aot.json", "copy_static_files": "cp -r package.json README.md LICENSE tsconfig.json typings.json typings dist/", "copy_static_files_prod": "cp -r package.json README.md LICENSE tsconfig.json aot/", "dev": "tsc --watch" @@ -24,19 +24,18 @@ "main": "./index.js", "dependencies": {}, "devDependencies": { - "tslint-ionic-rules": "0.0.8", - "typescript": "~2.2.1", - "@angular/common": "4.0.2", - "@angular/compiler": "4.0.2", - "@angular/compiler-cli": "4.0.2", - "@angular/core": "4.0.2", - "@angular/forms": "4.0.2", - "@angular/http": "4.0.2", - "@angular/platform-browser": "4.0.2", - "@angular/platform-browser-dynamic": "4.0.2", - "ionic-angular": "3.1.1", - "rxjs": "5.1.1", - "zone.js": "^0.8.5", + "typescript": "~2.4.2", + "@angular/common": "5.0.0", + "@angular/compiler": "5.0.0", + "@angular/compiler-cli": "5.0.0", + "@angular/core": "5.0.0", + "@angular/forms": "5.0.0", + "@angular/http": "5.0.0", + "@angular/platform-browser": "5.0.0", + "@angular/platform-browser-dynamic": "5.0.0", + "ionic-angular": "3.9.2", + "rxjs": "5.5.2", + "zone.js": "^0.8.18", "intl": "^1.2.5" } } diff --git a/src/calendar.ts b/src/calendar.ts index 0efe08cf..8bd6753a 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -290,10 +290,10 @@ export class CalendarComponent implements OnInit { @Input() formatDay:string = 'd'; @Input() formatDayHeader:string = 'EEE'; @Input() formatDayTitle:string = 'MMMM dd, yyyy'; - @Input() formatWeekTitle:string = 'MMMM yyyy, Week $n'; + @Input() formatWeekTitle:string = 'MMMM yyyy, \'Week\' w'; @Input() formatMonthTitle:string = 'MMMM yyyy'; @Input() formatWeekViewDayHeader:string = 'EEE d'; - @Input() formatHourColumn:string = 'j'; + @Input() formatHourColumn:string = 'ha'; @Input() showEventDetail:boolean = true; @Input() startingDayMonth:number = 0; @Input() startingDayWeek:number = 0; diff --git a/src/dayview.ts b/src/dayview.ts index be075c1e..9d36db3a 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -26,7 +26,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*eventIndex+'px',width: '100%',height:'25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -50,7 +50,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px', left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -88,7 +88,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*eventIndex+'px',width: '100%',height:'25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -112,7 +112,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px', left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -150,7 +150,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*eventIndex+'px',width: '100%',height:'25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -174,7 +174,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px', left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -429,7 +429,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (this.dateFormatter && this.dateFormatter.formatDayViewTitle) { this.formatTitle = this.dateFormatter.formatDayViewTitle; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatTitle = function (date:Date) { return datePipe.transform(date, this.formatDayTitle); }; @@ -438,7 +438,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (this.dateFormatter && this.dateFormatter.formatDayViewHourColumn) { this.formatHourColumnLabel = this.dateFormatter.formatDayViewHourColumn; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatHourColumnLabel = function (date:Date) { return datePipe.transform(date, this.formatHourColumn); }; @@ -472,7 +472,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { if (this.scrollToHour > 0) { let hourColumns = this.elm.nativeElement.querySelector('.dayview-normal-event-container').querySelectorAll('.calendar-hour-column'); - var me = this; + let me = this; setTimeout(function () { me.initScrollPosition = hourColumns[me.scrollToHour - me.startHour].offsetTop; }, 0); diff --git a/src/init-position-scroll.ts b/src/init-position-scroll.ts index ede4af10..9bd61b07 100644 --- a/src/init-position-scroll.ts +++ b/src/init-position-scroll.ts @@ -20,7 +20,7 @@ export class initPositionScrollComponent extends Scroll { private listenerAttached:boolean = false; constructor(el:ElementRef) { - super(el); + super(); this.element = el; } diff --git a/src/monthview.ts b/src/monthview.ts index f9776428..159f570d 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -26,7 +26,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[0], row: row, col: col}"> @@ -44,7 +44,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[0], row: row, col: col}"> @@ -65,7 +65,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[1], row: row, col: col}"> @@ -83,7 +83,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[1], row: row, col: col}"> @@ -104,7 +104,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[2], row: row, col: col}"> @@ -122,7 +122,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{view: views[2], row: row, col: col}"> @@ -131,7 +131,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; + [ngTemplateOutletContext]="{showEventDetail:showEventDetail, selectedDate: selectedDate, noEventsLabel: noEventsLabel}"> `, @@ -275,7 +275,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatMonthViewDay) { this.formatDayLabel = this.dateFormatter.formatMonthViewDay; } else { - var dayLabelDatePipe = new DatePipe('en-US'); + let dayLabelDatePipe = new DatePipe('en-US'); this.formatDayLabel = function (date:Date) { return dayLabelDatePipe.transform(date, this.formatDay); }; @@ -284,7 +284,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatMonthViewDayHeader) { this.formatDayHeaderLabel = this.dateFormatter.formatMonthViewDayHeader; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatDayHeaderLabel = function (date:Date) { return datePipe.transform(date, this.formatDayHeader); }; @@ -293,7 +293,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatMonthViewTitle) { this.formatTitle = this.dateFormatter.formatMonthViewTitle; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatTitle = function (date:Date) { return datePipe.transform(date, this.formatMonthTitle); }; diff --git a/src/weekview.ts b/src/weekview.ts index 0ad0fe0c..b82f8c36 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -35,7 +35,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*displayEvent.position+'px', width: 100*(displayEvent.endIndex-displayEvent.startIndex)+'%', height: '25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -58,7 +58,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px',left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -121,7 +121,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*displayEvent.position+'px', width: 100*(displayEvent.endIndex-displayEvent.startIndex)+'%', height: '25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -144,7 +144,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px',left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -207,7 +207,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: 25*displayEvent.position+'px', width: 100*(displayEvent.endIndex-displayEvent.startIndex)+'%', height: '25px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -230,7 +230,7 @@ import { IDisplayAllDayEvent } from "./calendar"; (click)="eventSelected(displayEvent.event)" [ngStyle]="{top: (37*displayEvent.startOffset/hourParts)+'px',left: 100/displayEvent.overlapNumber*displayEvent.position+'%', width: 100/displayEvent.overlapNumber+'%', height: 37*(displayEvent.endIndex -displayEvent.startIndex - (displayEvent.endOffset + displayEvent.startOffset)/hourParts)+'px'}"> + [ngTemplateOutletContext]="{displayEvent:displayEvent}"> @@ -512,7 +512,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatWeekViewDayHeader) { this.formatDayHeader = this.dateFormatter.formatWeekViewDayHeader; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatDayHeader = function (date:Date) { return datePipe.transform(date, this.formatWeekViewDayHeader); }; @@ -521,7 +521,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatWeekViewTitle) { this.formatTitle = this.dateFormatter.formatWeekViewTitle; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatTitle = function (date:Date) { return datePipe.transform(date, this.formatWeekTitle); }; @@ -530,7 +530,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.dateFormatter && this.dateFormatter.formatWeekViewHourColumn) { this.formatHourColumnLabel = this.dateFormatter.formatWeekViewHourColumn; } else { - var datePipe = new DatePipe(this.locale); + let datePipe = new DatePipe(this.locale); this.formatHourColumnLabel = function (date:Date) { return datePipe.transform(date, this.formatHourColumn); }; @@ -563,7 +563,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.scrollToHour > 0) { let hourColumns = this.elm.nativeElement.querySelector('.weekview-normal-event-container').querySelectorAll('.calendar-hour-column'); - var me = this; + let me = this; setTimeout(function () { me.initScrollPosition = hourColumns[me.scrollToHour - me.startHour].offsetTop; }, 0); @@ -912,25 +912,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } getTitle():string { - let firstDayOfWeek = this.range.startTime, - weekFormat = '$n', - weekNumberIndex = this.formatWeekTitle.indexOf(weekFormat), - title = this.formatTitle(firstDayOfWeek); - - if (weekNumberIndex !== -1) { - let weekNumber = String(WeekViewComponent.getISO8601WeekNumber(firstDayOfWeek)); - title = title.replace(weekFormat, weekNumber); - } - - return title; - } - - private static getISO8601WeekNumber(date:Date):number { - let dayOfWeekOnFirst = (new Date(date.getFullYear(), 0, 1)).getDay(); - let firstThurs = new Date(date.getFullYear(), 0, ((dayOfWeekOnFirst <= 4) ? 5 : 12) - dayOfWeekOnFirst); - let thisThurs = new Date(date.getFullYear(), date.getMonth(), date.getDate() + (4 - date.getDay())); - let diff = +thisThurs - +firstThurs; - return (1 + Math.round(diff / 6.048e8)); // 6.048e8 ms per week + let firstDayOfWeek = this.range.startTime; + return this.formatTitle(firstDayOfWeek); } private static compareEventByStartOffset(eventA:IDisplayEvent, eventB:IDisplayEvent):number { diff --git a/tsconfig-aot.json b/tsconfig-aot.json index e8b075f4..bc0310d3 100644 --- a/tsconfig-aot.json +++ b/tsconfig-aot.json @@ -22,9 +22,5 @@ ], "exclude": [ "node_modules" - ], - "angularCompilerOptions": { - "skipMetadataEmit" : false, - "genDir": "./aot/waste" - } + ] } From e41e99df3719528a918da46a0041b90dbf37c77e Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 12 Nov 2017 23:45:28 +0800 Subject: [PATCH 14/23] Update README --- README.md | 163 +++++++++++++++++++++++++++++++----------------------- 1 file changed, 93 insertions(+), 70 deletions(-) diff --git a/README.md b/README.md index b3e09981..a991e342 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ version 0.1.x depends on Ionic 2.0.0-rc.1 ~ Ionic 2.0.0-rc.4 version 0.2.x depends on Ionic 2.0.0-rc.5 (rc.5 has breaking change on the slide API) and 2.0.0 final version onwards. version 0.2.9+ depends on Ionic 2.3.0 version onwards. version 0.3.x depends on Ionic 3.1.1 version onwards. +version 0.4.x depends on Ionic 3.9.2 version onwards. # Usage @@ -21,7 +22,7 @@ Install: `npm install ionic2-calendar --save` Import the ionic2-calendar module: -``` +``` typescript import { NgModule } from '@angular/core'; import { IonicApp, IonicModule } from 'ionic-angular'; import { MyApp } from './app/app.component'; @@ -45,7 +46,8 @@ export class AppModule {} ``` If you are using PageModule, you need to import the NgCalendarModule in your page module -``` + +``` typescript import { NgCalendarModule } from 'ionic2-calendar'; @NgModule({ @@ -65,7 +67,7 @@ export class MyPageModule {} Add the directive in the html page -``` +``` html - +``` html + +``` +``` json calendar = { locale: 'en-GB' }; - +``` * markDisabled The callback function used to determine if the time should be marked as disabled. - - - +``` html + +``` +``` typescript markDisabled = (date: Date) => { var current = new Date(); return date < current; }; - +``` * dateFormatter The custom date formatter to transform date to text. If the custom date formatter is not set, the default Angular DatePipe is used. The format method in dateFormatter is optional, if omitted, the default Angular DatePipe is used. - +``` html - +``` +``` typescript calendar = { dateFormatter: { formatMonthViewDay: function(date:Date) { return date.getDate().toString(); }, formatMonthViewDayHeader: function(date:Date) { - return ‘testMDH’; + return 'testMDH'; }, formatMonthViewTitle: function(date:Date) { return 'testMT'; }, formatWeekViewDayHeader: function(date:Date) { - return ‘testWDH’; + return 'testWDH'; }, formatWeekViewTitle: function(date:Date) { - return 'testWT’; + return 'testWT'; }, formatWeekViewHourColumn: function(date:Date) { - return 'testWH’; + return 'testWH'; }, formatDayViewHourColumn: function(date:Date) { - return 'testDH’; + return 'testDH'; }, formatDayViewTitle: function(date:Date) { - return 'testDT’; + return 'testDT'; } } }; - +``` * dir -If set to “rtl”, the calendar supports RTL language. This feature is only supported in Ionic 2.3.0 version onwards. -Default value: “” +If set to "rtl", the calendar supports RTL language. This feature is only supported in Ionic 2.3.0 version onwards. +Default value: "" * scrollToHour Make weekview and dayview scroll to the specific hour after entering to the new view. @@ -222,7 +227,7 @@ Default value: false If set to true, swiping to previous view is disabled. Default value: false - + onCurrentDateChanged(event:Date) { var today = new Date(); @@ -242,41 +247,42 @@ Default value: false If set to true, swiping is disabled. Default value: false *Note:* Since swiping is disabled, you could set currentDate to move the calendar to previous/next view. Do not set lockSwipeToPrev in the constructor phase. It will cause the view not updating when changing the currentDate. You could either set it in some callback function after initialization phase or use setTimeout to trigger some delay. - - - +``` html + +``` +``` javascript ngAfterViewInit() { var me = this; setTimeout(function() { me.lockSwipes = true; },100); } - +``` * startHour Limit the weekview and dayview starts from which hour (0-23). Default value: 0 - - - +``` html + +``` * endHour Limit the weekview and dayview ends until which hour (1-24). Default value: 24 - - - +``` html + +``` * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. - +``` html onCurrentChanged = (ev: Date) => { console.log('Currently viewed date: ' + ev); }; - +``` * onRangeChanged The callback function triggered when the range or mode is changed if the queryMode is set to 'remote' The ev parameter contains two fields, startTime and endTime. - +``` html onRangeChanged = (ev: { startTime: Date, endTime: Date }) => { @@ -284,109 +290,114 @@ The ev parameter contains two fields, startTime and endTime. this.eventSource = events; }); }; - +``` * onEventSelected The callback function triggered when an event is clicked - +``` html onEventSelected = (event) => { console.log(event.title); }; - +``` * onTimeSelected The callback function triggered when a date is selected in the monthview. The ev parameter contains two fields, selectedTime and events, if there's no event at the selected time, the events field will be either undefined or empty array - +``` html onTimeSelected = (ev: { selectedTime: Date, events: any[] }) => { console.log('Selected time: ' + ev.selectedTime + ', hasEvents: ' + (ev.events !== undefined && ev.events.length !== 0)); }; - +``` * onTitleChanged The callback function triggered when the view title is changed - - onViewTitleChanged = (title: string) => { this.viewTitle = title; }; - +``` # View Customization Option Note: For any css class appear in the customized template, you need to specify the styles by yourself. The styles defined in the calendar component won’t be applied because of the view encapsulation. * monthviewDisplayEventTemplate Type: TemplateRef\ The template provides customized view for event displayed in the active monthview - +``` html - +``` * monthviewInactiveDisplayEventTemplate Type: TemplateRef\ The template provides customized view for event displayed in the inactive monthview - +``` html - +``` * monthviewEventDetailTemplate Type: TemplateRef\ The template provides customized view for event detail section in the monthview - +``` html - +``` * weekviewAllDayEventTemplate Type: TemplateRef\ The template provides customized view for all day event in the weekview - +``` html - +``` * weekviewNormalEventTemplate Type: TemplateRef\ The template provides customized view for normal event in the weekview +``` html +``` -* dayviewAllDayEventTemplate +* dayviewAllDayEventTemplate     Type: TemplateRef\ The template provides customized view for all day event in the dayview +``` html +``` -* dayviewNormalEventTemplate +* dayviewNormalEventTemplate     Type: TemplateRef\ The template provides customized view for normal event in the dayview +``` javascript - - +         +``` # EventSource @@ -397,15 +408,17 @@ EventSource is an array of event object which contains at least below fields: If allDay is set to true, the startTime has to be as a UTC date which time is set to 0:00 AM, because in an allDay event, only the date is considered, the exact time or timezone doesn't matter. For example, if an allDay event starting from 2014-05-09, then startTime is +``` javascript var startTime = new Date(Date.UTC(2014, 4, 8)); +``` -* endTime +* endTime     If allDay is set to true, the startTime has to be as a UTC date which time is set to 0:00 AM, because in an allDay event, only the date is considered, the exact time or timezone doesn't matter. For example, if an allDay event ending to 2014-05-10, then endTime is - +``` javascript var endTime = new Date(Date.UTC(2014, 4, 9)); - -* allDay +``` +* allDay     Indicates the event is allDay event or regular event **Note** The calendar only watches for the eventSource reference for performance consideration. That means only you manually reassign the eventSource value, the calendar gets notified, and this is usually fit to the scenario when the range is changed, you load a new data set from the backend. In case you want to manually insert/remove/update the element in the eventSource array, you can call instance method ‘loadEvents’ event to notify the calendar manually. @@ -414,7 +427,7 @@ Indicates the event is allDay event or regular event * loadEvents When this method is called, the calendar will be forced to reload the events in the eventSource array. This is only necessary when you directly modify the element in the eventSource array. -``` +``` typescript import { CalendarComponent } from "ionic2-calendar/calendar"; @Component({ @@ -427,7 +440,7 @@ export class HomePage { … loadEvents: function() { this.eventSource.push({ - title: ‘test’, + title: 'test', startTime: startTime, endTime: endTime, allDay: false @@ -442,22 +455,32 @@ You could use *locale* option to achieve the localization. If locale option is not specified, the calendar will use the LOCALE_ID set at the module level. By default, the LOCALE_ID is **en-US**. You can override it in the module as below. If you pass **undefined**, the LOCALE_ID will be detected using the browser language setting. But using explicit value is recommended, as browser has different level of localization support. Note that the event detail section in the month view doesn't support *locale* option, only LOCALE_ID takes effect. This is because it uses DatePipe in html directly. You could easily leverage customized event detail template to switch to other locale. -``` + +``` typescript import { NgModule, LOCALE_ID } from '@angular/core'; @NgModule({ … providers: [ - { provide: LOCALE_ID, useValue: ‘zh-CN’ } + { provide: LOCALE_ID, useValue: 'zh-CN' } ] }) ``` + +For version 0.4.x which depends on Ionic 3.9.2 and Angular 5.0, locale module needs to be registered explicitly in module file as below. +``` typescript +import { registerLocaleData } from '@angular/common'; +import localeZh from '@angular/common/locales/zh'; +registerLocaleData(localeZh); + +``` + If you want to change the locale dynamically, you should use *locale* option instead of LOCALE_ID. # Performance Tuning In the CPU profile, the default Intl based localization code occupies a big portion of the execution time. If you don’t need localization on certain parts, you can use the custom dateFormatter to override the date transform method. For example, the date in month view usually doesn’t require localization, you could use below code to just display the date part. If the month view day header doesn’t need to include the date, you could also use a string array containing static labels to save the date calculation. -``` +``` html calendar = { From 43f9c60a453908b8844d55c0f69b1129fa1fe188 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Mon, 20 Nov 2017 23:02:28 +0800 Subject: [PATCH 15/23] add spaceBetween option; adjust hour offset when formatting title to avoid DST issue. --- README.md | 7 +++++++ package.json | 2 +- src/calendar.ts | 4 ++++ src/dayview.ts | 7 +++++-- src/monthview.ts | 5 +++-- src/weekview.ts | 7 +++++-- 6 files changed, 25 insertions(+), 7 deletions(-) diff --git a/README.md b/README.md index a991e342..8f29dcb7 100644 --- a/README.md +++ b/README.md @@ -270,6 +270,13 @@ Default value: 24 ``` html ``` + +* spaceBetween +Distance between slides. +Default value: 0 +``` html + +``` * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. ``` html diff --git a/package.json b/package.json index de1751ae..8da40c0a 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.4.0", + "version": "0.4.1", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index 8bd6753a..e83adf24 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -172,6 +172,7 @@ export enum Step { [dir]="dir" [lockSwipeToPrev]="lockSwipeToPrev" [lockSwipes]="lockSwipes" + [spaceBetween]="spaceBetween" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -197,6 +198,7 @@ export enum Step { [lockSwipes]="lockSwipes" [startHour]="startHour" [endHour]="endHour" + [spaceBetween]="spaceBetween" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -220,6 +222,7 @@ export enum Step { [lockSwipes]="lockSwipes" [startHour]="startHour" [endHour]="endHour" + [spaceBetween]="spaceBetween" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -319,6 +322,7 @@ export class CalendarComponent implements OnInit { @Input() locale:string = ""; @Input() startHour:number = 0; @Input() endHour:number = 24; + @Input() spaceBetween:number = 0; @Output() onCurrentDateChanged = new EventEmitter(); @Output() onRangeChanged = new EventEmitter(); diff --git a/src/dayview.ts b/src/dayview.ts index 9d36db3a..9aed9134 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -10,7 +10,7 @@ import { IDisplayAllDayEvent } from "./calendar"; @Component({ selector: 'dayview', template: ` - +
{{allDayLabel}}
@@ -276,6 +276,7 @@ import { IDisplayAllDayEvent } from "./calendar"; line-height: 50px; text-align: center; width: 50px; + border-left: 1px solid #ddd; } [dir="rtl"] .dayview-allday-label { @@ -395,6 +396,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() lockSwipes:boolean; @Input() startHour:number; @Input() endHour:number; + @Input() spaceBetween:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -723,7 +725,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } getTitle():string { - let startingDate = this.range.startTime; + let startingDate = new Date(this.range.startTime.getTime()); + startingDate.setHours(12, 0,0,0); return this.formatTitle(startingDate); } diff --git a/src/monthview.ts b/src/monthview.ts index 159f570d..01b8941f 100644 --- a/src/monthview.ts +++ b/src/monthview.ts @@ -11,7 +11,7 @@ import { IMonthViewDisplayEventTemplateContext } from "./calendar"; selector: 'monthview', template: `
- + @@ -246,6 +246,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() dir:string = ""; @Input() lockSwipeToPrev:boolean; @Input() lockSwipes:boolean; + @Input() spaceBetween:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -634,7 +635,7 @@ export class MonthViewComponent implements ICalendarComponent, OnInit, OnChanges 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); + headerDate = new Date(year, month, 1, 12, 0, 0, 0); return this.formatTitle(headerDate); } diff --git a/src/weekview.ts b/src/weekview.ts index b82f8c36..5b391e4c 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -10,7 +10,7 @@ import { IDisplayAllDayEvent } from "./calendar"; @Component({ selector: 'weekview', template: ` - +
@@ -348,6 +348,7 @@ import { IDisplayAllDayEvent } from "./calendar"; line-height: 50px; text-align: center; width: 50px; + border-left: 1px solid #ddd; } [dir="rtl"] .weekview-allday-label { @@ -481,6 +482,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() lockSwipes:boolean; @Input() startHour:number; @Input() endHour:number; + @Input() spaceBetween:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -912,7 +914,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } getTitle():string { - let firstDayOfWeek = this.range.startTime; + let firstDayOfWeek = new Date(this.range.startTime.getTime()); + firstDayOfWeek.setHours(12, 0, 0, 0); return this.formatTitle(firstDayOfWeek); } From f06b018de8f175e43653917c1baaf5082a2978ed Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 3 Dec 2017 20:38:14 +0800 Subject: [PATCH 16/23] fix bug when calculating event width; --- .gitignore | 3 ++- package.json | 4 ++-- src/dayview.ts | 17 +++++++++-------- src/weekview.ts | 17 +++++++++-------- 4 files changed, 22 insertions(+), 19 deletions(-) diff --git a/.gitignore b/.gitignore index ed8c74bc..9679002f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,5 @@ /typings /node_modules - +/.idea /dist +/aot diff --git a/package.json b/package.json index 8da40c0a..2e29fe4e 100644 --- a/package.json +++ b/package.json @@ -1,13 +1,13 @@ { "name": "ionic2-calendar", - "version": "0.4.1", + "version": "0.4.2", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", "calendar" ], "author": { - "name": "twinsbc" + "name": "twinssbc" }, "license": "MIT", "repository": { diff --git a/src/dayview.ts b/src/dayview.ts index 9aed9134..2422ea63 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -749,7 +749,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { placeEvents(orderedEvents:IDisplayEvent[]) { this.calculatePosition(orderedEvents); - DayViewComponent.calculateWidth(orderedEvents, this.hourRange); + DayViewComponent.calculateWidth(orderedEvents, this.hourRange, this.hourParts); } placeAllDayEvents(orderedEvents:IDisplayEvent[]) { @@ -805,14 +805,15 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } } - private static calculateWidth(orderedEvents:IDisplayEvent[], size:number) { - let cells:{ calculated: boolean; events: IDisplayEvent[]; }[] = new Array(size); + private static calculateWidth(orderedEvents:IDisplayEvent[], size:number, hourParts: number) { + let totalSize = size * hourParts, + cells:{ calculated: boolean; events: IDisplayEvent[]; }[] = new Array(totalSize); // sort by position in descending order, the right most columns should be calculated first orderedEvents.sort((eventA, eventB) => { return eventB.position - eventA.position; }); - for (let i = 0; i < size; i += 1) { + for (let i = 0; i < totalSize; i += 1) { cells[i] = { calculated: false, events: [] @@ -821,8 +822,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { let len = orderedEvents.length; for (let i = 0; i < len; i += 1) { let event = orderedEvents[i]; - let index = event.startIndex; - while (index < event.endIndex) { + let index = event.startIndex * hourParts + event.startOffset; + while (index < event.endIndex * hourParts - event.endOffset) { cells[index].events.push(event); index += 1; } @@ -836,8 +837,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { event.overlapNumber = overlapNumber; let eventQueue = [event]; while ((event = eventQueue.shift())) { - let index = event.startIndex; - while (index < event.endIndex) { + let index = event.startIndex * hourParts + event.startOffset; + while (index < event.endIndex * hourParts - event.endOffset) { if (!cells[index].calculated) { cells[index].calculated = true; if (cells[index].events) { diff --git a/src/weekview.ts b/src/weekview.ts index 5b391e4c..d78e5df3 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -938,7 +938,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges placeEvents(orderedEvents:IDisplayEvent[]) { this.calculatePosition(orderedEvents); - WeekViewComponent.calculateWidth(orderedEvents, this.hourRange); + WeekViewComponent.calculateWidth(orderedEvents, this.hourRange, this.hourParts); } placeAllDayEvents(orderedEvents:IDisplayEvent[]) { @@ -994,14 +994,15 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } } - private static calculateWidth(orderedEvents:IDisplayEvent[], size:number) { - let cells = new Array(size); + private static calculateWidth(orderedEvents:IDisplayEvent[], size:number, hourParts:number) { + let totalSize = size * hourParts, + cells = new Array(totalSize); // sort by position in descending order, the right most columns should be calculated first orderedEvents.sort((eventA, eventB) => { return eventB.position - eventA.position; }); - for (let i = 0; i < size; i += 1) { + for (let i = 0; i < totalSize; i += 1) { cells[i] = { calculated: false, events: [] @@ -1010,8 +1011,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges let len = orderedEvents.length; for (let i = 0; i < len; i += 1) { let event = orderedEvents[i]; - let index = event.startIndex; - while (index < event.endIndex) { + let index = event.startIndex * hourParts + event.startOffset; + while (index < event.endIndex * hourParts - event.endOffset) { cells[index].events.push(event); index += 1; } @@ -1025,8 +1026,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges event.overlapNumber = overlapNumber; let eventQueue = [event]; while ((event = eventQueue.shift())) { - let index = event.startIndex; - while (index < event.endIndex) { + let index = event.startIndex * hourParts + event.startOffset; + while (index < event.endIndex * hourParts - event.endOffset) { if (!cells[index].calculated) { cells[index].calculated = true; if (cells[index].events) { From b0f45322d069b70e237302e2f13fc5acf9588530 Mon Sep 17 00:00:00 2001 From: Luca Caprini Date: Mon, 12 Mar 2018 18:33:17 +0100 Subject: [PATCH 17/23] Custom template for weekview header --- README.md | 268 ++++++++++++++++++++++++++---------------------- src/calendar.ts | 13 ++- src/weekview.ts | 29 ++++-- 3 files changed, 173 insertions(+), 137 deletions(-) diff --git a/README.md b/README.md index 8f29dcb7..f4cf65aa 100644 --- a/README.md +++ b/README.md @@ -68,7 +68,7 @@ export class MyPageModule {} Add the directive in the html page ``` html - - + + ``` # Note for Ionic Build/Run command @@ -156,60 +157,60 @@ Default value: true The locale used to display text in the calendar. Default value: undefined (which means the local language) ``` html - + ``` ``` json - calendar = { - locale: 'en-GB' - }; + calendar = { + locale: 'en-GB' + }; ``` * markDisabled The callback function used to determine if the time should be marked as disabled. ``` html - + ``` ``` typescript - markDisabled = (date: Date) => { - var current = new Date(); - return date < current; - }; + markDisabled = (date: Date) => { + var current = new Date(); + return date < current; + }; ``` * dateFormatter The custom date formatter to transform date to text. If the custom date formatter is not set, the default Angular DatePipe is used. The format method in dateFormatter is optional, if omitted, the default Angular DatePipe is used. ``` html - + ``` ``` typescript - calendar = { - dateFormatter: { - formatMonthViewDay: function(date:Date) { - return date.getDate().toString(); - }, - formatMonthViewDayHeader: function(date:Date) { - return 'testMDH'; - }, - formatMonthViewTitle: function(date:Date) { - return 'testMT'; - }, - formatWeekViewDayHeader: function(date:Date) { - return 'testWDH'; - }, - formatWeekViewTitle: function(date:Date) { - return 'testWT'; - }, - formatWeekViewHourColumn: function(date:Date) { - return 'testWH'; - }, - formatDayViewHourColumn: function(date:Date) { - return 'testDH'; - }, - formatDayViewTitle: function(date:Date) { - return 'testDT'; - } + calendar = { + dateFormatter: { + formatMonthViewDay: function(date:Date) { + return date.getDate().toString(); + }, + formatMonthViewDayHeader: function(date:Date) { + return 'testMDH'; + }, + formatMonthViewTitle: function(date:Date) { + return 'testMT'; + }, + formatWeekViewDayHeader: function(date:Date) { + return 'testWDH'; + }, + formatWeekViewTitle: function(date:Date) { + return 'testWT'; + }, + formatWeekViewHourColumn: function(date:Date) { + return 'testWH'; + }, + formatDayViewHourColumn: function(date:Date) { + return 'testDH'; + }, + formatDayViewTitle: function(date:Date) { + return 'testDT'; } - }; + } + }; ``` * dir If set to "rtl", the calendar supports RTL language. This feature is only supported in Ionic 2.3.0 version onwards. @@ -226,106 +227,112 @@ Default value: false * lockSwipeToPrev If set to true, swiping to previous view is disabled. Default value: false - - - - onCurrentDateChanged(event:Date) { - var today = new Date(); - today.setHours(0, 0, 0, 0); - event.setHours(0, 0, 0, 0); - - if (this.calendar.mode === 'month') { - if (event.getFullYear() < today.getFullYear() || (event.getFullYear() === today.getFullYear() && event.getMonth() <= today.getMonth())) { - this.lockSwipeToPrev = true; - } else { - this.lockSwipeToPrev = false; - } +``` html + +``` +``` typescript + onCurrentDateChanged(event:Date) { + var today = new Date(); + today.setHours(0, 0, 0, 0); + event.setHours(0, 0, 0, 0); + + if (this.calendar.mode === 'month') { + if (event.getFullYear() < today.getFullYear() || (event.getFullYear() === today.getFullYear() && event.getMonth() <= today.getMonth())) { + this.lockSwipeToPrev = true; + } else { + this.lockSwipeToPrev = false; } } + } +``` * lockSwipes If set to true, swiping is disabled. Default value: false *Note:* Since swiping is disabled, you could set currentDate to move the calendar to previous/next view. Do not set lockSwipeToPrev in the constructor phase. It will cause the view not updating when changing the currentDate. You could either set it in some callback function after initialization phase or use setTimeout to trigger some delay. ``` html - + ``` -``` javascript - ngAfterViewInit() { - var me = this; - setTimeout(function() { - me.lockSwipes = true; - },100); - } +``` typescript + ngAfterViewInit() { + var me = this; + setTimeout(function() { + me.lockSwipes = true; + },100); + } ``` * startHour Limit the weekview and dayview starts from which hour (0-23). Default value: 0 ``` html - + ``` * endHour Limit the weekview and dayview ends until which hour (1-24). Default value: 24 ``` html - + ``` * spaceBetween Distance between slides. Default value: 0 ``` html - + ``` * onCurrentDateChanged The callback function triggered when the date that is currently viewed changes. ``` html - - - onCurrentChanged = (ev: Date) => { - console.log('Currently viewed date: ' + ev); - }; + +``` +``` typescript + onCurrentChanged = (ev: Date) => { + console.log('Currently viewed date: ' + ev); + }; ``` * onRangeChanged The callback function triggered when the range or mode is changed if the queryMode is set to 'remote' The ev parameter contains two fields, startTime and endTime. ``` html - - - onRangeChanged = (ev: { startTime: Date, endTime: Date }) => { - Events.query(ev, (events) => { - this.eventSource = events; - }); - }; + +``` +``` typescript + onRangeChanged = (ev: { startTime: Date, endTime: Date }) => { + Events.query(ev, (events) => { + this.eventSource = events; + }); + }; ``` * onEventSelected The callback function triggered when an event is clicked ``` html - - - onEventSelected = (event) => { - console.log(event.title); - }; + +``` +``` typescript + onEventSelected = (event) => { + console.log(event.title); + }; ``` * onTimeSelected The callback function triggered when a date is selected in the monthview. The ev parameter contains two fields, selectedTime and events, if there's no event at the selected time, the events field will be either undefined or empty array ``` html - - - onTimeSelected = (ev: { selectedTime: Date, events: any[] }) => { - console.log('Selected time: ' + ev.selectedTime + ', hasEvents: ' + (ev.events !== undefined && ev.events.length !== 0)); - }; + +``` +``` typescript + onTimeSelected = (ev: { selectedTime: Date, events: any[] }) => { + console.log('Selected time: ' + ev.selectedTime + ', hasEvents: ' + (ev.events !== undefined && ev.events.length !== 0)); + }; ``` * onTitleChanged The callback function triggered when the view title is changed ``` html - - - onViewTitleChanged = (title: string) => { - this.viewTitle = title; - }; - + +``` +``` typescript + onViewTitleChanged = (title: string) => { + this.viewTitle = title; + }; ``` # View Customization Option Note: For any css class appear in the customized template, you need to specify the styles by yourself. The styles defined in the calendar component won’t be applied because of the view encapsulation. @@ -334,52 +341,62 @@ Note: For any css class appear in the customized template, you need to specify t Type: TemplateRef\ The template provides customized view for event displayed in the active monthview ``` html - + + {{view.dates[row*7+col].label}} + - + ``` * monthviewInactiveDisplayEventTemplate Type: TemplateRef\ The template provides customized view for event displayed in the inactive monthview ``` html - + + {{view.dates[row*7+col].label}} + - + ``` * monthviewEventDetailTemplate Type: TemplateRef\ The template provides customized view for event detail section in the monthview ``` html - - - + + ... + + + +``` +* weekviewHeaderTemplate +Type: TemplateRef\ +The template provides customized view for day header in the weekview +``` html + +
{{ viewDate.dayHeader }}
+
+ + ``` * weekviewAllDayEventTemplate Type: TemplateRef\ The template provides customized view for all day event in the weekview ``` html - + +
{{displayEvent.event.title}}
+
- + ``` * weekviewNormalEventTemplate Type: TemplateRef\ The template provides customized view for normal event in the weekview ``` html - + +
{{displayEvent.event.title}}
+
- + ``` * dayviewAllDayEventTemplate     @@ -387,23 +404,23 @@ Type: TemplateRef\ The template provides customized view for all day event in the dayview ``` html - + +
{{displayEvent.event.title}}
+
- + ``` * dayviewNormalEventTemplate     Type: TemplateRef\ The template provides customized view for normal event in the dayview -``` javascript - +``` html + +
{{displayEvent.event.title}}
+
-         + ``` # EventSource @@ -416,14 +433,14 @@ If allDay is set to true, the startTime has to be as a UTC date which time is se For example, if an allDay event starting from 2014-05-09, then startTime is ``` javascript - var startTime = new Date(Date.UTC(2014, 4, 8)); + var startTime = new Date(Date.UTC(2014, 4, 8)); ``` * endTime     If allDay is set to true, the startTime has to be as a UTC date which time is set to 0:00 AM, because in an allDay event, only the date is considered, the exact time or timezone doesn't matter. For example, if an allDay event ending to 2014-05-10, then endTime is ``` javascript - var endTime = new Date(Date.UTC(2014, 4, 9)); + var endTime = new Date(Date.UTC(2014, 4, 9)); ``` * allDay     Indicates the event is allDay event or regular event @@ -489,7 +506,8 @@ In the CPU profile, the default Intl based localization code occupies a big port ``` html - +``` +``` typescript calendar = { dateFormatter: { formatMonthViewDay: function(date:Date) { diff --git a/src/calendar.ts b/src/calendar.ts index e83adf24..1202b6bf 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -47,12 +47,12 @@ export interface IMonthViewRow { export interface IWeekView extends IView { dates: IWeekViewDateRow[]; rows: IWeekViewRow[][]; - dayHeaders: string[]; } export interface IWeekViewDateRow { date: Date; events: IDisplayEvent[]; + dayHeader: string; } export interface IWeekViewRow { @@ -70,6 +70,10 @@ export interface IDisplayEvent { position?: number; } +export interface IDisplayWeekViewHeader { + viewDate: IWeekViewDateRow; +} + export interface IDisplayAllDayEvent { event: IEvent; } @@ -146,6 +150,9 @@ export enum Step { + + {{ viewDate.dayHeader }} +
{{displayEvent.event.title}}
@@ -172,7 +179,7 @@ export enum Step { [dir]="dir" [lockSwipeToPrev]="lockSwipeToPrev" [lockSwipes]="lockSwipes" - [spaceBetween]="spaceBetween" + [spaceBetween]="spaceBetween" (onRangeChanged)="rangeChanged($event)" (onEventSelected)="eventSelected($event)" (onTimeSelected)="timeSelected($event)" @@ -187,6 +194,7 @@ export enum Step { [hourParts]="hourParts" [eventSource]="eventSource" [markDisabled]="markDisabled" + [weekviewHeaderTemplate]="weekviewHeaderTemplate||defaultWeekviewHeaderTemplate" [weekviewAllDayEventTemplate]="weekviewAllDayEventTemplate||defaultAllDayEventTemplate" [weekviewNormalEventTemplate]="weekviewNormalEventTemplate||defaultNormalEventTemplate" [locale]="locale" @@ -309,6 +317,7 @@ export class CalendarComponent implements OnInit { @Input() monthviewDisplayEventTemplate:TemplateRef; @Input() monthviewInactiveDisplayEventTemplate:TemplateRef; @Input() monthviewEventDetailTemplate:TemplateRef; + @Input() weekviewHeaderTemplate:TemplateRef; @Input() weekviewAllDayEventTemplate:TemplateRef; @Input() weekviewNormalEventTemplate:TemplateRef; @Input() dayviewAllDayEventTemplate:TemplateRef; diff --git a/src/weekview.ts b/src/weekview.ts index d78e5df3..2687d66b 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -3,7 +3,7 @@ import { Slides } from 'ionic-angular'; import { Component, OnInit, OnChanges, HostBinding, Input, Output, EventEmitter, SimpleChanges, ViewChild, ViewEncapsulation, TemplateRef, ElementRef } from '@angular/core'; import { Subscription } from 'rxjs/Subscription'; -import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode, IDateFormatter } from './calendar'; +import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode, IDateFormatter, IDisplayWeekViewHeader } from './calendar'; import { CalendarService } from './calendar.service'; import { IDisplayAllDayEvent } from "./calendar"; @@ -16,7 +16,10 @@ import { IDisplayAllDayEvent } from "./calendar";
- @@ -102,7 +105,10 @@ import { IDisplayAllDayEvent } from "./calendar"; - @@ -188,7 +194,10 @@ import { IDisplayAllDayEvent } from "./calendar"; - @@ -348,7 +357,7 @@ import { IDisplayAllDayEvent } from "./calendar"; line-height: 50px; text-align: center; width: 50px; - border-left: 1px solid #ddd; + border-left: 1px solid #ddd; } [dir="rtl"] .weekview-allday-label { @@ -462,6 +471,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @ViewChild('weekSlider') slider:Slides; @HostBinding('class.weekview') class = true; + @Input() weekviewHeaderTemplate:TemplateRef; @Input() weekviewAllDayEventTemplate:TemplateRef; @Input() weekviewNormalEventTemplate:TemplateRef; @@ -669,7 +679,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges while (i < n) { dates[i++] = { date: new Date(current.getTime()), - events: [] + events: [], + dayHeader: '' }; current.setDate(current.getDate() + 1); } @@ -686,15 +697,13 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges getViewData(startTime:Date):IWeekView { let dates = WeekViewComponent.getDates(startTime, 7); - let dayHeaders:string[] = []; for (let i = 0; i < 7; i++) { - dayHeaders.push(this.formatDayHeader(dates[i].date)); + dates[i].dayHeader = this.formatDayHeader(dates[i].date); } return { rows: WeekViewComponent.createDateObjects(startTime, this.startHour, this.endHour), - dates: dates, - dayHeaders: dayHeaders + dates: dates }; } From a53b986cddd324aef3b5b1c47f2078c3922c06f1 Mon Sep 17 00:00:00 2001 From: Luca Caprini Date: Mon, 12 Mar 2018 18:49:05 +0100 Subject: [PATCH 18/23] Day selection in week view header Added day selection with click on week view header Added autoSelect on week view Added weekview-with-event, weekview-current and weekview-selected css class (with commented style) --- README.md | 2 +- src/calendar.ts | 14 +++-- src/weekview.ts | 137 ++++++++++++++++++++++++++++++++++++++++++++++-- 3 files changed, 144 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index f4cf65aa..c3c760ef 100644 --- a/README.md +++ b/README.md @@ -151,7 +151,7 @@ Default value: 'local' It can be set to 15 or 30, so that the event can be displayed at more accurate position in weekview or dayview. Default value: 60 * autoSelect -If set to true, the current calendar date will be auto selected when calendar is loaded or swiped in the month view. +If set to true, the current calendar date will be auto selected when calendar is loaded or swiped in the month and week view. Default value: true * locale The locale used to display text in the calendar. diff --git a/src/calendar.ts b/src/calendar.ts index 1202b6bf..465955da 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -50,8 +50,11 @@ export interface IWeekView extends IView { } export interface IWeekViewDateRow { + current?: boolean; date: Date; events: IDisplayEvent[]; + hasEvent?: boolean; + selected?: boolean; dayHeader: string; } @@ -98,14 +101,14 @@ export interface ITimeSelected { } export interface IMonthViewDisplayEventTemplateContext { - view: IView, - row: number, - col: number + view: IView; + row: number; + col: number; } export interface IMonthViewEventDetailTemplateContext { - selectedDate: ITimeSelected, - noEventsLabel: string + selectedDate: ITimeSelected; + noEventsLabel: string; } export interface IDateFormatter { @@ -192,6 +195,7 @@ export enum Step { [startingDayWeek]="startingDayWeek" [allDayLabel]="allDayLabel" [hourParts]="hourParts" + [autoSelect]="autoSelect" [eventSource]="eventSource" [markDisabled]="markDisabled" [weekviewHeaderTemplate]="weekviewHeaderTemplate||defaultWeekviewHeaderTemplate" diff --git a/src/weekview.ts b/src/weekview.ts index 2687d66b..c13b8ef7 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -16,7 +16,9 @@ import { IDisplayAllDayEvent } from "./calendar"; - - - @@ -45,15 +40,9 @@ import { IDisplayAllDayEvent } from "./calendar"; {{hourColumnLabels[i]}} @@ -83,14 +72,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -107,15 +91,9 @@ import { IDisplayAllDayEvent } from "./calendar"; {{hourColumnLabels[i]}} @@ -145,14 +123,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -169,15 +142,9 @@ import { IDisplayAllDayEvent } from "./calendar"; {{hourColumnLabels[i]}} @@ -380,6 +347,8 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() dayviewAllDayEventTemplate:TemplateRef; @Input() dayviewNormalEventTemplate:TemplateRef; + @Input() dayviewAllDayEventSectionTemplate:TemplateRef; + @Input() dayviewNormalEventSectionTemplate:TemplateRef; @Input() formatHourColumn:string; @Input() formatDayTitle:string; @@ -397,6 +366,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { @Input() startHour:number; @Input() endHour:number; @Input() spaceBetween:number; + @Input() hourSegments:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -427,7 +397,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { } ngOnInit() { - this.hourRange = this.endHour - this.startHour; + this.hourRange = (this.endHour - this.startHour) * this.hourSegments; if (this.dateFormatter && this.dateFormatter.formatDayViewTitle) { this.formatTitle = this.dateFormatter.formatDayViewTitle; } else { @@ -548,20 +518,22 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { this.direction = 0; } - static createDateObjects(startTime:Date, startHour: number, endHour: number):IDayViewRow[] { + static createDateObjects(startTime:Date, startHour: number, endHour: number, timeInterval: number):IDayViewRow[] { let rows:IDayViewRow[] = [], time:Date, currentHour = startTime.getHours(), currentDate = startTime.getDate(); for (let hour = startHour; hour < endHour; hour += 1) { - time = new Date(startTime.getTime()); - time.setHours(currentHour + hour); - time.setDate(currentDate); - rows.push({ - time: time, - events: [] - }); + for(let interval = 0; interval < timeInterval; interval +=1 ) { + time = new Date(startTime.getTime()); + time.setHours(currentHour + hour, 60 * interval / timeInterval); + time.setDate(currentDate); + rows.push({ + time: time, + events: [] + }); + } } return rows; } @@ -576,7 +548,7 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { getViewData(startTime:Date):IDayView { return { - rows: DayViewComponent.createDateObjects(startTime, this.startHour, this.endHour), + rows: DayViewComponent.createDateObjects(startTime, this.startHour, this.endHour, this.hourSegments), allDayEvents: [] }; } @@ -606,7 +578,9 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { allDayEvents:IDisplayAllDayEvent[] = this.views[currentViewIndex].allDayEvents = [], oneHour = 3600000, eps = 0.016, - normalEventInRange = false; + normalEventInRange = false, + rangeStartRowIndex = this.startHour * this.hourSegments, + rangeEndRowIndex = this.endHour * this.hourSegments; for (let hour = 0; hour < this.hourRange; hour += 1) { rows[hour].events = []; @@ -638,16 +612,16 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { timeDifferenceStart = 0; } else { timeDiff = eventStartTime.getTime() - startTime.getTime() - (eventStartTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceStart = timeDiff / oneHour; + timeDifferenceStart = timeDiff / oneHour * this.hourSegments; } let timeDifferenceEnd: number; if (eventEndTime >= endTime) { timeDiff = endTime.getTime() - startTime.getTime() - (endTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceEnd = timeDiff / oneHour; + timeDifferenceEnd = timeDiff / oneHour * this.hourSegments; } else { timeDiff = eventEndTime.getTime() - startTime.getTime() - (eventEndTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceEnd = timeDiff / oneHour; + timeDifferenceEnd = timeDiff / oneHour * this.hourSegments; } let startIndex = Math.floor(timeDifferenceStart); @@ -655,27 +629,27 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { let startOffset = 0; let endOffset = 0; if (this.hourParts !== 1) { - if (startIndex < this.startHour) { + if (startIndex < rangeStartRowIndex) { startOffset = 0; } else { startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); } - if (endIndex > this.endHour) { + if (endIndex > rangeEndRowIndex) { endOffset = 0; } else { endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); } } - if (startIndex < this.startHour) { + if (startIndex < rangeStartRowIndex) { startIndex = 0; } else { - startIndex -= this.startHour; + startIndex -= rangeStartRowIndex; } - if (endIndex > this.endHour) { - endIndex = this.endHour; + if (endIndex > rangeEndRowIndex) { + endIndex = rangeEndRowIndex; } - endIndex -= this.startHour; + endIndex -= rangeStartRowIndex; if (startIndex < endIndex) { let displayEvent = { diff --git a/src/weekview.ts b/src/weekview.ts index d78e5df3..4ecfbccc 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -5,7 +5,7 @@ import { Subscription } from 'rxjs/Subscription'; import { ICalendarComponent, IDisplayEvent, IEvent, ITimeSelected, IRange, IWeekView, IWeekViewRow, IWeekViewDateRow, CalendarMode, IDateFormatter } from './calendar'; import { CalendarService } from './calendar.service'; -import { IDisplayAllDayEvent } from "./calendar"; +import { IDisplayAllDayEvent, IWeekViewAllDayEventSectionTemplateContext, IWeekViewNormalEventSectionTemplateContext } from "./calendar"; @Component({ selector: 'weekview', @@ -29,16 +29,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -53,15 +46,9 @@ import { IDisplayAllDayEvent } from "./calendar"; {{hourColumnLabels[i]}} @@ -115,16 +102,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -140,13 +120,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -201,16 +177,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -226,13 +195,9 @@ import { IDisplayAllDayEvent } from "./calendar"; @@ -464,6 +429,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() weekviewAllDayEventTemplate:TemplateRef; @Input() weekviewNormalEventTemplate:TemplateRef; + @Input() weekviewAllDayEventSectionTemplate:TemplateRef; + @Input() weekviewNormalEventSectionTemplate:TemplateRef; @Input() formatWeekTitle:string; @Input() formatWeekViewDayHeader:string; @@ -483,6 +450,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() startHour:number; @Input() endHour:number; @Input() spaceBetween:number; + @Input() hourSegments:number; @Output() onRangeChanged = new EventEmitter(); @Output() onEventSelected = new EventEmitter(); @@ -510,7 +478,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } ngOnInit() { - this.hourRange = this.endHour - this.startHour; + this.hourRange = (this.endHour - this.startHour) * this.hourSegments; if (this.dateFormatter && this.dateFormatter.formatWeekViewDayHeader) { this.formatDayHeader = this.dateFormatter.formatWeekViewDayHeader; } else { @@ -640,23 +608,25 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.direction = 0; } - static createDateObjects(startTime:Date, startHour: number, endHour: number):IWeekViewRow[][] { + static createDateObjects(startTime:Date, startHour: number, endHour: number, timeInterval: number):IWeekViewRow[][] { let times:IWeekViewRow[][] = [], currentHour = startTime.getHours(), currentDate = startTime.getDate(); for (let hour = startHour; hour < endHour; hour += 1) { - let row:IWeekViewRow[] = []; - for (let day = 0; day < 7; day += 1) { - let time = new Date(startTime.getTime()); - time.setHours(currentHour + hour); - time.setDate(currentDate + day); - row.push({ - events: [], - time: time - }); + for(let interval = 0; interval < timeInterval; interval +=1 ) { + let row:IWeekViewRow[] = []; + for (let day = 0; day < 7; day += 1) { + let time = new Date(startTime.getTime()); + time.setHours(currentHour + hour, 60 * interval / timeInterval); + time.setDate(currentDate + day); + row.push({ + events: [], + time: time + }); + } + times.push(row); } - times.push(row); } return times; } @@ -692,7 +662,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } return { - rows: WeekViewComponent.createDateObjects(startTime, this.startHour, this.endHour), + rows: WeekViewComponent.createDateObjects(startTime, this.startHour, this.endHour, this.hourSegments), dates: dates, dayHeaders: dayHeaders }; @@ -733,7 +703,11 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges // add allday eps eps = 0.016, allDayEventInRange = false, - normalEventInRange = false; + normalEventInRange = false, + rangeStartRowIndex = this.startHour * this.hourSegments, + rangeEndRowIndex = this.endHour * this.hourSegments, + allRows = 24 * this.hourSegments; + for (let i = 0; i < 7; i += 1) { dates[i].events = []; @@ -796,28 +770,28 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges timeDifferenceStart = 0; } else { timeDiff = eventStartTime.getTime() - startTime.getTime() - (eventStartTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceStart = timeDiff / oneHour; + timeDifferenceStart = timeDiff / oneHour * this.hourSegments; } let timeDifferenceEnd:number; if (eventEndTime >= endTime) { timeDiff = endTime.getTime() - startTime.getTime() - (endTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceEnd = timeDiff / oneHour; + timeDifferenceEnd = timeDiff / oneHour * this.hourSegments; } else { timeDiff = eventEndTime.getTime() - startTime.getTime() - (eventEndTime.getTimezoneOffset() - startTime.getTimezoneOffset()) * 60000; - timeDifferenceEnd = timeDiff / oneHour; + timeDifferenceEnd = timeDiff / oneHour * this.hourSegments; } let startIndex = Math.floor(timeDifferenceStart), endIndex = Math.ceil(timeDifferenceEnd - eps), - startRowIndex = startIndex % 24, - dayIndex = Math.floor(startIndex / 24), - endOfDay = dayIndex * 24, + startRowIndex = startIndex % allRows, + dayIndex = Math.floor(startIndex / allRows), + endOfDay = dayIndex * allRows, startOffset = 0, endOffset = 0; if (this.hourParts !== 1) { - if (startRowIndex < this.startHour) { + if (startRowIndex < rangeStartRowIndex) { startOffset = 0; } else { startOffset = Math.floor((timeDifferenceStart - startIndex) * this.hourParts); @@ -825,29 +799,33 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } do { - endOfDay += 24; + endOfDay += allRows; let endRowIndex:number; - if (endOfDay <= endIndex) { - endRowIndex = 24; + if (endOfDay < endIndex) { + endRowIndex = allRows; } else { - endRowIndex = endIndex % 24; + if(endOfDay === endIndex) { + endRowIndex = allRows; + } else { + endRowIndex = endIndex % allRows; + } if (this.hourParts !== 1) { - if (endRowIndex > this.endHour) { + if (endRowIndex > rangeEndRowIndex) { endOffset = 0; } else { endOffset = Math.floor((endIndex - timeDifferenceEnd) * this.hourParts); } } } - if(startRowIndex < this.startHour) { + if(startRowIndex < rangeStartRowIndex) { startRowIndex = 0; } else { - startRowIndex -= this.startHour; + startRowIndex -= rangeStartRowIndex; } - if(endRowIndex > this.endHour) { - endRowIndex = this.endHour; + if(endRowIndex > rangeEndRowIndex) { + endRowIndex = rangeEndRowIndex; } - endRowIndex -= this.startHour; + endRowIndex -= rangeStartRowIndex; if(startRowIndex < endRowIndex) { let displayEvent = { From b3ce05c37af18d18e7d350fe4fcd71dcb6b53407 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Wed, 23 May 2018 22:55:44 +0800 Subject: [PATCH 20/23] add logic to handle timeInterval larger than 1 hour case --- package.json | 2 +- src/dayview.ts | 18 ++++++++++++++---- src/weekview.ts | 18 ++++++++++++++---- 3 files changed, 29 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 488efdaa..63743d88 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.4.3", + "version": "0.4.4", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/dayview.ts b/src/dayview.ts index 0359d987..650de6d2 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -522,12 +522,22 @@ export class DayViewComponent implements ICalendarComponent, OnInit, OnChanges { let rows:IDayViewRow[] = [], time:Date, currentHour = startTime.getHours(), - currentDate = startTime.getDate(); + currentDate = startTime.getDate(), + hourStep, + minStep; - for (let hour = startHour; hour < endHour; hour += 1) { - for(let interval = 0; interval < timeInterval; interval +=1 ) { + if(timeInterval < 1) { + hourStep = Math.floor(1 / timeInterval); + minStep = 60; + } else { + hourStep = 1; + minStep = Math.floor(60 / timeInterval); + } + + for (let hour = startHour; hour < endHour; hour += hourStep) { + for(let interval = 0; interval < 60; interval += minStep ) { time = new Date(startTime.getTime()); - time.setHours(currentHour + hour, 60 * interval / timeInterval); + time.setHours(currentHour + hour, interval); time.setDate(currentDate); rows.push({ time: time, diff --git a/src/weekview.ts b/src/weekview.ts index 4ecfbccc..7809e10d 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -611,14 +611,24 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges static createDateObjects(startTime:Date, startHour: number, endHour: number, timeInterval: number):IWeekViewRow[][] { let times:IWeekViewRow[][] = [], currentHour = startTime.getHours(), - currentDate = startTime.getDate(); + currentDate = startTime.getDate(), + hourStep, + minStep; - for (let hour = startHour; hour < endHour; hour += 1) { - for(let interval = 0; interval < timeInterval; interval +=1 ) { + if(timeInterval < 1) { + hourStep = Math.floor(1 / timeInterval); + minStep = 60; + } else { + hourStep = 1; + minStep = Math.floor(60 / timeInterval); + } + + for (let hour = startHour; hour < endHour; hour += hourStep) { + for (let interval = 0; interval < 60; interval += minStep) { let row:IWeekViewRow[] = []; for (let day = 0; day < 7; day += 1) { let time = new Date(startTime.getTime()); - time.setHours(currentHour + hour, 60 * interval / timeInterval); + time.setHours(currentHour + hour, interval); time.setDate(currentDate + day); row.push({ events: [], From dacfdbe24706c343785b6faeba2182ed52a400a6 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 9 Sep 2018 20:08:27 +0800 Subject: [PATCH 21/23] clean up the weekview code; add css customization explanation in README --- README.md | 50 +++++++++++++++++++++++++--- package.json | 2 +- src/weekview.ts | 87 +++++++++++++++++-------------------------------- 3 files changed, 76 insertions(+), 63 deletions(-) diff --git a/README.md b/README.md index adcbfd09..fa8075c4 100644 --- a/README.md +++ b/README.md @@ -349,6 +349,46 @@ The callback function triggered when the view title is changed }; ``` # View Customization Option +There are two ways to customize the look and feel. If you just want to simply change the color or size of certain element, you could override the styles of the predefined css classes. *CSS Customization* section lists some important css classes. If you need to change the layout of certain element, you could refer to the *Template Customization* part. + +## CSS Customization + +* monthview-primary-with-event +The date that is in current month and having events + +* monthview-secondary-with-event +The date that is in previous/next month and having events + +* monthview-selected +The selected date + +* monthview-current +The current date + +* monthview-disabled +The disabled date + +* weekview-with-event +The date having all day events, applied to the day header in week view + +* week-view-current +The current date, applied to the day header in week view + +* weekview-selected +The selected date, applied to the day header in week view + +* weekview-allday-label +Applied to the all day label in week view + +* dayview-allday-label +Applied to the all day label in day view + +* calendar-hour-column +Applied to the hour column in both weekview and day view + + +## Template Customization + Note: For any css class appear in the customized template, you need to specify the styles by yourself. The styles defined in the calendar component won’t be applied because of the view encapsulation. You could refer to calendar.ts to get the definition of context types. * monthviewDisplayEventTemplate @@ -381,7 +421,7 @@ The template provides customized view for event detail section in the monthview ``` -* weekviewHeaderTemplate +* weekviewHeaderTemplate (version >= 0.4.5) Type: TemplateRef\ The template provides customized view for day header in the weekview ``` html @@ -438,7 +478,7 @@ The template provides customized view for normal event in the dayview * weekviewAllDayEventSectionTemplate (version >= 0.3) Type: TemplateRef\ -The template provides customized view for all day event section in the weekview +The template provides customized view for all day event section (table part) in the weekview ``` html @@ -459,7 +499,7 @@ The template provides customized view for all day event section in the weekview * weekviewNormalEventSectionTemplate (version >= 0.3) Type: TemplateRef\ -The template provides customized view for normal event section in the weekview +The template provides customized view for normal event section (table part) in the weekview ``` html @@ -479,7 +519,7 @@ The template provides customized view for normal event section in the weekview * dayviewAllDayEventSectionTemplate (version >= 0.3) Type: TemplateRef\ -The template provides customized view for all day event section in the dayview +The template provides customized view for all day event section (table part) in the dayview ``` html @@ -498,7 +538,7 @@ The template provides customized view for all day event section in the dayview * dayviewNormalEventSectionTemplate (version >= 0.3) Type: TemplateRef\ -The template provides customized view for normal event section in the dayview +The template provides customized view for normal event section (table part) in the dayview ``` html diff --git a/package.json b/package.json index 63743d88..71a875a8 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.4.4", + "version": "0.4.5", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/weekview.ts b/src/weekview.ts index d174e09f..6b30021a 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -360,28 +360,6 @@ import { IDisplayAllDayEvent, IWeekViewAllDayEventSectionTemplateContext, IWeekV overflow: hidden; white-space: nowrap; font-size: 14px; - /* cursor: pointer; */ - } - - .weekview-header th.weekview-with-event { - /* background-color: #3a87ad; */ - /* color: white; */ - } - - .weekview-header th.weekview-current { - /* background-color: #f0f0f0; */ - } - - .weekview-header th.weekview-with-event.weekview-current { - /* color: #000; */ - } - - .weekview-header th.weekview-selected { - /* background-color: #009900; */ - /* color: white; */ - } - .weekview-header th.weekview-with-event.weekview-current.weekview-selected { - /* color: white; */ } .weekview-allday-table { @@ -498,7 +476,6 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges public views:IWeekView[] = []; public currentViewIndex = 0; - public selectedDate:IWeekViewDateRow; public range:IRange; public direction = 0; public mode:CalendarMode = 'week'; @@ -933,32 +910,30 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges if (this.autoSelect) { let findSelected = false; + let selectedDate; for (let r = 0; r < 7; r += 1) { if (dates[r].selected) { - this.selectedDate = dates[r]; + selectedDate = dates[r]; findSelected = true; break; } } if (findSelected) { + let disabled = false; + if (this.markDisabled) { + disabled = this.markDisabled(selectedDate.date); + } + this.onTimeSelected.emit({ - selectedTime: this.selectedDate.date, - events: this.convertDisplayEventsInEvents(this.selectedDate.events), - disabled: false + selectedTime: selectedDate.date, + events: selectedDate.events.map(e => e.event), + disabled: disabled }); } } } - convertDisplayEventsInEvents(displayEvents: IDisplayEvent[]): IEvent[] { - let events:IEvent[] = []; - for (let i = 0; i < displayEvents.length; i += 1) { - events.push(displayEvents[i].event); - } - return events; - } - refreshView() { this.range = this.getRange(this.calendarService.currentDate); @@ -1145,15 +1120,8 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges view.dates[r].selected = false; } - if (selectedDayDifference >= 0 && selectedDayDifference < 7 && (this.autoSelect)) { + if (selectedDayDifference >= 0 && selectedDayDifference < 7 && this.autoSelect) { view.dates[selectedDayDifference].selected = true; - this.selectedDate = view.dates[selectedDayDifference]; - } else { - this.selectedDate = { - date: null, - events: [], - dayHeader: '' - }; } if (currentDayDifference >= 0 && currentDayDifference < 7) { @@ -1161,24 +1129,29 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } } - eventSelected(event:IEvent) { - this.onEventSelected.emit(event); - let date = new Date(event.startTime.getTime()); - date.setHours(12); - this.daySelected({ - date: date, - events: [], - dayHeader: '' - }); - } - daySelected(viewDate:IWeekViewDateRow) { let selectedDate = viewDate.date, - events = viewDate.events; + dates = this.views[this.currentViewIndex].dates, + currentViewStartDate = this.range.startTime, + oneDay = 86400000, + selectedDayDifference = Math.floor((selectedDate.getTime() - currentViewStartDate.getTime() - (selectedDate.getTimezoneOffset() - currentViewStartDate.getTimezoneOffset()) * 60000) / oneDay); this.calendarService.setCurrentDate(selectedDate); - this.refreshView(); - this.direction = 0; + + for (let r = 0; r < 7; r += 1) { + dates[r].selected = false; + } + + if (selectedDayDifference >= 0 && selectedDayDifference < 7) { + dates[selectedDayDifference].selected = true; + } + + let disabled = false; + if (this.markDisabled) { + disabled = this.markDisabled(selectedDate); + } + + this.onTimeSelected.emit({selectedTime: selectedDate, events: viewDate.events.map(e => e.event), disabled: disabled}); } setScrollPosition(scrollPosition:number) { From 45e1492ee4d08e9117ce749aa589b25848a7cc62 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 18 Nov 2018 13:51:38 +0800 Subject: [PATCH 22/23] fix lockSwipes bug in weekview --- src/weekview.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/weekview.ts b/src/weekview.ts index 6b30021a..18c20bc5 100644 --- a/src/weekview.ts +++ b/src/weekview.ts @@ -570,7 +570,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.slider.lockSwipeToPrev(lockSwipeToPrev.currentValue); } - let lockSwipes = changes['lockSwipesv']; + let lockSwipes = changes['lockSwipes']; if (lockSwipes) { this.slider.lockSwipes(lockSwipes.currentValue); } From fa2e08cb4532bc7bb4f6c093f3c3e2d43c825dde Mon Sep 17 00:00:00 2001 From: twinssbc Date: Sun, 18 Nov 2018 13:52:01 +0800 Subject: [PATCH 23/23] update version for release --- README.md | 2 +- package.json | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/README.md b/README.md index fa8075c4..c8b93d82 100644 --- a/README.md +++ b/README.md @@ -349,7 +349,7 @@ The callback function triggered when the view title is changed }; ``` # View Customization Option -There are two ways to customize the look and feel. If you just want to simply change the color or size of certain element, you could override the styles of the predefined css classes. *CSS Customization* section lists some important css classes. If you need to change the layout of certain element, you could refer to the *Template Customization* part. +There are two ways to customize the look and feel. If you just want to simply change the color or size of certain element, you could override the styles of the predefined css classes. **CSS Customization** section lists some important css classes. If you need to change the layout of certain element, you could refer to the **Template Customization** part. ## CSS Customization diff --git a/package.json b/package.json index 71a875a8..271f18bd 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.4.5", + "version": "0.4.6", "description": "Ionic2 calendar component", "keywords": [ "Ionic2",
{{dayHeader}} + + +
{{dayHeader}} + + +
{{dayHeader}} + + +
+ @@ -105,7 +107,9 @@ import { IDisplayAllDayEvent } from "./calendar";
+ @@ -194,7 +198,9 @@ import { IDisplayAllDayEvent } from "./calendar";
+ @@ -389,6 +395,28 @@ import { IDisplayAllDayEvent } from "./calendar"; overflow: hidden; white-space: nowrap; font-size: 14px; + /* cursor: pointer; */ + } + + .weekview-header th.weekview-with-event { + /* background-color: #3a87ad; */ + /* color: white; */ + } + + .weekview-header th.weekview-current { + /* background-color: #f0f0f0; */ + } + + .weekview-header th.weekview-with-event.weekview-current { + /* color: #000; */ + } + + .weekview-header th.weekview-selected { + /* background-color: #009900; */ + /* color: white; */ + } + .weekview-header th.weekview-with-event.weekview-current.weekview-selected { + /* color: white; */ } .weekview-allday-table { @@ -482,6 +510,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges @Input() allDayLabel:string; @Input() hourParts:number; @Input() eventSource:IEvent[]; + @Input() autoSelect:boolean = true; @Input() markDisabled:(date:Date) => boolean; @Input() locale:string; @Input() dateFormatter:IDateFormatter; @@ -501,6 +530,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges public views:IWeekView[] = []; public currentViewIndex = 0; + public selectedDate:IWeekViewDateRow; public range:IRange; public direction = 0; public mode:CalendarMode = 'week'; @@ -746,6 +776,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges for (let i = 0; i < 7; i += 1) { dates[i].events = []; + dates[i].hasEvent = false; } for (let day = 0; day < 7; day += 1) { @@ -792,6 +823,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges eventSet.push(displayAllDayEvent); dates[allDayStartIndex].events = eventSet; } + dates[allDayStartIndex].hasEvent = true; } } else { if (eventEndTime <= startTime || eventStartTime >= endTime) { @@ -874,6 +906,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges eventSet.push(displayEvent); rows[startRowIndex][dayIndex].events = eventSet; } + dates[dayIndex].hasEvent = true; } startRowIndex = 0; startOffset = 0; @@ -909,6 +942,33 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.placeAllDayEvents(orderedAllDayEvents); } } + + if (this.autoSelect) { + let findSelected = false; + for (let r = 0; r < 7; r += 1) { + if (dates[r].selected) { + this.selectedDate = dates[r]; + findSelected = true; + break; + } + } + + if (findSelected) { + this.onTimeSelected.emit({ + selectedTime: this.selectedDate.date, + events: this.convertDisplayEventsInEvents(this.selectedDate.events), + disabled: false + }); + } + } + } + + convertDisplayEventsInEvents(displayEvents: IDisplayEvent[]): IEvent[] { + let events:IEvent[] = []; + for (let i = 0; i < displayEvents.length; i += 1) { + events.push(displayEvents[i].event); + } + return events; } refreshView() { @@ -919,6 +979,7 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges this.onTitleChanged.emit(title); } this.calendarService.populateAdjacentViews(this); + this.updateCurrentView(this.range.startTime, this.views[this.currentViewIndex]); this.calendarService.rangeChanged(this); } @@ -928,6 +989,33 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges return this.formatTitle(firstDayOfWeek); } + getHighlightClass(date: IWeekViewDateRow):string { + let className = ''; + + if (date.hasEvent) { + if (className) { + className += ' '; + } + className = 'weekview-with-event'; + } + + if (date.selected) { + if (className) { + className += ' '; + } + className += 'weekview-selected'; + } + + if (date.current) { + if (className) { + className += ' '; + } + className += 'weekview-current'; + } + + return className; + } + private static compareEventByStartOffset(eventA:IDisplayEvent, eventB:IDisplayEvent):number { return eventA.startOffset - eventB.startOffset; } @@ -1058,8 +1146,51 @@ export class WeekViewComponent implements ICalendarComponent, OnInit, OnChanges } } + updateCurrentView(currentViewStartDate:Date, view:IWeekView) { + let 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 (let r = 0; r < 7; r += 1) { + view.dates[r].selected = false; + } + + if (selectedDayDifference >= 0 && selectedDayDifference < 7 && (this.autoSelect)) { + view.dates[selectedDayDifference].selected = true; + this.selectedDate = view.dates[selectedDayDifference]; + } else { + this.selectedDate = { + date: null, + events: [], + dayHeader: '' + }; + } + + if (currentDayDifference >= 0 && currentDayDifference < 7) { + view.dates[currentDayDifference].current = true; + } + } + eventSelected(event:IEvent) { this.onEventSelected.emit(event); + let date = new Date(event.startTime.getTime()); + date.setHours(12); + this.daySelected({ + date: date, + events: [], + dayHeader: '' + }); + } + + daySelected(viewDate:IWeekViewDateRow) { + let selectedDate = viewDate.date, + events = viewDate.events; + + this.calendarService.setCurrentDate(selectedDate); + this.refreshView(); + this.direction = 0; } setScrollPosition(scrollPosition:number) { From 8a4bcbc587340b626ea21c1765ff268168ad4903 Mon Sep 17 00:00:00 2001 From: twinssbc Date: Thu, 15 Mar 2018 22:52:36 +0800 Subject: [PATCH 19/23] add timeInterval option; add more custom template option in weekview and dayview; fix logic to handle edge case when calculating the event position in weekview; --- README.md | 142 +++++++++++++++++++++++++++++++++++++++------- package.json | 2 +- src/calendar.ts | 71 +++++++++++++++++++++++ src/dayview.ts | 120 +++++++++++++++------------------------ src/weekview.ts | 148 +++++++++++++++++++++--------------------------- 5 files changed, 303 insertions(+), 180 deletions(-) diff --git a/README.md b/README.md index 8f29dcb7..4a5dc42b 100644 --- a/README.md +++ b/README.md @@ -147,8 +147,20 @@ If queryMode is set to 'remote', when the range or mode is changed, the calendar Users will need to implement their custom loading data logic in this function, and fill it into the eventSource. The eventSource is watched, so the view will be updated once the eventSource is changed. Default value: 'local' * step -It can be set to 15 or 30, so that the event can be displayed at more accurate position in weekview or dayview. +It is used to display the event using more accurate time interval in weekview and dayview. For example, if set to 30, then the event will only occupy half of the row height (If timeInterval option uses default value). The unit is minute. It can be set to 15 or 30. Default value: 60 +``` html + +``` + +* timeInterval (version >= 0.3) +It is used to display the rows using more accurate time interval in weekview and dayview. For example, if set to 30, then the time interval between each row is 30 mins. +The unit is minute. It should be the factor or multiple of 60, which means 60%timeInterval=0 or timeInterval%60=0. +Default value: 60 +``` html + +``` + * autoSelect If set to true, the current calendar date will be auto selected when calendar is loaded or swiped in the month view. Default value: true @@ -258,12 +270,14 @@ Default value: false },100); } ``` + * startHour Limit the weekview and dayview starts from which hour (0-23). Default value: 0 ``` html ``` + * endHour Limit the weekview and dayview ends until which hour (1-24). Default value: 24 @@ -328,15 +342,15 @@ The callback function triggered when the view title is changed ``` # View Customization Option -Note: For any css class appear in the customized template, you need to specify the styles by yourself. The styles defined in the calendar component won’t be applied because of the view encapsulation. +Note: For any css class appear in the customized template, you need to specify the styles by yourself. The styles defined in the calendar component won’t be applied because of the view encapsulation. You could refer to calendar.ts to get the definition of context types. * monthviewDisplayEventTemplate Type: TemplateRef\ The template provides customized view for event displayed in the active monthview ``` html - + ``` @@ -344,9 +358,9 @@ The template provides customized view for event displayed in the active monthvie Type: TemplateRef\ The template provides customized view for event displayed in the inactive monthview ``` html - + ``` @@ -354,9 +368,9 @@ The template provides customized view for event displayed in the inactive monthv Type: TemplateRef\ The template provides customized view for event detail section in the monthview ``` html - + ``` @@ -364,9 +378,9 @@ The template provides customized view for event detail section in the monthview Type: TemplateRef\ The template provides customized view for all day event in the weekview ``` html - + ``` @@ -375,37 +389,116 @@ Type: TemplateRef\ The template provides customized view for normal event in the weekview ``` html - + ``` -* dayviewAllDayEventTemplate     +* dayviewAllDayEventTemplate Type: TemplateRef\ The template provides customized view for all day event in the dayview - ``` html - + ``` -* dayviewNormalEventTemplate     +* dayviewNormalEventTemplate Type: TemplateRef\ The template provides customized view for normal event in the dayview -``` javascript - +         ``` +* weekviewAllDayEventSectionTemplate (version >= 0.3) +Type: TemplateRef\ +The template provides customized view for all day event section in the weekview + +``` html + +
+
+ + +
+
+
+ +         +``` + +* weekviewNormalEventSectionTemplate (version >= 0.3) +Type: TemplateRef\ +The template provides customized view for normal event section in the weekview + +``` html + +
+
+ + +
+
+
+ +         +``` + +* dayviewAllDayEventSectionTemplate (version >= 0.3) +Type: TemplateRef\ +The template provides customized view for all day event section in the dayview + +``` html + +
+ + +
+
+ +         +``` + +* dayviewNormalEventSectionTemplate (version >= 0.3) +Type: TemplateRef\ +The template provides customized view for normal event section in the dayview + +``` html + +
+
+ + +
+
+
+ +         +``` + # EventSource EventSource is an array of event object which contains at least below fields: @@ -513,4 +606,11 @@ Answer: This calendar has dependency on 'Intl'. Run *npm install intl@1.2.5* to Answer: If you bind currentDate like this: [currentDate]="calendar.currentDate". You need to assign calendar.currentDate a valid Date object * How to switch the calendar to previous/next month programmatically? -Answer: You can change currentDate to the date in previous/next month. +Answer: You can change currentDate to the date in previous/next month. You could also retrieve the Swiper element and then call the Swiper API directly. +``` +var mySwiper = document.querySelector('.swiper-container')['swiper']; + mySwiper.slideNext(); +``` + +* Error: Cannot read property 'dayHeaders' of undefined +Answer: Take a look at the Localization section. For version 0.4.x, you need to manually register the locale. \ No newline at end of file diff --git a/package.json b/package.json index 2e29fe4e..488efdaa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "ionic2-calendar", - "version": "0.4.2", + "version": "0.4.3", "description": "Ionic2 calendar component", "keywords": [ "Ionic2", diff --git a/src/calendar.ts b/src/calendar.ts index e83adf24..f0f28313 100644 --- a/src/calendar.ts +++ b/src/calendar.ts @@ -104,6 +104,26 @@ export interface IMonthViewEventDetailTemplateContext { noEventsLabel: string } +export interface IWeekViewAllDayEventSectionTemplateContext { + day: IWeekViewDateRow, + eventTemplate: TemplateRef +} + +export interface IWeekViewNormalEventSectionTemplateContext { + tm: IWeekViewRow, + eventTemplate: TemplateRef +} + +export interface IDayViewAllDayEventSectionTemplateContext { + alldayEvents: IDisplayAllDayEvent[], + eventTemplate: TemplateRef +} + +export interface IDayViewNormalEventSectionTemplateContext { + tm: IDayViewRow, + eventTemplate: TemplateRef +} + export interface IDateFormatter { formatMonthViewDay?: { (date:Date): string; }; formatMonthViewDayHeader?: { (date:Date): string; }; @@ -152,6 +172,39 @@ export enum Step {
{{displayEvent.event.title}}
+ +
+
+ + +
+
+
+ +
+ + +
+
+ +
+
+ + +
+
+
boolean; @Input() monthviewDisplayEventTemplate:TemplateRef; @@ -313,6 +373,10 @@ export class CalendarComponent implements OnInit { @Input() weekviewNormalEventTemplate:TemplateRef; @Input() dayviewAllDayEventTemplate:TemplateRef; @Input() dayviewNormalEventTemplate:TemplateRef; + @Input() weekviewAllDayEventSectionTemplate:TemplateRef; + @Input() weekviewNormalEventSectionTemplate:TemplateRef; + @Input() dayviewAllDayEventSectionTemplate:TemplateRef; + @Input() dayviewNormalEventSectionTemplate:TemplateRef; @Input() dateFormatter:IDateFormatter; @Input() dir:string = ""; @Input() scrollToHour:number = 0; @@ -332,6 +396,7 @@ export class CalendarComponent implements OnInit { private _currentDate:Date; private hourParts = 1; + private hourSegments = 1; private currentDateChangedFromChildrenSubscription:Subscription; constructor(private calendarService:CalendarService, @Inject(LOCALE_ID) private appLocale:string) { @@ -346,7 +411,13 @@ export class CalendarComponent implements OnInit { this.autoSelect = true; } } + this.hourSegments = 60 / this.timeInterval; this.hourParts = 60 / this.step; + if(this.hourParts <= this.hourSegments) { + this.hourParts = 1; + } else { + this.hourParts = this.hourParts / this.hourSegments; + } this.startHour = parseInt(this.startHour.toString()); this.endHour = parseInt(this.endHour.toString()); this.calendarService.queryMode = this.queryMode; diff --git a/src/dayview.ts b/src/dayview.ts index 2422ea63..0359d987 100644 --- a/src/dayview.ts +++ b/src/dayview.ts @@ -5,7 +5,7 @@ import { Subscription } from 'rxjs/Subscription'; import { ICalendarComponent, IDayView, IDayViewRow, IDisplayEvent, IEvent, ITimeSelected, IRange, CalendarMode, IDateFormatter } from './calendar'; import { CalendarService } from './calendar.service'; -import { IDisplayAllDayEvent } from "./calendar"; +import { IDisplayAllDayEvent, IDayViewAllDayEventSectionTemplateContext, IDayViewNormalEventSectionTemplateContext } from "./calendar"; @Component({ selector: 'dayview', @@ -21,14 +21,9 @@ import { IDisplayAllDayEvent } from "./calendar";
-
- - -
+ +
-
-
- - -
-
+ +
-
- - -
+ +
-
-
- - -
-
+ +
-
- - -
+ +
-
-
- - -
-
+ +
-
-
- - -
-
+ +
-
-
- - -
-
+ +
-
-
- - -
-
+ +
-
- - -
+ +
-
-
- - -
-
+ +
-
- - -
+ +