Skip to content

Instantly share code, notes, and snippets.

@sjurgis
Last active February 5, 2018 08:37
Show Gist options
  • Save sjurgis/3c9ad1294b1466d7b910 to your computer and use it in GitHub Desktop.
Save sjurgis/3c9ad1294b1466d7b910 to your computer and use it in GitHub Desktop.
FullCalendar calendar view implementation in Salesforce.com

This is an adaptation of Cody Sechelski's Create a Calendar View in Salesforce.com.

The main problem with his implementation was that it wasn't handling more than 2000 records. This was due to a Apex workaround, as it is reserves start and end variables, Cody made a repeat table and parsed that into JavaScript object. My solution creates JSON string in Apex and then uses string function to replace all startString and endString instances. A more sensible solution would involve recreating the object in JavaScript or simply editing the FullCalendar library to look for different variable names.

I have also simplified the code a bit so you can start working towards your personal implementation. As this is using JavaScript remoting, I hope this gives you a framework to work towards more advanced features like editing or optimizing request sizes (executing a request on next month load).

The page

<apex:page showHeader="false" standardStylesheets="false" controller="fullCalendar" >
    <script src="//cdnjs.cloudflare.com/ajax/libs/jquery/2.1.4/jquery.min.js"/>
    <script src="//cdnjs.cloudflare.com/ajax/libs/moment.js/2.10.3/moment.min.js"/>
    <script src="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.3.1/fullcalendar.min.js"/>
    <link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.3.1/fullcalendar.min.css" rel="stylesheet" />
    <link href="//cdnjs.cloudflare.com/ajax/libs/fullcalendar/2.3.1/fullcalendar.print.css" rel="stylesheet" media="print"  />
    <body>             
   <script type="text/javascript"> 
      function getEventData() {                         // records are retrieved from soql database
        Visualforce.remoting.Manager.invokeAction(
            '{!$RemoteAction.fullCalendar.eventdata}',  // controller and method names
            function(result, event){
                if (event.status) {
                    evt =  JSON.parse(result);
                    $('#calendar').fullCalendar({       // html element and library name
                        events: evt                     
                    }) 
                } else if (event.type === 'exception') { 
                    console.log(event.message);
                } else {
                    console.log(event.message);
                }
            }, 
            {escape: false}
        );
    }
    $(document).ready(function() {
        getEventData();
    });
    </script>
    <div id="calendar"></div>
    </body>
</apex:page>

The class

public class fullCalendar {
    public string eventsJSON {get;set;}
    
    //The calendar plugin is expecting dates is a certain format. We can use this string to get it formated correctly
    static String dtFormat = 'EEE, d MMM yyyy HH:mm:ss z';

    @RemoteAction
    public static string eventdata(){
        calEvent[] events = new calEvent[]{};
        for(Event evnt: [select Id, Subject, isAllDayEvent, StartDateTime, EndDateTime from Event]){
            DateTime startDT = evnt.StartDateTime;
            DateTime endDT = evnt.EndDateTime;
            
            calEvent myEvent = new calEvent();
            myEvent.title = evnt.Subject;
            myEvent.allDay = evnt.isAllDayEvent;
            myEvent.startString = startDT.format(dtFormat);
            myEvent.endString = endDT.format(dtFormat);
            myEvent.url = '/' + evnt.Id;
            myEvent.className = 'event-personal';
            events.add(myEvent);
        }
        
        string jsonEvents = JSON.serialize(events);
        jsonEvents = jsonEvents.replace('startString','start');
        jsonEvents = jsonEvents.replace('endString','end');
        
        return jsonEvents;
    }

    // Class to hold calendar event data
    public class calEvent {
        public String title {get;set;}
        public Boolean allDay {get;set;}
        public String startString {get;set;}
        public String endString {get;set;}
        public String url {get;set;}
        public String className {get;set;}
    }
}

Tested to 10'000 records with this execute anonymous

event[] bulklist= new event[]{};
for (integer i = 0; i < 100000; i++)
{
    string srnd = string.valueOf(math.random());
    blob rnd = Blob.valueOf(srnd);
    bulklist.add(new event (
        subject=encodingUtil.base64Encode(rnd),
        startDateTime=system.now().addDays(-10+ (math.random() * 10 ).intValue()),
        isAllDayEvent=true     
    ) );
}
insert bulklist;

To do: test with natural distribution graph.

@Nelson9206-zz
Copy link

Hi Guys

Could someone please assist me in having this setup in my org. I have tried copying the above code but nothing seems to be displaying. I am new to javascript, perhaps I am not doing something right. Can someone please send me a full sample based on the aforementioned tutorial. It seems dated so I am not sure if it still works the same.

Kind Regards

@beccig
Copy link

beccig commented Jun 26, 2017

Hello,

I have implemented this solution and it is populating great. But how do you call a refetch or refresh when there are changes? I have tried several things and nothing will make it go out to the controller and get a new JSON list to populate. It just populates the same thing.

Thank you for you help. I have been trying for 3 months and currently just refresh the entire page with a submit button. It works but does not bring the user back to the page they were on.

@beccig
Copy link

beccig commented Jul 20, 2017

Hello,
I'm still looking for help on this to be able to refetch event. Any help is appreciated :-).

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment