function readOnly(count){ }
Starting November 20, the site will be set to read-only. On December 4, 2023,
forum discussions will move to the Trailblazer Community.
+ Start a Discussion
suji srinivasansuji srinivasan 

how to load FullcalendarJS in static resource for LWC? Fullcalendarjs css and jquery files are not loading got error.

Hi , I need to create custom calendar LWC Component . which fullcalendarjs version can i use for this  component.
 I tried with  version  3 and 5,6 . 
HTML:
<template>
 
    <!-- Spinner to show on waiting screens -->
    <template if:true={openSpinner}>
        <lightning-spinner alternative-text="Loading" size="medium"></lightning-spinner>
    </template>
 
   <div class="slds-grid slds-wrap slds-theme_default">
        <div class="slds-col slds-size_3-of-12">
            <!-- To display list of events or any parent records  
                TODO: add drag items in this div to drop on fullcalendar.
            -->
            <div class=" slds-p-around_medium slds-border_right slds-scrollable_y" style="height:800px">
                <div class="slds-clearfix">
                    <div class="slds-float_right">
                        <lightning-button icon-name="utility:add" slot="actions"
                                        alternative-text="add" title="Add" size="small"
                                        class="slds-p-around_medium"
                                        label="Add Event"
                                        onclick={addEvent}>
                        </lightning-button>
                    </div>
                  </div>
                 
                <template for:each={events} for:item="eachevent">
                    <lightning-card key={eachevent.id}
                                    class="slds-p-left_medium slds-p-right_small">
                        <h3 slot="title">
                            <span class="slds-p-right_small">
                                <lightning-icon icon-name="standard:event" size="small">
 
                                </lightning-icon>
                            </span>
                            {eachevent.title}
                        </h3>
                        <lightning-button-icon icon-name="action:remove" slot="actions"
                                                alternative-text="remove" title="Remove"
                                                value={eachevent.id} size="small"
                                                onclick={removeEvent}>
 
                        </lightning-button-icon>
                         
                        <p class="slds-p-horizontal_small"> Start: <lightning-formatted-date-time value={eachevent.start} year="numeric" month="numeric" day="numeric" hour="2-digit"
                            minute="2-digit" time-zone="GMT" time-zone-name="short" hour12="true"></lightning-formatted-date-time></p>
 
                        <p class="slds-p-horizontal_small">End <lightning-formatted-date-time value={eachevent.end} year="numeric" month="numeric" day="numeric" hour="2-digit"
                            minute="2-digit" time-zone="GMT" time-zone-name="short" hour12="true"></lightning-formatted-date-time></p>
                         
                    </lightning-card>
                </template>
            </div>
        </div>
        <div class="slds-col slds-size_9-of-12">
                <!-- fullcalendar sits in this div -->
                <div id="calendar" class="fullcalendarjs"></div>
        </div>
   </div>
 

JS:


import { LightningElement, track, wire } from 'lwc';
import { loadScript,loadStyle } from 'lightning/platformResourceLoader';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';
import FullCalendarJS from '@salesforce/resourceUrl/FullCalendarJS';
import fetchEvents from '@salesforce/apex/FullCalendarController.fetchEvents';
import createEvent from '@salesforce/apex/FullCalendarController.createEvent';
import deleteEvent from '@salesforce/apex/FullCalendarController.deleteEvent';
import { refreshApex } from '@salesforce/apex';
/**
 * @description: FullcalendarJs class with all the dependencies
 */
export default class FullCalendarJs extends LightningElement {
    //static renderMode ='light';
    //To avoid the recursion from renderedcallback
    fullCalendarJsInitialised = false;
 
    //Fields to store the event data -- add all other fields you want to add
    title;
    startDate;
    endDate;
 
    eventsRendered = false;//To render initial events only once
    openSpinner = false; //To open the spinner in waiting screens
    openModal = false; //To open form
 
    @track
    events = []; //all calendar events are stored in this field
 
    //To store the orignal wire object to use in refreshApex method
    eventOriginalData = [];
 
    //Get data from server - in this example, it fetches from the event object
    @wire(fetchEvents)
    eventObj(value){
        this.eventOriginalData = value; //To use in refresh cache
 
        const {data, error} = value;
        if(data){
            //format as fullcalendar event object
            console.log(data);
            let events = data.map(event => {
                return { id : event.Id,
                        title : event.Subject,
                        start : event.StartDateTime,
                        end : event.EndDateTime,
                        allDay : event.IsAllDayEvent};
            });
            this.events = JSON.parse(JSON.stringify(events));
            console.log(this.events);
            this.error = undefined;
 
            //load only on first wire call -
            // if events are not rendered, try to remove this 'if' condition and add directly
            if(! this.eventsRendered){
                //Add events to calendar
                const $ele = this.template.querySelector("div.fullcalendarjs");
                $ele.fullCalendar('renderEvents', this.events, true);
                this.eventsRendered = true;
            }
        }else if(error){
            this.events = [];
            this.error = 'No events are found';
        }
   }
 
   /**
    * Load the fullcalendar.io in this lifecycle hook method
    */
  renderedCallback() {
   // loadScript(this, jQuery ),
      // Performs this operation only on first render
      if (this.fullCalendarJsInitialised) {
         return;
      }
      this.fullCalendarJsInitialised = true;
      console.log('InsidefullCalendarJsInitialised');
      console.log(FullCalendarJS);
      console.log(jQuery);
     
      // Executes all loadScript and loadStyle promises
      // and only resolves them once all promises are done
        Promise.all([
            loadScript(this, FullCalendarJS + "/fullcalendarjquerymoment/jquery.min.js"),
            loadScript(this, FullCalendarJS + "/fullcalendarjquerymoment/moment.min.js"),
            loadScript(this, FullCalendarJS + "/fullcalendarminjs/fullcalendar.min.js"),
            loadStyle(this, FullCalendarJS + "/fullcalendarprintmincss/fullcalendar.min.css"),
        ])
        .then(() => {
            //initialize the full calendar
        this.initialiseFullCalendarJs();
        })
        .catch((error) => {
        console.error({
            message: "Error occured on FullCalendarJS",
            error,
        });
        });
   }
 
    initialiseFullCalendarJs() {
       const  $ele = this.template.querySelector("div.fullcalendarjs");
        //const modal = this.template.querySelector('div.modalclass');
        console.log($ele);
 
        let self = this;
 
        //To open the form with predefined fields
        //TODO: to be moved outside this function
        function openActivityForm(startDate, endDate){
            self.startDate = startDate;
            self.endDate = endDate;
            self.openModal = true;
        }
        //Actual fullcalendar renders here - https://fullcalendar.io/docs/v3/view-specific-options
        $ele.fullCalendar({
            header: {
                left: "prev,next today",
                center: "title",
                right: "month,agendaWeek,agendaDay",
            },
            defaultDate: new Date(), // default day is today - to show the current date
            defaultView : 'agendaWeek', //To display the default view - as of now it is set to week view
            navLinks: true, // can click day/week names to navigate views
            // editable: true, // To move the events on calendar - TODO
            selectable: true, //To select the period of time
 
            //To select the time period : https://fullcalendar.io/docs/v3/select-method
            select: function (startDate, endDate) {
                let stDate = startDate.format();
                let edDate = endDate.format();
                 
                openActivityForm(stDate, edDate);
            },
            eventLimit: true, // allow "more" link when too many events
            events: this.events, // all the events that are to be rendered - can be a duplicate statement here
        });
    }
 
    //TODO: add the logic to support multiple input texts
    handleKeyup(event) {
        this.title = event.target.value;
    }
     
    //To close the modal form
    handleCancel(event) {
      let ev = event.target.value;
      if(ev){
        this.openModal = false;
      }
       
    }
 
   //To save the event
    handleSave(event) {
      let ev = event.target.value;
      if(ev){
        //let events = this.events;
        this.openSpinner = true;
 
        //get all the field values - as of now they all are mandatory to create a standard event
        //TODO- you need to add your logic here.
        this.template.querySelectorAll('lightning-input').forEach(ele => {
            if(ele.name === 'title'){
               this.title = ele.value;
           }
           if(ele.name === 'start'){
                this.startDate = ele.value.includes('.000Z') ? ele.value : ele.value + '.000Z';
            }
            if(ele.name === 'end'){
                this.endDate = ele.value.includes('.000Z') ? ele.value : ele.value + '.000Z';
            }
        });
       
        //format as per fullcalendar event object to create and render
        let newevent = {title : this.title, start : this.startDate, end: this.endDate};
        console.log(this.events);
 
        //Close the modal
        this.openModal = false;
        //Server call to create the event
        createEvent({'event' : JSON.stringify(newevent)})
        .then( result => {
            const $ele = this.template.querySelector("div.fullcalendarjs");
 
            //To populate the event on fullcalendar object
            //Id should be unique and useful to remove the event from UI - calendar
            newevent.id = result;
             
            //renderEvent is a fullcalendar method to add the event to calendar on UI
            //Documentation: https://fullcalendar.io/docs/v3/renderEvent
            //$.noConflict();
            //jQuery( document ).ready(function( $ ){
            $ele.fullCalendar( 'renderEvent', newevent, true );//});
             
            //To display on UI with id from server
            this.events.push(newevent);
 
            //To close spinner and modal
            this.openSpinner = false;
 
            //show toast message
            this.showNotification('Success!!', 'Your event has been logged', 'success');
 
        })
        .catch( error => {
            console.log(error);
            this.openSpinner = false;
 
            //show toast message - TODO
            this.showNotification('Oops', 'Something went wrong, please review console', 'error');
        })
   }
  }
   
   /**
    * @description: remove the event with id
    * @documentation: https://fullcalendar.io/docs/v3/removeEvents
    */
   removeEvent(event) {
        //open the spinner
        this.openSpinner = true;
 
        //delete the event from server and then remove from UI
        let eventid = event.target.value;
        deleteEvent({'eventid' : eventid})
        .then( result => {
            console.log(result);
            const $ele = this.template.querySelector("div.fullcalendarjs");
            console.log(eventid);
            $ele.fullCalendar( 'removeEvents', [eventid] );
 
            this.openSpinner = false;
             
            //refresh the grid
            return refreshApex(this.eventOriginalData);
 
        })
        .catch( error => {
            console.log(error);
            this.openSpinner = false;
        });
   }
 
   /**
    *  @description open the modal by nullifying the inputs
    */
    addEvent(event) {
      let ev = event.target.value;
      if(ev){
        this.startDate = null;
        this.endDate = null;
        this.title = null;
        this.openModal = true;
    }
  }
 
    /**
     * @description method to show toast events
     */
    showNotification(title, message, variant) {
        console.log('enter');
        const evt = new ShowToastEvent({
            title: title,
            message: message,
            variant: variant,
        });
        this.dispatchEvent(evt);
    }
}

Apex class:
public with sharing class FullCalendarController {
    public class EventException extends Exception {}
   
    /**
     * @description: To retrieve the most recent events
     */
    @AuraEnabled(cacheable=true)
    public static List<Event> fetchEvents() {
        return [SELECT Id, Subject, StartDateTime, IsAllDayEvent, EndDateTime
                FROM Event
                ORDER BY CreatedDate DESC
                LIMIT 100];
    }
    /**
     * @description To create an event from web component
     * @param event - json string with event details - title, start and end for now
     */
    @AuraEnabled
    public static Id createEvent(String event){
        //The following logic to be replaced with your respective event object
        if(String.isBlank(event)){
            return null;
        }
        Map<String, Object> eventMap = (Map<String, Object>) JSON.deserializeUntyped(event);
       
        Event newEvent = new Event();
        newEvent.Subject = eventMap.get('title') != null ? (String)eventMap.get('title') : null;
        String startdate = eventMap.get('start') != null ?
                            ((String)eventMap.get('start')).replace('T', ' ').replace('.000Z', '') :
                            null;
        String endDate = eventMap.get('end') != null ?
                            ((String)eventMap.get('end')).replace('T', ' ').replace('.000Z', '') :
                            null;
        newEvent.StartDateTime = startdate != null ? Datetime.valueOfGmt(startdate) : null;
        newEvent.EndDateTime = endDate != null ? Datetime.valueOfGmt(endDate) : null;
        // newEvent.IsAllDayEvent = eventMap.get('start') != null ? eventMap.get('start') : null;
        insert newEvent;
        return newEvent.Id;
    }
    /**
     * @description To delete an event from web component
     * @param eventid - event id to delete from the component
     */
    @AuraEnabled
    public static void deleteEvent(Id eventid) {
       
        if(eventid != null){
            delete [SELECT Id FROM Event Where Id=:eventid];
        }else{
            throw new EventException('Event id is not passed');
        }
    }
}
 

SubratSubrat (Salesforce Developers) 
Hello ,

The FullCalendarJS library is quite versatile and supports different versions. However, based on your provided code, it seems that you are using the FullCalendar v3 library.

In your JavaScript code, you're using methods like fullCalendar, renderEvents, renderEvent, and removeEvents, which are specific to FullCalendar v3. These methods have been changed in newer versions, such as FullCalendar v4 and v5.

If you want to use a different version of FullCalendarJS, you'll need to make some modifications to your code based on the version you choose. Here are the steps you can follow:

Identify the version of FullCalendarJS you want to use. You can visit the FullCalendarJS website (https://fullcalendar.io/) and check the documentation for the version you prefer.
Based on the chosen version, update your import statement in the JavaScript code to load the correct FullCalendarJS resource. For example, if you want to use FullCalendar v5, you would replace the import statement:
import FullCalendarJS from '@salesforce/resourceUrl/FullCalendarJS';
with the appropriate import statement for FullCalendar v5.

Update your renderedCallback() method to initialize the correct version of FullCalendarJS. The initialization code, options, and method names may differ based on the version you choose. Refer to the FullCalendarJS documentation for your chosen version to understand the initialization process and make the necessary adjustments.

By following these steps and referring to the FullCalendarJS documentation for your chosen version, you should be able to integrate the desired version of FullCalendar into your custom LWC component successfully.

Hope this helps !
Thank you.