Reputation: 20041
I am using fullcalendar.io
I dynamically populate my calendar, by adding events via evenSources. Such as:
$('.add-more-events').on('click', function(){
var myEventSourceUrl = // ... get the event source url somehow
var eventSourceColor = // ... get the color for this source
var eventSource = {
type: 'GET',
url: myEventSourceUrl,
color: eventSourceColor
};
$('.my-calendar').fullCalendar('addEventSource', eventSource);
}
Likewise, I dynamically unpopulate my calendar, by removing events via eventSource. Such as:
$('.remove-some-events').on('click', function(){
var myEventSourceUrl = // ... get the event source url somehow
var eventSourceColor = // ... get the color for this source
var eventSource = {
type: 'GET',
url: myEventSourceUrl,
color: eventSourceColor
};
$('.my-calendar').fullCalendar('removeEventSource', eventSource);
}
So far, so good: visually, events are appearing in the calendar (populated), & disappearing in the calendar (unpopulated) as expected. That is, whenever I click on the relevant button.
At some point, I want to reinitialize my calendar & redisplay the events that were last present in my calendar (keep the last eventSources I suppose).
Pseudo code would look like:
1. Back up my events
2. Destroy my calendar
3. Create & initialize new calendar
4. Add the backed up events (see step 1) to the new calendar
So I implemented the above such as:
var clientEvents = $('.my-calendar').fullCalendar('clientEvents'); /* [1] */
$('.my-calendar').fullCalendar('destroy'); /* [2] */
$('.my-calendar').fullCalendar(calendarOptions); /* [3] */
var arrayLengthClientEvents = clientEvents.length;
for (var i = 0; i < arrayLengthClientEvents; i++) {
$('.my-calendar').fullCalendar( 'addEventSource', clientEvents[i].source); /* [4] */
}
But for some reason, I get duplicated events when calling $('.my-calendar').fullCalendar('clientEvents')
.
Note: it seems to be happening when switching weeks, not sure about this though, it may be unrelated.
Upvotes: 1
Views: 6052
Reputation: 14133
clientEvents
Retrieves events that FullCalendar has in memory.
.fullCalendar( 'clientEvents' [, idOrFilter ] ) -> Array
So it returns an array of events.
You store it, recreate the FC and then add the source of each event. But the sources are URLs and the same for many events, so you get duplicates.
Basically you are doing
$('.my-calendar').fullCalendar('addEventSource', {url:"/myfeed"});
$('.my-calendar').fullCalendar('addEventSource', {url:"/myfeed"});
which will give you duplicates.
So to fix it, you could check for duplicates and not add them. Add the method below:
var filterOutDuplicateEventSources = function(allEventSources){
var hash = {};
var remainingEventSources = [];
var arrayLength = allEventSources.length;
for (var i = 0; arrayLength !== 0 && i < arrayLength; i++) {
var currentEventSource = allEventSources[i];
var currentEventSourceUrl = currentEventSource.url;
if(currentEventSourceUrl){
if(hash[currentEventSourceUrl] === 1){
continue; //skip this event source, we've already added it
}else{
hash[currentEventSourceUrl] = 1; // remember that we add this currentEventSourceUrl
remainingEventSources.push(currentEventSource);
}
}else{
//handle non-url event sources
}
}
return remainingEventSources;
}
Use this method such as:
// Get all event sources
var allEventSources = [];
var arrayLengthClientEvents = clientEvents.length;
for (var i = 0; i < arrayLengthClientEvents; i++) {
allEventSources.push( clientEvents[i].source );
}
// Filter out duplicated event sources
var remainingEventSources = filterOutDuplicateEventSources( allEventSources );
Technically, I don't believe that clientEvents
is meant to be used that way. What you really need is an eventSources
method. But it doesn't exist (might be a good feature request).
I would likely try to store the calendar's event source state outside of fullcalendar. You said you have buttons that turn things on and off, are these basically toggles? Is it possible to determine the state by simply querying your various controls? Something along those lines might be a better solution. Maybe.
Upvotes: 1