Implement Angular Calendar Component: How to Drag & Create Events?
www.bacancytechnology.com
Introduction
Angular Calendar is a component that allows a user to drag and create events in a calendar and also shows events on the month, week, or day view. In this tutorial, we will learn how to implement Angular Calendar component with the feature to drag and create events.
Tutorial Goal: Implement Angular Calendar Component
Before building the demo click the below link to watch video and see what are we going to build.
Video
Create an Angular CLI Project
To install Angular CLI run the below-given command:
npm install -g @angular/cli
Run the following command for creating a new Angular Project:
ng new angular-calendar-demo cd angular-calendar-demo
Install Angular Calendar
Install angular-calendar & date-fns through npm:
npm install angular-calendar date-fns
Adding Angular Calendar to your Application
Import the CSS in global styles of the project i.e. src/styles.css.
@import "../node_modules/angularcalendar/css/angular-calendar.css";
Import angular-calendar & date-fns in the app.module.ts file as shown in the following code.
// app.module.ts import { NgModule } from '@angular/core'; import { BrowserModule } from '@angular/platform-browser'; import { AppRoutingModule } from './approuting.module'; import { AppComponent } from './app.component'; import { CalendarModule, DateAdapter } from 'angular-calendar'; import { adapterFactory } from 'angularcalendar/date-adapters/date-fns'; import { DragCompComponent } from './view/drag-comp/drag-comp.component'; @NgModule({ declarations: [AppComponent, DragCompComponent], imports: [ BrowserModule,
AppRoutingModule, CalendarModule.forRoot({ provide: DateAdapter, useFactory: adapterFactory, }), ], providers: [], bootstrap: [AppComponent], }) export class AppModule {}
Development. Optimization. Maintenance. Everything at Bacancy! Get ready to lessen your struggle! Hire Angular developer from Bacancy today and start developing your dream product! We are here for you!
Create a New Component
ng generate component drag-comp
Use the following TypeScript code: Business Logic
// drag-comp.component.ts <div class="container"> <ng-template #weekViewHourSegmentTemplate let-segment="segment" vent let-locale="locale" letsegmentHeight="segmentHeight" let-isTimeLabel="isTimeLabel" > import { ChangeDetectorRef } from '@angular/core'; import { ChangeDetectionStrategy,
Component, OnInit, ViewEncapsulation, } from '@angular/core'; import { CalendarEvent, CalendarEventTitleFormatter } from 'angular-calendar'; import { WeekViewHourSegment } from 'calendar-utils'; import { addDays, addMinutes, endOfWeek } from 'date-fns'; import { fromEvent } from 'rxjs'; import { finalize, takeUntil } from 'rxjs/operators'; function floorToNearest(amount: number, precision: number) { return Math.floor(amount / precision) * precision; }
@Component({ selector: 'app-drag-comp', templateUrl: './dragcomp.component.html', styleUrls: ['./dragcomp.component.scss'], changeDetection: ChangeDetectionStrategy.OnPush, providers: [ { provide: CalendarEventTitleFormatter, }, ], encapsulation: ViewEncapsulation.None, })
export class DragCompComponent implements OnInit { viewDate = new Date();
weekStartsOn: 0 = 0; dragToCreateActive = false; events: CalendarEvent[] = []; days: any[] = []; slots: any[] = []; constructor(private cdr: ChangeDetectorRef) {} ngOnInit(): void { this.initDays(); } initDays() { this.days = [ 'Sunday', 'Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday',
f ]; for (let i = 0; i < this.days.length; i++) { let a = { day: this.days[i], time: [] }; this.slots.push(a); }; } startDragToCreate( segment: WeekViewHourSegment, mouseDownEvent: MouseEvent, segmentElement: HTMLElement ){ const dragToSelectEvent: CalendarEvent ={ id: this.events.length, title: 'New slot', start: segment.date, meta: { tmpEvent: true,
}, actions: [ { label: '', onClick: ({ event }: { event: CalendarEvent }): void => { this.events = this.events.filter((iEvent) => iEvent !== event); this.removeSlot(event.id); }, }, ], }; this.events = [...this.events, dragToSelectEvent]; const segmentPosition = segmentElement.getBoundingClientRect (); this.dragToCreateActive = true;
const endOfView = endOfWeek(this.viewDate, { weekStartsOn: this.weekStartsOn, }); fromEvent(document, 'mousemove') .pipe( finalize(() => { delete dragToSelectEvent.meta.tmpEvent; this.dragToCreateActive = false; this.refresh(); }), takeUntil(fromEvent(document, 'mouseup')) ) .subscribe((mouseMoveEvent: MouseEvent) => { const minutesDiff = ceilToNearest( mouseMoveEvent.clientY -
segmentPosition.top, 30 ); const daysDiff = floorToNearest( mouseMoveEvent.clientX segmentPosition.left, segmentPosition.width ) / segmentPosition.width; const newEnd = addDays(addMinutes(segment.date, minutesDiff), daysDiff); if (newEnd > segment.date && newEnd < endOfView) { dragToSelectEvent.end = newEnd; } this.refresh(); });
} private refresh() { this.events = [...this.events]; this.cdr.detectChanges(); this.getSlots(); } convertTime(t) { return new Date(t).toTimeString(); } convertDay(d) { return new Date(d).toLocaleString('enus', { weekday: 'long', }); } getSlots() { this.slots.map((day, i) => { this.slots[i].time = [];
this.events.forEach((e) => { if (day.day == this.convertDay(e.start)) { this.slots[i].time.push({ startTime: e.start, endTime: e.end, id: e.id, }); } }); }); } removeSlot(id) { for (let j = 0; j < this.slots.length; j++) { this.slots[j].time = this.slots[j].time.filter((t) => t.id !== id); } } }
Use the following HTML code: User Interface
// drag-comp.component.html <div class="container"> <ng-template #weekViewHourSegmentTemplate let-segment="segment" vent let-locale="locale" letsegmentHeight="segmentHeight" let-isTimeLabel="isTimeLabel" > <div #segmentElement class="cal-hour-segment" [style.height.px]="segmentHeight" [class.cal-hourstart]="segment.isStart"
[class.cal-after-hourstart]="!segment.isStart" [ngClass]="segment.cssClass" (mousedown)="startDragToCreate(s egment, $event, segmentElement)"> <div class="cal-time" *ngIf="isTimeLabel"> {{ segment.date | calendarDate:'weekViewHour':locale }} </div> </div> </ng-template> </div>
<mwl-calendar-week-view [viewDate]="viewDate" [events]="events" [hourSegmentTemplate]="weekVie wHourSegmentTemplate" [weekStartsOn]="weekStartsOn"> </mwl-calendar-week-view> <hr> <div>Selected Slots</div> <pre>{{ slots | json }}</pre>
Run the Application
ng serve
Then, open the following URL in your browser: http://localhost:4200
Github Repository: Angular Calendar Source Code
You can visit the source code and clone the github repository to play around with the code.
Conclusion
So this was all about how to implement Angular Calendar Component in your Angular application. I hope now you can easily create your events and play around with the feature. The Angular Calendar component does provide various useful features we will discuss that surely as well! Want to learn more about Angular? Visit the Angular tutorials page! No doubt, you will love the tutorials that our team has been curated for you! Reach out to us in case you have any suggestions/queries/feedback. We’re always delighted to answer!
Thank You!
www.bacancytechnology.com