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 { JsonPipe } from '@angular/common';
  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;
    }
  }