Featured Image
Software Development

How to integrate FullCalendar in Angular

There are plenty of awesome JQuery libraries available on GitHub which are easy to integrate with pure JQuery projects. But after the release of high-level JavaScript frameworks like Angular, React and Vue it is sometimes difficult to use these libraries in its normal way. We can find wrappers for these libraries on GitHub. But it might be the case that these wrappers are not always updated with the latest functionalities of native JQuery library.

One such pure JQuery library is FullCalendar which supports management of events in different views of a calendar like Day, Week, Month and List view.

This article describes the step-by-step process of integrating FullCalendar in Angular-6+.

Step-1.

Let’s first create a new Angular project named full-calendar-demo:

// generate angular project
ng new full-calendar-demo

// go to project directory
cd full-calendar-demo

// start local server
ng serve --open

Step-2.

Install JQuery, moment.js and FullCalendar packages:

// install other dependencies ( JQuery and moment ) with 
// fullcalendar
npm install jquery moment fullcalendar --save

// install JQuery types for typescript support
npm install --save-dev @types/jquery

Step-3.

Create a new component named full-calendar:

ng g c full-calendar

Step-4.

Import full-calendar styles file in the angular.json file:

angular.json:

...
...
   "styles": [
      "./node_modules/fullcalendar/dist/fullcalendar.min.css",
      "src/styles.css"
   ],
...
...

Step-5.

Modify app.component.html to view full-calendar component:

app.component.html:

<app-full-calendar></app-full-calendar>

Step-6.

Import JQuery, FullCalendar and moment packages in a component.ts file:

full-calendar.component.ts:

import { Component, OnInit } from '@angular/core';

import * as $ from 'jquery';
import * as moment from 'moment';
import 'fullcalendar';

@Component({
   selector: 'app-full-calendar',
   templateUrl: './full-calendar.component.html',
   styleUrls: ['./full-calendar.component.css']
})

export class FullCalendarComponent implements OnInit {

   constructor() { }

   ngOnInit() { }

}

Make sure that you import all these packages in above order only. Otherwise, you might get the error in console.

Step-7.

Add an element in a component.html file and configure the object to be passed in FullCalendar to have some basic functionality initially.

full-calendar.component.html:

<div id="full-calendar"></div>

full-calendar.component.ts:

import { Component, OnInit, Input } from '@angular/core';
import * as $ from 'jquery';
import 'fullcalendar';
import * as moment from 'moment';

@Component({
   selector: 'app-full-calendar',
   templateUrl: './full-calendar.component.html',
   styleUrls: ['./full-calendar.component.css']
})

export class FullCalendarComponent implements OnInit {

@Input()
      set configurations(config: any) {
         if(config) {
            defaultConfigurations = config;  
         }
      }

@Input() eventData: any;
   
   defaultConfigurations: any;

constructor() {

this.defaultConfigurations = {
         editable: true,
         eventLimit: true,
         titleFormat: 'MMM D YYYY',
         header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
         },
         buttonText: {
            today: 'Today',
            month: 'Month',
            week: 'Week',
            day: 'Day'
         },
         views: {
            agenda: {
               eventLimit: 2
            }
         },
         allDaySlot: false,
         slotDuration: moment.duration('00:15:00'),
         slotLabelInterval: moment.duration('01:00:00'),
         firstDay: 1,
         selectable: true,
         selectHelper: true,
         events: this.eventData,
      };
   }

   ngOnInit() { }
}
  1. configurations is an input property which overrides the default configurations object defaultConfigurations.
  2. eventData is an input property which is an array of all events to be displayed on the calendar.
  3. defaultConfigurations is an object which contains some basic properties already assigned with default values.
  4. Notice the last property in defaultConfigurations object “events”, it is assigned as eventData value, that’s how we pass events to FullCalendar.

Step-8.

Let’s set some default events data to view events on the calendar:

full-calendar.component.ts:

constructor() {
   this.eventData = [
       {
          title: 'event1',
          start: moment()
       },
       {
          title: 'event2',
          start: moment(),
          end: moment().add(2, 'days')
       },
   ];
   ...
   ...
   ...

}

Step-9.

Initialize FullCalendar with defaultConfigurations object:

full-calendar.component.ts:

...
...
   ngOnInit() {
      $('#full-calendar').fullCalendar(
         this.defaultConfigurations
      );

   }
...
...

And that’s it. Go to your browser and visit the URL localhost:4200. You will see the calendar with three views month, week and day, and there are two events.

If you can’t find the output in your browser, stop your local-server and restart it by ng serve again.

Till now we just provided our events and configurations to the FullCalendar. But that’s not always the case. We may want to add a new event, drag an event from one day to another or perform some other operations.

So our next step is to catch callbacks which get emitted by FullCalendar and perform some operations ( like making an API call to backend server to store new event or modify the duration of the event ).

Step-10.

Catch FullCalendar callbacks:

full-calendar.component.ts:

constructor() {
   this.defaultConfigurations = {
      ...
      ...
      dayClick: (date, jsEvent, activeView) => {
         this.dayClick(date, jsEvent, activeView);
      },
      
      eventDragStart: (timeSheetEntry, jsEvent, ui, activeView) => {
         this.eventDragStart(
             timeSheetEntry, jsEvent, ui, activeView
         );
      },
      eventDragStop: (timeSheetEntry, jsEvent, ui, activeView) => {
         this.eventDragStop(
            timeSheetEntry, jsEvent, ui, activeView
         );
      },
   };
}
...
...
dayClick(date, jsEvent, activeView) {
   console.log('day click');
}

eventDragStart(timeSheetEntry, jsEvent, ui, activeView) {
   console.log('event drag start');
}

eventDragStop(timeSheetEntry, jsEvent, ui, activeView) {
   console.log('event drag end');
}

...
...

In the above example, we catch three callbacks dayClick, eventDragStart, and eventDragStop in defaultConfigurations object and pass the callback arguments to component methods so that these methods can perform actions we want.

Right now, it just logs events in the console, but you can perform any operations you want.

Go to your browser, open browser console by pressing Ctrl + Shift + i. Now click on a day in the calendar and you will see ‘day click’ gets logged on browser console.

Same way try to drag an event from one day to another. When you start dragging and event, it logs ‘event drag start’ in the console and when you stop it, it logs ‘event drag end’.

You can find more configuration options and callbacks here at the docs of FullCalendar.

Conclusion

In this blog, we have seen how to integrate jQuery FullCalendar in Angular using a custom directive. This approach allows us to use the native jQuery library without relying on third-party wrappers. We have also learned how to create a shared module and import it in other modules to use the directive. I hope you liked reading this blog post, please do checkout my other blogs written by me:

React vs Angular: A Comprehensive Comparison

Angular: Make your code more Consistent, Readable and Expandable

If you are looking for Angular development services, you can contact us. We have a team of experienced and skilled developers who can deliver high-quality and scalable solutions for your business needs. Contact us today.

author
Kalpesh Shingala
I am a Fullstack Developer having expertise in architecture and development of Responsive, Performance efficient, Extendable and Browser compatible web applications by using the latest technologies like Angular and Vuejs.