Create a custom calendar in LWC — Part 1

Rohit Tanwani
7 min readJun 20, 2023

--

Salesforce calendar is a great tool to view, create and edit event data in Salesforce.

Salesforce Lightning Calendar

One can create an object calendar in the Salesforce calendar to view that object data in the Salesforce calendar. You can create an object calendar by clicking the Sidebar button on the right of the ‘New Event’ button, clicking on the settings icons on the right of My Calendars and clicking New Calendar. Provide all of the information and you will have a calendar which will show the object's data you have selected. If you encounter any problems follow this link:

Salesforce Account Object Calendar

But there are two major problems in the Salesforce object calendar.

  1. There is no direct way to create data through the salesforce object calendar. Salesforce object calendar only creates event data.
  2. There is not much customization you can do in the salesforce calendar. (If you want to see contacts of a particular account. You have to create a list view and then use that list view in the New Calendar screen).

So to overcome these problems, we are creating a custom solution through LWC. To create a custom calendar either one can create it from scratch(lot of work and good luck with that) or import a library and use it. We are going to use a library known as FullCalendar.io.

The steps to use the FullCalendar library in LWC are too simple.

  1. Download the FullCalendar zip file from this link.
  2. Upload the zip file as a static resource in the salesforce.
  3. Use this static resource in our LWC component.

Once you are done with all of this and if you are lucky (I received this error after two hours of debugging) you will receive the following error.

Lightning Web Security error in importing Fullcalendar library

Now if you are receiving any other error or this error. Following the steps below will help you to show the calendar in LWC. But you have to promise me you will follow each step as mentioned. One mistake and it will be hours of debugging (trust me I have done that).

  1. Download the V5 FullCalendar library zip file. Why? Firstly because this article will use v5 so it will be easier for you guys to follow. Second, we are going to make some changes in core library code and core library import is banned from v6. Each FullCalendar plugin implicitly calls the core library. Okay, I know this is confusing download the v5 FullCalendar library zip file.
  2. Extract the Fullcalendar zip file to make the changes in some of the JS files. If you have downloaded the v5 library after extraction the folder will look like this.
Fullcalendar v5 library zip file after extraction

3. Go into the lib folder and open main.js in VS Code. Change the following line of code from

var FullCalendar = (function (exports) {

to

(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ?
factory(exports) :
typeof define === 'function' && define.amd ? define(['exports'], factory) :
(global = global || self, factory(global.FullCalendar = {}));
}(this, function (exports) {

Your main.js file should look like this.

Updated main.js file

Save the main.js file. Go to the folder where you have extracted the FullCalendar library. Select the lib folder and right-click and create a zip file. In Windows 11 you can create a zip file by right click on the folder and selecting Compress to Zip file option. Rename the zip file as fullcalendarWorking.

4. Upload this updated zip file as a static resource in the salesforce org. To create a static resource. Go to Setup, in quick find search for Static Resources. Click on Static Resources. Click on New to create a new static resource. Write Fullcalendar as Resource Name. Provide a value in the description field if you like. Click on choose file button and upload the fullcalendarWorking zip file here. Set cache control to Public.

Phewww! We have done with the library changes now let’s create a component to use the library. Open VS Code and create a lightning web component. Provide component name as customCalendar. After successfully creating a component head over to the component HTML file, and write the following code in the HTML file between the <template> tag.

<lightning-card>
<div class="fullcalendar"></div>
</lightning-card>

We are using the <lightning-card> tag to provide a white background to the LWC component. I don’t like a transparent calendar but it is not compulsory to use it. <div> tag is required here because under this div we are going to render the calendar component. By the way, the transparent calendar will look like this.

Transparent Custom Calendar

We are done with the HTML code. Now let’s move to the JS file.

First, let’s import the static resource. So write the following code above the class declaration and below the LightningElement import.

import FullCalendarJS from '@salesforce/resourceUrl/FullCalendar';

Importing this static resource to use it in our component.

After static resource import, import loadStyle and loadScript methods from platformResourceLoader

import { loadStyle, loadScript } from 'lightning/platformResourceLoader';

To import a third-party JavaScript or CSS library, use the platformResourceLoader module. For more details about these two methods follow this link.

Now under the class, write the connectedCallback method to import the main.js and main.css files from static resources. The connectedCallback method will look like this.

connectedCallback() {
Promise.all([
loadStyle(this, FullCalendarJS + '/lib/main.css'),
loadScript(this, FullCalendarJS + '/lib/main.js')
])
.then(() => {
this.initializeCalendar();
})
.catch(error => console.log(error))
}

At first in connectedCallback we have Promise.All this is loading the main style sheet and main js file to provide a Fullcalendar instance to our component which we are later going to use in the initializeCalendar method. As Promise.All returns a promise hence we are writing then and catch after it. Currently, if everything loads fine then we are proceeding to initialize the calendar if not we go to catch block and print the error.

Write the initializeCalendar method and create a FullCalendar.Calendar instance. Confusing isn’t most of you will encounter errors here. First copy and paste the initializeCalendar method and if there is any error please reread this article. Maybe you have missed a step or two.

initializeCalendar() { 
const calendarEl = this.template.querySelector('div.fullcalendar');
const calendar = new FullCalendar.Calendar(calendarEl, {});
calendar.render();
}

The syntax to create a calendar instance in LWC is

const calendar = new FullCalendar.Calendar(calendarElement, optionsObject);

CalendarElement is the HTML element under which you have to show the calendar(Remember the <div> tag we have created in the HTML file). optionsObject is the calendar options object. Here you can customize the calendar as much as you want. Customization involves showing/not showing calendar header actions, title formatting, and column formatting, to name a few.

After successfully creating the instance of Fullcalendar.Calendar. It is now time to render the calendar in our LWC. For that Fullcalendar provide the render method. We just called the method and that’s it. We are done, just deploy the component by setting the appropriate targetConfig and adding the LWC component to the salesforce page. The custom calendar will look like this in the salesforce org.

Custom Calendar LWC

Just for reference the HTML and JS code files are looking like this.

Custom Calendar HTML Code
Custom Calendar JS Code

Some concerns which many of you might have now are:

  1. How can we style this calendar this is not at all looking good. We want this calendar to look like a salesforce component. Can we do that?
  2. This only shows the monthly view. Can we have several modes just like the salesforce calendar?
  3. Except for the header panel button, nothing is interactive in this component. So can we make this calendar interactive?
  4. How to show data here and more importantly How to create data from this component.

and many more…

All of your concerns will be resolved in the upcoming parts. If you guys can wait go ahead and if not please go through the FullCalendar documentation here.

If you have any more concerns please write it in the comment box. If possible we will cover that in our series. If you like this blog post, show your appreciation in the comment box or by liking this post.

Here is the link for Part 2 everyone. Keep showing your support for this project. Thanks, everyone.

--

--

Rohit Tanwani

Consultant at Deloitte USI | Salesforce Developer | Cinephile