Top


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.

calendar

Installation

ng add angular-calendar

calendar.html


<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>

calendar.ts

import { JsonPipe } from '@angular/common';
import { Component, TemplateRef, ViewEncapsulation, inject, viewChild } from '@angular/core';
import { FormsModule } from '@angular/forms';

import { NgbModal } from '@ng-bootstrap/ng-bootstrap';
import {
  CalendarEvent,
  CalendarEventAction,
  CalendarEventTimesChangedEvent,
  CalendarModule,
  CalendarView,
} from 'angular-calendar';
import {
  addDays,
  addHours,
  endOfDay,
  endOfMonth,
  isSameDay,
  isSameMonth,
  startOfDay,
  subDays,
} from 'date-fns';
import { Subject } from 'rxjs';

@Component({
  selector: 'app-calendar',
  imports: [CalendarModule, FormsModule, JsonPipe],
  encapsulation: ViewEncapsulation.None,
  templateUrl: './calendar.html',
  styleUrl: './calendar.scss',
})
export class Calendar {
  public readonly modalContent = viewChild.required>('modalContent');
  public view: CalendarView = CalendarView.Month;
  public CalendarView = CalendarView;
  public viewDate: Date = new Date();
  public refresh = new Subject();
  public activeDayIsOpen: boolean = true;
  public color: string;
  public modalDetails!: {
    action: string;
    event: CalendarEvent;
  };

  public colors = {
    red: {
      primary: '#3949ab',
      secondary: '#e8e5ff',
    },
    blue: {
      primary: '#4fc3f7',
      secondary: '#f2f2f2',
    },
    yellow: {
      primary: '#ffb829',
      secondary: '#fff7e5',
    },
  };

  public 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);
      },
    },
  ];

  public events: CalendarEvent[] = [
    {
      start: subDays(startOfDay(new Date()), 1),
      end: addDays(new Date(), 1),
      title: 'A 3 day event',
      color: { primary: '#3949ab', secondary: '#4fc3f7' },
      actions: this.actions,
      allDay: true,
      resizable: {
        beforeStart: true,
        afterEnd: true,
      },
      draggable: true,
    },
    {
      start: startOfDay(new Date()),
      title: 'An event with no end date',
      color: { ...this.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: { ...this.colors['blue'] },
      allDay: true,
    },
    {
      start: addHours(startOfDay(new Date()), 2),
      end: addHours(new Date(), 2),
      title: 'A draggable and resizable event',
      color: { ...this.colors['yellow'] },
      actions: this.actions,
      resizable: {
        beforeStart: true,
        afterEnd: true,
      },
      draggable: true,
    },
  ];

  private modal = inject(NgbModal);

  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.modalDetails = { event, action };
    this.modal.open(this.modalContent(), { size: 'lg', modalDialogClass: 'calendar-event' });
  }

  addEvent(): void {
    this.events = [
      ...this.events,
      {
        title: 'New event',
        start: startOfDay(new Date()),
        end: endOfDay(new Date()),
        color: this.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;
  }
}

Uninstalling Package

npm uninstall angular-calendar