Skip to content

Commit fef1b04

Browse files
committed
docs(examples): add example of how to drag to create week view events
Closes #719
1 parent 15fccd0 commit fef1b04

File tree

5 files changed

+230
-0
lines changed

5 files changed

+230
-0
lines changed

src/app/demo-app.module.ts

+8
Original file line numberDiff line numberDiff line change
@@ -273,6 +273,14 @@ import { DemoModule as DefaultDemoModule } from './demo-modules/kitchen-sink/mod
273273
label: 'Day view scheduler'
274274
}
275275
},
276+
{
277+
path: 'drag-to-create-events',
278+
loadChildren:
279+
'./demo-modules/drag-to-create-events/module#DemoModule',
280+
data: {
281+
label: 'Drag to create events'
282+
}
283+
},
276284
{
277285
path: '**',
278286
redirectTo: 'kitchen-sink'
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,119 @@
1+
import {
2+
ChangeDetectionStrategy,
3+
ChangeDetectorRef,
4+
Component,
5+
ViewEncapsulation
6+
} from '@angular/core';
7+
import {
8+
CalendarEvent,
9+
CalendarEventTitleFormatter,
10+
CalendarView
11+
} from 'angular-calendar';
12+
import { DayViewHourSegment } from 'calendar-utils';
13+
import { fromEvent } from 'rxjs';
14+
import { finalize, takeUntil } from 'rxjs/operators';
15+
import { addDays, addMinutes, endOfWeek } from 'date-fns';
16+
17+
function floorToNearest(amount: number, precision: number) {
18+
return Math.floor(amount / precision) * precision;
19+
}
20+
21+
function ceilToNearest(amount: number, precision: number) {
22+
return Math.ceil(amount / precision) * precision;
23+
}
24+
25+
export class CustomEventTitleFormatter extends CalendarEventTitleFormatter {
26+
weekTooltip(event: CalendarEvent, title: string) {
27+
if (!event.meta.tmpEvent) {
28+
return super.weekTooltip(event, title);
29+
}
30+
}
31+
32+
dayTooltip(event: CalendarEvent, title: string) {
33+
if (!event.meta.tmpEvent) {
34+
return super.dayTooltip(event, title);
35+
}
36+
}
37+
}
38+
39+
// tslint:disable-next-line max-classes-per-file
40+
@Component({
41+
selector: 'mwl-demo-component',
42+
changeDetection: ChangeDetectionStrategy.OnPush,
43+
templateUrl: 'template.html',
44+
providers: [
45+
{
46+
provide: CalendarEventTitleFormatter,
47+
useClass: CustomEventTitleFormatter
48+
}
49+
],
50+
styles: [
51+
`
52+
.disable-hover {
53+
pointer-events: none;
54+
}
55+
`
56+
],
57+
encapsulation: ViewEncapsulation.None
58+
})
59+
export class DemoComponent {
60+
viewDate = new Date();
61+
62+
events: CalendarEvent[] = [];
63+
64+
dragToCreateActive = false;
65+
66+
constructor(private cdr: ChangeDetectorRef) {}
67+
68+
startDragToCreate(
69+
segment: DayViewHourSegment,
70+
mouseDownEvent: MouseEvent,
71+
segmentElement: HTMLElement
72+
) {
73+
const dragToSelectEvent: CalendarEvent = {
74+
id: this.events.length,
75+
title: 'New event',
76+
start: segment.date,
77+
meta: {
78+
tmpEvent: true
79+
}
80+
};
81+
this.events = [...this.events, dragToSelectEvent];
82+
const segmentPosition = segmentElement.getBoundingClientRect();
83+
this.dragToCreateActive = true;
84+
const endOfView = endOfWeek(this.viewDate);
85+
86+
fromEvent(document, 'mousemove')
87+
.pipe(
88+
finalize(() => {
89+
delete dragToSelectEvent.meta.tmpEvent;
90+
this.dragToCreateActive = false;
91+
this.refresh();
92+
}),
93+
takeUntil(fromEvent(document, 'mouseup'))
94+
)
95+
.subscribe((mouseMoveEvent: MouseEvent) => {
96+
const minutesDiff = ceilToNearest(
97+
mouseMoveEvent.clientY - segmentPosition.top,
98+
30
99+
);
100+
101+
const daysDiff =
102+
floorToNearest(
103+
mouseMoveEvent.clientX - segmentPosition.left,
104+
segmentPosition.width
105+
) / segmentPosition.width;
106+
107+
const newEnd = addDays(addMinutes(segment.date, minutesDiff), daysDiff);
108+
if (newEnd > segment.date && newEnd < endOfView) {
109+
dragToSelectEvent.end = newEnd;
110+
}
111+
this.refresh();
112+
});
113+
}
114+
115+
private refresh() {
116+
this.events = [...this.events];
117+
this.cdr.detectChanges();
118+
}
119+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import { NgModule } from '@angular/core';
2+
import { CommonModule } from '@angular/common';
3+
import { RouterModule } from '@angular/router';
4+
import { CalendarModule, DateAdapter } from 'angular-calendar';
5+
import { adapterFactory } from 'angular-calendar/date-adapters/date-fns';
6+
import { DemoComponent } from './component';
7+
import { DemoUtilsModule } from '../demo-utils/module';
8+
9+
@NgModule({
10+
imports: [
11+
CommonModule,
12+
CalendarModule.forRoot({
13+
provide: DateAdapter,
14+
useFactory: adapterFactory
15+
}),
16+
DemoUtilsModule,
17+
RouterModule.forChild([{ path: '', component: DemoComponent }])
18+
],
19+
declarations: [DemoComponent],
20+
exports: [DemoComponent]
21+
})
22+
export class DemoModule {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export const sources = [
2+
{
3+
filename: 'component.ts',
4+
contents: {
5+
raw: require('!!raw-loader!./component'),
6+
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./component')
7+
}
8+
},
9+
{
10+
filename: 'template.html',
11+
contents: {
12+
raw: require('!!raw-loader!./template.html'),
13+
highlighted: require('!!raw-loader!highlightjs-loader?lang=xml!./template.html')
14+
}
15+
},
16+
{
17+
filename: 'module.ts',
18+
contents: {
19+
raw: require('!!raw-loader!./module'),
20+
highlighted: require('!!raw-loader!highlightjs-loader?lang=typescript!./module')
21+
}
22+
}
23+
];
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
<div class="row">
2+
<div class="col-md-6">
3+
<div class="btn-group">
4+
<div
5+
class="btn btn-primary"
6+
mwlCalendarPreviousView
7+
[view]="'day'"
8+
[(viewDate)]="viewDate">
9+
Previous
10+
</div>
11+
<div
12+
class="btn btn-outline-secondary"
13+
mwlCalendarToday
14+
[(viewDate)]="viewDate">
15+
Today
16+
</div>
17+
<div
18+
class="btn btn-primary"
19+
mwlCalendarNextView
20+
[view]="'day'"
21+
[(viewDate)]="viewDate">
22+
Next
23+
</div>
24+
</div>
25+
</div>
26+
<div class="col-md-6 text-right">
27+
<h3>{{ viewDate | calendarDate:('weekViewTitle') }}</h3>
28+
</div>
29+
</div>
30+
<br>
31+
32+
<ng-template
33+
#weekViewHourSegmentTemplate
34+
let-segment="segment"
35+
let-locale="locale"
36+
let-segmentHeight="segmentHeight"
37+
let-isTimeLabel="isTimeLabel">
38+
<div
39+
#segmentElement
40+
class="cal-hour-segment"
41+
[style.height.px]="segmentHeight"
42+
[class.cal-hour-start]="segment.isStart"
43+
[class.cal-after-hour-start]="!segment.isStart"
44+
[ngClass]="segment.cssClass"
45+
(mousedown)="startDragToCreate(segment, $event, segmentElement)"
46+
>
47+
<div class="cal-time" *ngIf="isTimeLabel">
48+
{{ segment.date | calendarDate:'weekViewHour':locale }}
49+
</div>
50+
</div>
51+
</ng-template>
52+
53+
<mwl-calendar-week-view
54+
[viewDate]="viewDate"
55+
[events]="events"
56+
[hourSegmentTemplate]="weekViewHourSegmentTemplate"
57+
>
58+
</mwl-calendar-week-view>

0 commit comments

Comments
 (0)