6

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

5

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.

  • I wonder if there might be something in the Helper or controller.js that isn't compatible? Otherwise, this is awesome, but unfortunately it just reinforces my original post. How can Salesforce state that these are compatible libraries if they don't actually work? And they are going to make Locker Service live in just a couple of months... – Logan May 1 '17 at 11:57
  • Also, how would you utilize lightning:container in this example? – Logan May 1 '17 at 12:13
  • Logan , I took a look into the error thrown by locker .. it's says it's due to usage of fn of undefined in the full calendar library .. it could be due to the dependency of jQuery in full calendar .. and as mentioned .. Salesforce is looking into this issue as per the stack exchange post and we have sfdc team stating it would be fixed before the mandatory critical update which is more or less a month away – StormBr34ker May 2 '17 at 8:38
  • 1
    Also usage of lightning:container is restricted to dev orgs so it would not help you much here .. I don't have a example .. but the general idea is that .. we use a iframe concept to load the full calendar .. I mean the full calendar will be sandboxed inside our component and we would pass the values through JavaScript postMessage. . rather than using aura expressions .. since this container would lie outside the aura life cycle – StormBr34ker May 2 '17 at 8:41
  • Thanks Sumuga, I really appreciate all of the time you have invested in your explanations and comments! – Logan May 2 '17 at 12:09
2

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?

Modern libraries tend to be CSP-compliant, so the general answer is neither. However, it is understood that Salesforce has tweaked the security as much as possible to remain safe and yet allow libraries like this to work. It's understood that these allowances are minimal.

It would be difficult for a typical developer to modify one of these libraries to be compliant with Locker Service. It wouldn't surprise me at all if at least a few open source projects have had issues or pull requests logged directly against their github repo to fix minor security issues, but this isn't publicly documented by salesforce, as near as I can tell.

Are there libraries out there that people have already created that are Locker compliant that can be downloaded?

Generally, developers following best practices will find they are already LockerService compliant. @KeithC posted a link that includes "known-good" versions of a few popular libraries. It appears that salesforce.com regularly tests these libraries to make sure that LockerService doesn't break them.

Are there any links people can share that show recent examples of implementing Fullcalendar in a Locker Service enabled environment?

I don't know of any such examples, but I would invite anyone who reads this answer to edit in a link or add a comment.

  • Regarding the implementation of Full Calendar in locker enabled environment. AFAIK there is a non-exhaustive list of libs that are proven to work with lightning locker service and FULL CALENDAR 3.1.0 is among those. Reference : developer.salesforce.com/blogs/developer-relations/2017/02/…, any future or past releases of this lib are not supported. – StormBr34ker Apr 29 '17 at 15:26
  • 1
    Also lightning:container is something that we ought to explore as it looks like there might be alternatives to work-around the locker service security, though it would be something similar to working on an iframe and it might complicate things in terms of message passing ( postMessage ) and page loads – StormBr34ker Apr 29 '17 at 15:30
  • @Sumuga Thanks, yeah, I saw that link provided in one of the comments above... very helpful, thank you! Have you seen any examples of this being used? Doesn't necessarily have to be Fullcalendar... I just like to see how others utilize a tool. – Logan Apr 29 '17 at 17:07
  • @sfdcfox Thanks, that is very informative! I will also post links to any examples of Fullcalendar implemented in Lightning on this thread as a help to others that are searching. For anyone that wants to post a link, please include the date that the page you are referencing was created as there have been so many changes in the last few years/months... – Logan Apr 29 '17 at 17:09

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.