Skip to content

Commit eb6f73b

Browse files
author
Matt Lewis
committed
docs(demos): show how removed allowDragOutside option can be implemented in userland
Closes #229 Closes #232
1 parent ced3e29 commit eb6f73b

File tree

4 files changed

+176
-17
lines changed

4 files changed

+176
-17
lines changed

demos/demo-modules/draggable-external-events/component.ts

+159-12
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,136 @@
1-
import { Component, ChangeDetectionStrategy } from '@angular/core';
2-
import { CalendarEvent, CalendarEventTimesChangedEvent } from 'angular-calendar';
1+
import { Component, ChangeDetectionStrategy, EventEmitter, Output } from '@angular/core';
2+
import {
3+
CalendarEvent,
4+
CalendarEventTimesChangedEvent,
5+
CalendarWeekViewComponent,
6+
CalendarUtils,
7+
CalendarWeekViewEvent,
8+
CalendarGetWeekViewArgs,
9+
CalendarWeekViewEventRow
10+
} from 'angular-calendar';
11+
import { Subject } from 'rxjs/Subject';
12+
import addDays from 'date-fns/add_days';
13+
import differenceInDays from 'date-fns/difference_in_days';
14+
import startOfDay from 'date-fns/start_of_day';
315
import { colors } from '../demo-utils/colors';
416

17+
interface MyCalendarEventTimesChangedEvent extends CalendarEventTimesChangedEvent {
18+
droppedOutsideCalendar?: boolean;
19+
}
20+
21+
export class MyCalendarUtils extends CalendarUtils {
22+
23+
getWeekView(args: CalendarGetWeekViewArgs): CalendarWeekViewEventRow[] {
24+
args.absolutePositionedEvents = true;
25+
return super.getWeekView(args);
26+
}
27+
28+
}
29+
30+
@Component({
31+
selector: 'drag-events-outside-week-view-component', // tslint:disable-line
32+
template: `
33+
<div class="cal-week-view" #weekViewContainer>
34+
<mwl-calendar-week-view-header
35+
[days]="days"
36+
[locale]="locale"
37+
[customTemplate]="headerTemplate"
38+
(dayClicked)="dayClicked.emit($event)"
39+
(eventDropped)="eventTimesChanged.emit($event)">
40+
</mwl-calendar-week-view-header>
41+
<div class="cal-events">
42+
<div
43+
*ngFor="let eventRow of eventRows"
44+
#eventRowContainer
45+
class="cal-events-row"
46+
style="height: auto">
47+
<div
48+
class="cal-event-container"
49+
style="position: static"
50+
#event
51+
[class.cal-draggable]="weekEvent.event.draggable"
52+
*ngFor="let weekEvent of eventRow.row"
53+
[style.width]="((100 / days.length) * weekEvent.span) + '%'"
54+
[style.marginLeft]="((100 / days.length) * weekEvent.offset) + '%'"
55+
mwlResizable
56+
[resizeEdges]="{left: weekEvent.event?.resizable?.beforeStart, right: weekEvent.event?.resizable?.afterEnd}"
57+
[resizeSnapGrid]="{left: getDayColumnWidth(eventRowContainer), right: getDayColumnWidth(eventRowContainer)}"
58+
[validateResize]="validateResize"
59+
(resizeStart)="resizeStarted(weekViewContainer, weekEvent, $event)"
60+
(resizing)="resizing(weekEvent, $event, getDayColumnWidth(eventRowContainer))"
61+
(resizeEnd)="resizeEnded(weekEvent)"
62+
mwlDraggable
63+
[dragAxis]="{
64+
x: weekEvent.event.draggable && currentResizes.size === 0,
65+
y: weekEvent.event.draggable && currentResizes.size === 0
66+
}"
67+
[dropData]="{event: weekEvent.event}"
68+
(dragEnd)="eventDragged(weekEvent, $event.x, getDayColumnWidth(eventRowContainer))">
69+
<mwl-calendar-week-view-event
70+
[weekEvent]="weekEvent"
71+
[tooltipPlacement]="tooltipPlacement"
72+
[tooltipTemplate]="tooltipTemplate"
73+
[customTemplate]="eventTemplate"
74+
(eventClicked)="eventClicked.emit({event: weekEvent.event})">
75+
</mwl-calendar-week-view-event>
76+
</div>
77+
</div>
78+
</div>
79+
</div>
80+
`,
81+
providers: [{
82+
provide: CalendarUtils,
83+
useClass: MyCalendarUtils
84+
}]
85+
})
86+
export class DragEventsOutsideWeekViewComponent extends CalendarWeekViewComponent {
87+
88+
@Output() eventTimesChanged: EventEmitter<MyCalendarEventTimesChangedEvent> = new EventEmitter();
89+
90+
eventDragged(weekEvent: CalendarWeekViewEvent, draggedByPx: number, dayWidth: number): void {
91+
92+
let daysDragged: number = Math.round(draggedByPx / dayWidth);
93+
let newStart: Date = addDays(weekEvent.event.start, daysDragged);
94+
let droppedOutsideCalendar: boolean = false;
95+
96+
// Restrict start to first and last day on current week
97+
if (newStart < this.days[0].date) {
98+
daysDragged += differenceInDays(startOfDay(this.days[0].date), startOfDay(newStart));
99+
droppedOutsideCalendar = true;
100+
}
101+
const lastDate: Date = this.days[this.days.length - 1].date;
102+
if (newStart > lastDate) {
103+
daysDragged -= differenceInDays(startOfDay(newStart), startOfDay(lastDate));
104+
droppedOutsideCalendar = true;
105+
}
106+
107+
newStart = addDays(weekEvent.event.start, daysDragged);
108+
let newEnd: Date;
109+
if (weekEvent.event.end) {
110+
newEnd = addDays(weekEvent.event.end, daysDragged);
111+
}
112+
113+
this.eventTimesChanged.emit({newStart, newEnd, event: weekEvent.event, droppedOutsideCalendar});
114+
115+
}
116+
117+
dragStart(weekViewContainer: HTMLElement, event: HTMLElement): void {
118+
119+
event.parentNode.insertBefore(event.cloneNode(), event.nextSibling);
120+
121+
// With a scrollbar during the drag, the event is only visible inside the calendar.
122+
// The "fixed" position bring the event on top, even when dragged outside the calendar.
123+
const eventRect: ClientRect = event.getBoundingClientRect();
124+
event.style.left = eventRect.left + 'px';
125+
event.style.top = eventRect.top + 'px';
126+
event.style.width = eventRect.width + 'px';
127+
event.style.position = 'fixed';
128+
event.style.marginLeft = '';
129+
130+
}
131+
132+
}
133+
5134
@Component({
6135
selector: 'mwl-demo-component',
7136
changeDetection: ChangeDetectionStrategy.OnPush,
@@ -29,18 +158,36 @@ export class DemoComponent {
29158

30159
activeDayIsOpen: boolean = false;
31160

32-
eventDropped({event, newStart, newEnd}: CalendarEventTimesChangedEvent): void {
33-
const externalIndex: number = this.externalEvents.indexOf(event);
34-
if (externalIndex > -1) {
35-
this.externalEvents.splice(externalIndex, 1);
36-
this.events.push(event);
161+
refresh: Subject<any> = new Subject();
162+
163+
eventDropped({event, newStart, newEnd, droppedOutsideCalendar}: MyCalendarEventTimesChangedEvent): void {
164+
165+
if (!droppedOutsideCalendar) {
166+
const externalIndex: number = this.externalEvents.indexOf(event);
167+
if (externalIndex > -1) {
168+
this.externalEvents.splice(externalIndex, 1);
169+
this.events.push(event);
170+
}
171+
event.start = newStart;
172+
if (newEnd) {
173+
event.end = newEnd;
174+
}
175+
this.viewDate = newStart;
176+
this.activeDayIsOpen = true;
37177
}
38-
event.start = newStart;
39-
if (newEnd) {
40-
event.end = newEnd;
178+
179+
}
180+
181+
droppedBack(event: CalendarEvent): void {
182+
183+
const internalIndex: number = this.events.indexOf(event);
184+
185+
if (internalIndex > -1) {
186+
this.events.splice(internalIndex, 1);
187+
this.externalEvents.push(event);
188+
189+
this.refresh.next();
41190
}
42-
this.viewDate = newStart;
43-
this.activeDayIsOpen = true;
44191
}
45192

46193
}

demos/demo-modules/draggable-external-events/module.ts

+5-2
Original file line numberDiff line numberDiff line change
@@ -2,18 +2,21 @@ import { NgModule } from '@angular/core';
22
import { CommonModule } from '@angular/common';
33
import { CalendarModule } from 'angular-calendar';
44
import { DragAndDropModule } from 'angular-draggable-droppable';
5+
import { ResizableModule } from 'angular-resizable-element';
56
import { DemoUtilsModule } from '../demo-utils/module';
6-
import { DemoComponent } from './component';
7+
import { DemoComponent, DragEventsOutsideWeekViewComponent } from './component';
78

89
@NgModule({
910
imports: [
1011
CommonModule,
1112
CalendarModule.forRoot(),
1213
DragAndDropModule,
14+
ResizableModule,
1315
DemoUtilsModule
1416
],
1517
declarations: [
16-
DemoComponent
18+
DemoComponent,
19+
DragEventsOutsideWeekViewComponent
1720
],
1821
exports: [
1922
DemoComponent

demos/demo-modules/draggable-external-events/template.html

+9-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
<div class="row">
22

33
<div class="col-md-3">
4-
<div class="card">
4+
<div
5+
class="card"
6+
mwlDroppable
7+
(drop)="droppedBack($event.dropData.event)">
58
<div class="card-block">
69
<ul>
710
<li
@@ -32,18 +35,21 @@
3235
[viewDate]="viewDate"
3336
[events]="events"
3437
[activeDayIsOpen]="activeDayIsOpen"
38+
[refresh]="refresh"
3539
(eventTimesChanged)="eventDropped($event)">
3640
</mwl-calendar-month-view>
37-
<mwl-calendar-week-view
41+
<drag-events-outside-week-view-component
3842
*ngSwitchCase="'week'"
3943
[viewDate]="viewDate"
4044
[events]="events"
45+
[refresh]="refresh"
4146
(eventTimesChanged)="eventDropped($event)">
42-
</mwl-calendar-week-view>
47+
</drag-events-outside-week-view-component>
4348
<mwl-calendar-day-view
4449
*ngSwitchCase="'day'"
4550
[viewDate]="viewDate"
4651
[events]="events"
52+
[refresh]="refresh"
4753
(eventTimesChanged)="eventDropped($event)">
4854
</mwl-calendar-day-view>
4955
</div>

src/index.ts

+3
Original file line numberDiff line numberDiff line change
@@ -13,5 +13,8 @@ export {
1313
CalendarEvent,
1414
EventAction as CalendarEventAction,
1515
MonthViewDay as CalendarMonthViewDay,
16+
WeekViewEvent as CalendarWeekViewEvent,
17+
WeekViewEventRow as CalendarWeekViewEventRow,
18+
GetWeekViewArgs as CalendarGetWeekViewArgs,
1619
DAYS_OF_WEEK
1720
} from 'calendar-utils';

0 commit comments

Comments
 (0)