Top

Calender

With a busy schedule, users might need something to keep track of the upcoming events. A calendar app has been provided, where users can enter the upcoming events and a tag will be added in the calendar. Now you don't have to worry whether you will remember the next scheduled meeting.


Installing and usage

ng add angular-calendar

Inside Your Template tag add:

<mwl-calendar-month-view *ngSwitchCase="CalendarView.Month" [viewDate]="viewDate" [events]="events" 
[refresh]="refresh" [activeDayIsOpen]="activeDayIsOpen" (dayClicked)="dayClicked($event.day)" 
(eventClicked)="handleEvent('Clicked', $event.event)" (eventTimesChanged)="eventTimesChanged($event)">
</mwl-calendar-month-view>

Inside Your Script tag add:


    import { Component, inject, TemplateRef, viewChild } from '@angular/core';
    import { FormsModule } from '@angular/forms';
    
    import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
    import {
      CalendarCommonModule,
      CalendarDayModule,
      CalendarEvent,
      CalendarEventAction,
      CalendarEventTimesChangedEvent,
      CalendarMonthModule,
      CalendarView,
      CalendarWeekModule,
    } from 'angular-calendar';
    import { FlatpickrModule } from 'angularx-flatpickr';
    import { EventColor } from 'calendar-utils';
    import {
      addDays,
      addHours,
      endOfDay,
      endOfMonth,
      isSameDay,
      isSameMonth,
      startOfDay,
      subDays,
    } from 'date-fns';
    import { Subject } from 'rxjs';
    
    const colors: Record = {
      red: {
        primary: '#ad2121',
        secondary: '#FAE3E3',
      },
      blue: {
        primary: '#1e90ff',
        secondary: '#D1E8FF',
      },
      yellow: {
        primary: '#e3bc08',
        secondary: '#FDF1BA',
      },
    };
    
    @Component({
      selector: 'app-calender',
      templateUrl: './calender.html',
      styleUrls: ['./calender.scss'],
      imports: [
        CalendarCommonModule,
        CalendarMonthModule,
        CalendarWeekModule,
        CalendarDayModule,
        FormsModule,
        FlatpickrModule,
        JsonPipe,
      ],
    })
    export class Calender {
      private modal = inject(NgbModal);
      public readonly modalContent = viewChild.required>('modalContent');
      public view: CalendarView = CalendarView.Month;
      public CalendarView = CalendarView;
      public viewDate: Date = new Date();
    
      modalData!: {
        action: string;
        event: CalendarEvent;
      };
    
      actions: CalendarEventAction[] = [
        {
          label: '',
          a11yLabel: 'Edit',
          onClick: ({ event }: { event: CalendarEvent }): void => {
            this.handleEvent('Edited', event);
          },
        },
        {
          label: '',
          a11yLabel: 'Delete',
          onClick: ({ event }: { event: CalendarEvent }): void => {
            this.events = this.events.filter(iEvent => iEvent !== event);
            this.handleEvent('Deleted', event);
          },
        },
      ];
    
      refresh = new Subject();
    
      events: CalendarEvent[] = [
        {
          start: subDays(startOfDay(new Date()), 1),
          end: addDays(new Date(), 1),
          title: 'A 3 day event',
          color: {
            primary: '#ad2121',
            secondary: '#FAE3E3',
          },
          actions: this.actions,
          allDay: true,
          resizable: {
            beforeStart: true,
            afterEnd: true,
          },
          draggable: true,
        },
        {
          start: startOfDay(new Date()),
          title: 'An event with no end date',
          color: { ...colors['yellow'] },
          actions: this.actions,
        },
        {
          start: subDays(endOfMonth(new Date()), 3),
          end: addDays(endOfMonth(new Date()), 3),
          title: 'A long event that spans 2 months',
          color: { ...colors['blue'] },
          allDay: true,
        },
        {
          start: addHours(startOfDay(new Date()), 2),
          end: addHours(new Date(), 2),
          title: 'A draggable and resizable event',
          color: { ...colors['yellow'] },
          actions: this.actions,
          resizable: {
            beforeStart: true,
            afterEnd: true,
          },
          draggable: true,
        },
      ];
    
      activeDayIsOpen: boolean = true;
      color: string;
    
      dayClicked({ date, events }: { date: Date; events: CalendarEvent[] }): void {
        if (isSameMonth(date, this.viewDate)) {
          if (
            (isSameDay(this.viewDate, date) && this.activeDayIsOpen === true) ||
            events.length === 0
          ) {
            this.activeDayIsOpen = false;
          } else {
            this.activeDayIsOpen = true;
          }
          this.viewDate = date;
        }
      }
    
      eventTimesChanged({ event, newStart, newEnd }: CalendarEventTimesChangedEvent): void {
        this.events = this.events.map(iEvent => {
          if (iEvent === event) {
            return {
              ...event,
              start: newStart,
              end: newEnd,
            };
          }
          return iEvent;
        });
        this.handleEvent('Dropped or resized', event);
      }
    
      handleEvent(action: string, event: CalendarEvent): void {
        this.modalData = { event, action };
        this.modal.open(this.modalContent(), { size: 'lg' });
      }
    
      addEvent(): void {
        this.events = [
          ...this.events,
          {
            title: 'New event',
            start: startOfDay(new Date()),
            end: endOfDay(new Date()),
            color: colors['red'],
            draggable: true,
            resizable: {
              beforeStart: true,
              afterEnd: true,
            },
          },
        ];
      }
    
      deleteEvent(eventToDelete: CalendarEvent) {
        this.events = this.events.filter(event => event !== eventToDelete);
      }
    
      setView(view: CalendarView) {
        this.view = view;
      }
    
      closeOpenMonthViewDay() {
        this.activeDayIsOpen = false;
      }
    }