Reputation: 20925
I have a web application that uses fullcalendar.io. I only have one event per day maximum. My problem is that everytime the events are fetched, it fetches all events, and this results into re-rendering of all the events in the month (at least). I don't want to refetch existing (in client already) events!
Why is this bad? Well, it's bad because the FullCalendar is programmed so that it will first hide/delete the clientside events from showing, then waits until the fetch is done, and then re-renders all the events. This results into a situation where for almost a second of time, the calendar month shows empty, before it renders the events. How I would like it to behave is: The calendar should fetch only the events that are not currently showed in that visible month. Then when it returns, it only re-renders those events that are new.
How I tried to achieve it is this:
events: {
data: function () {
return {
dynamic_value: JSON.stringify({myarray:$('#calendar').fullCalendar('clientEvents')})
};
},
url: '/calendar/events',
}
What I tried to do was to set a dynamic parameter, where I should put all the client side events. And then in the server backend, I would only send back events that are not included in that parameter. The problem is, that if I call the fullCalendar('clientEvents') in this place (inside the events object), it results in an empty array. So how could I give the events object a parameter to indicate that it should only fetch new events? Or am I approaching this the wrong way from the beginning?
Upvotes: 0
Views: 1289
Reputation: 20925
Even if I would have found a way (I actually did) to pass old events to the dynamic_value (parameter), that wouldn't have solved the real problem.
And why is that? It is because I was using refetching for displaying the events. I looked under the hood of FullCalendar refetching function, and what it does is that it first deletes all the events from the calendar, and after that, it starts fetching new events. And during that ajax fetch, the calendar will stay blank. So it wouldn't helped me even if I had set the old events as a paremeter, and then applied serverside filtering.
But, luckily, I was able to solve the real problem. I continued fetching all events (I might change it in the future though), but I managed to avoid the problem. What I did was that I (again) looked under the hood. I realised that in FullCalendar there exists many un-documented functions that are usable through the api. One of them is a fetchEvents function (used by the refetchEvents function). The fetchEvents function only does the fetching, and it doesn't remove any old events. So what I did was that instead of using the reFetchEvents, I used:
$('#calendar').fullCalendar(
'fetchEvents',
$('#calendar').fullCalendar('getView').start,
$('#calendar').fullCalendar('getView').end
);
The fetchEvents function just needs the start and end as paramaters. I was able to get those by following how the fetchEvents function is used by refetchEvents function, and there they got the start and end from getView function. I was able to use the getView function as seen above.
But this is only half of the solution. Surely, I must somehow delete the old calendar events in a proper place. Well, for that, I was lucky to find also a function that could be used through the api (even not documented). I had to change the events part configuration in my fullCalendar. Instead of simple json feed URL, I changed it to ajax specification with success function, so that I could, in proper place, do the destroying of old events. So now the destroying part happens only after the ajax response, which will make the destroy to render process quick:
events: function(start, end, timezone, callback) {
$.ajax({
url: '/calendar/events',
dataType: 'json',
data: {
start: start.unix(),
end: end.unix()
},
success: function(doc) {
var events = [];
doc.forEach(function(eventObject) {
events.push({
title: eventObject.title,
start: eventObject.start,
user: eventObject.user,
allDay: eventObject.allDay,
overlap: eventObject.overlap,
created: eventObject.created
});
});
$('#calendar').fullCalendar('destroyEvents');
callback(events);
}
});
}
As you can see above, I use the fullCalendar destroyEvents before sending the new events for the callback to be rendered. And this solved the blank calendar during ajax call.
Upvotes: 1