Render fullcalendar on a lightning component
Hi @prashanthkr based on my comment i tried to prototype this, and it works like charm during inital load/refresh in both SF1 and desktop.
Edit on 20-09-2017:
Fullcalendar works for the below js version with LockerService(v40) in place :
jQuery - v3.2.1
MomentJS - v2.18.1
FullCalendar - v3.1.0/v3.5.1(latest)
NOTE: Libraries should be included in the above order.
Here's my code:
fullCalendar.cmp
<aura:component controller="FullCalendarController" implements="force:appHostable">
<ltng:require styles="{!$Resource.FullCalenderJs + '/fullcalendar/fullcalendar.css'}"
scripts="{!join(',',
$Resource.FullCalenderJs + '/fullcalendar/lib/jquery.min.js',
$Resource.FullCalenderJs + '/fullcalendar/lib/moment.min.js',
$Resource.FullCalenderJs + '/fullcalendar/fullcalendar.js'
)}"
afterScriptsLoaded="{!c.afterScriptsLoaded}" />
<ltng:require styles="/resource/FullCalendar/FullCalendar/fullcalendar.css"/>
<aura:attribute name="events" type="Object[]" />
<div id="calendar"></div>
</aura:component>
fullCalendarController.js
({
afterScriptsLoaded: function(cmp,evt,helper){
var events = cmp.get("v.events");
console.log(events);
if(!events.length)
{
helper.fetchEvents(cmp);
}
},
})
fullCalendarHelper.js
({
loadDataToCalendar :function(data){
$('#calendar').fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
defaultDate: '2016-04-01',
editable: true,
eventLimit: true,
events:data
});
},
tranformToFullCalendarFormat : function(component,events) {
var eventArr = [];
for(var i = 0;i < events.length;i++){
eventArr.push({
'id':events[i].Id,
'start':events[i].StartDateTime,
'end':events[i].EndDateTime,
'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();
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:(FullCalendarController)
public class FullCalendarController {
@AuraEnabled
public static List<Event> getEvents(){
return [SELECT AccountId,EndDateTime,Id,StartDateTime,Subject FROM Event];
}
}
-- UPDATE --
Above solution work properly in Standalone app not in LEX on subsequent loads. After hours of inspecting DOM Element returned by jquery selector which was different compared to the first time load,jquery was not returning the proper DOM when the component descriptor is loaded from cache.
So Inorder to get the proper DOM,on every load,i replaced the jquery selector $('#calendar')
to component.find('#calendar').getElement()
and it actually returns the proper DOM Element,and the fullcalendar is getting rendered on subsequent loads in LEX.
fullCalendar.cmp should be like this to support above:
<aura:component controller="FullCalendarController" implements="force:appHostable">
<ltng:require styles="{!$Resource.FullCalenderJs + '/fullcalendar/fullcalendar.css'}"
scripts="{!join(',',
$Resource.FullCalenderJs + '/fullcalendar/lib/jquery.min.js',
$Resource.FullCalenderJs + '/fullcalendar/lib/moment.min.js',
$Resource.FullCalenderJs + '/fullcalendar/fullcalendar.js'
)}"
afterScriptsLoaded="{!c.afterScriptsLoaded}" />
<ltng:require styles="/resource/FullCalendar/FullCalendar/fullcalendar.css"/>
<aura:attribute name="events" type="Object[]" />
<div aura:id="calendar"></div>
</aura:component>
And loadDataToCalendar method should look like this:
({
loadDataToCalendar :function(component,data){
var ele = component.find('calendar').getElement();
$(ele).fullCalendar({
header: {
left: 'prev,next today',
center: 'title',
right: 'month,basicWeek,basicDay'
},
defaultDate: '2016-04-01',
editable: true,
eventLimit: true,
events:data
});
},
})