[SalesForce] Locker Service and Fullcalendar.io

I have seen that there have already been some questions regarding the open source Fullcalendar.io and the various libraries associated with it, and the strict requirements of Locker Service, but I was wondering if there have been any updates on the compatibility of the two. It seems like Lightning is changing so frequently, that there is a need for a new workaround every 3-6 months, and I am wondering about the best course of action.

  • Are people altering the libraries to make them compliant, or is
    Salesforce working to make sure that their requirements don't have
    such an impact on heavily utilized open source libraries such as
    Fullcalendar?
  • Are there libraries out there that people have already created that
    are Locker compliant that can be downloaded?
  • Are there any links people can share that show recent examples of
    implementing Fullcalendar in a Locker Service enabled environment?

I really appreciate any information I can get!
Logan

Best Answer

Logan, I just happen to have a sample of Fullcalendar which displays events. But heads up .. it is not locker compatible. even though I have used ( Full Calendar: 3.1.0 & jQuery 2.2.4 ) as recommended in the non-exhaustive list of libs.

When locker service is enabled: You would get the following the error

Locker Activated Error FullCalendar

This is quite an ongoing issue,

FullCalendar lib with LockerService

which salesforce is aiming to fix it before the mandatory locker service critical update as per the comments from the sfdc team.

However, for now, you could disable the locker service, and get the components to work as expected.

Locker Deactivated

You would be able to see the calendar as follows

FullCalendar

The logic for the fullcalendar as follows:

Component / App :

<aura:application access="global" controller="FullCalendarController" extends="force:slds">
    <link href="{!$Resource.FullCalendar+'/fullcalendar.print.min.css'}" rel="stylesheet" media="print" />
    <ltng:require styles="{!join(',', $Resource.FullCalendar + '/fullcalendar.min.css')}" 
                  scripts="{!join(',', $Resource.FullCalendar + '/jquery-2.2.4.min.js', $Resource.FullCalendar + '/fullcalendar.min.js' , $Resource.FullCalendar + '/moment.min.js', $Resource.FullCalendar + '/moment-timezone.min.js', $Resource.FullCalendar + '/moment-timezone-with-data-2012-2022.min.js', $Resource.FullCalendar + '/jquery-ui.min.js')}" 
                  afterScriptsLoaded="{!c.scriptsLoaded}" />
    <aura:attribute name="events" type="Object[]" />

    <div class="slds-grid calendarContainer">
        <div class="slds-col">
            <div aura:id="calendar"></div>
        </div>
    </div>

</aura:application>

Controller.js :

({
    scriptsLoaded: function(cmp,evt,helper){
        var events = cmp.get("v.events");
        if(!events.length)
        {
            helper.fetchEvents(cmp);
        }
    }
})

Helper.js :

({
    loadDataToCalendar :function(component,data){
        var today = moment().format('YYYY-MM-DD');
        var ele = component.find('calendar').getElement();
        /* Header section left intentionally blank to remove the header buttons */
        $(ele).fullCalendar({
            aspectRatio: 2.50,
            header: {
                left: '',
                center: '',
                right: '',
            },
            defaultDate: today,
            navLinks: true,
            navLinkDayClick: $A.getCallback(function(date, jsEvent) {

            }),
            editable: true,
            eventLimit: true,
            events:data,
            eventClick: $A.getCallback(function(calEvent, jsEvent, view) {
                var editRecordEvent = $A.get("e.force:editRecord");
                editRecordEvent.setParams({
                    "recordId": calEvent.id
                });
                editRecordEvent.fire();
            })
        });
    },
    tranformToFullCalendarFormat : function(component,events) {
        var eventArr = [];
        for(var i = 0;i < events.length;i++){
            eventArr.push({
                'id':events[i].Id,
                'start': moment.tz(events[i].StartDateTime, "America/Los_Angeles"),
                'end': moment.tz(events[i].EndDateTime, "America/Los_Angeles"),
                'title':events[i].Subject
            });
        }
        return eventArr;
    },
    fetchEvents : function(component) {
        var action = component.get("c.getEvents"); 
        var self = this;
        action.setCallback(this, function(response) {
            var state = response.getState();
            console.log(state);
            if(component.isValid() && state === "SUCCESS"){
                var eventArr = self.tranformToFullCalendarFormat(component,response.getReturnValue());
                self.loadDataToCalendar(component,eventArr);
                component.set("v.events",eventArr);
            }
        });

        $A.enqueueAction(action); 
    }
})

Apex Controller :

public class FullCalendarController {
    @AuraEnabled
    public static List<Event> getEvents(){
        return [SELECT AccountId,EndDateTime,Id,StartDateTime,Subject FROM Event];
    }
}

Note: The markup provided above does not contain the entire logic for the all components shown in the fullCalendar view. For instance the logic to change the week or month etc or fire a new event creation etc,

Hope this helps.

Related Topic