FullCalendar jQuery Plugin

This post is more than 2 years old.

This isn't going to be a real deep post - more of a "Cool, take a look" type thing. A while back I found the FullCalendar jQuery plugin. As you can probably guess, it's a plugin that provides a full calendar view for dates. I finally made myself take some time to play with it and I'm pretty darn impressed. Some of the features include:

  • Ability to edit events (move them around to reschedule)
  • Obviously the ability to load events via JSON, but even cooler, the ability to integrate with Google Calendar
  • Multiple views (from calendar to week to day)
  • Lots of customization

I ran into a few issues while working with the code, but nothing too terrible. Here's a simple example with a few customizations:


<link rel="stylesheet" text="text/css" href="fullcalendar-1.5.1/fullcalendar/fullcalendar.css" />
<script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.7.1/jquery.min.js"></script>
<script type="text/javascript" src="fullcalendar-1.5.1/fullcalendar/fullcalendar.js"></script>
$(document).ready(function() {

		aspectRatio: 2,
		buttonText: {
			today:"Go to Today"


<div id="cal"></div>


As you can see, there isn't much going on here. I've got a div that will store my calendar and then I simply point to it with the plugin. All of the options I have there (and I'll explain them in a second) are optional.

So what did I customize and why? Oddly the height of he calendar, by default, was always a bit too tall for the screen in Chrome. Setting an aspectRatio of 2 seemed to work well to keep the calendar on screen. I don't think I full understand yet how best to use it, but in playing around it worked ok.

Another minor customization was to the today button. By default the calendar will include a button to return to you the current month and current day. That button's default label was "today". The lowercase bugged me. Luckily you can see how easy it was to customize. (I could easily remove it as well.)

Finally it would be nice to include some events, right? I pointed to a CFC called events. The plugin will pass a start/end range to your back end service and then you simply return the data. It requires an array of events and their docs clarify what each event object should contain. Here's the CFC I used:

component {
	remote function getEvents(any start, any end) {
		var realStart = epochTimeToDate(start);
		var realEnd = epochTimeToDate(end);
		writelog(file="application", text="Asked for #realstart# to #realend#, orig start=#start#");

		var q = new com.adobe.coldfusion.query();   		     
        q.setSQL("select id, title, posted from tblblogentries where posted >= :start and posted <= :end");        
        var dbresults = q.execute().getResult();
        writelog(file="application", text="Result: #dbresults.recordCount#");

        var results = [];
        for(var i=1; i<= dbresults.recordCount; i++) {
        	arrayAppend(results, {
        return results;
	//Credit Chris Mellon - http://www.cflib.org/udf/EpochTimeToDate
	private function epochTimeToDate(epoch) {
    	return DateAdd("s", epoch, "January 1 1970 00:00:00");

	//Credit Chris Mellon - http://www.cflib.org/udf/GetEpochTime	
	private function getEpochTime() {
	    var datetime = 0;
	    if (ArrayLen(Arguments) is 0) {
	        datetime = Now();
	    else {
	        if (IsDate(Arguments[1])) {
	            datetime = Arguments[1];
	        } else {
	            return NULL;
	    return DateDiff("s", "January 1 1970 00:00", datetime);    


The plugin sends a date range to you in UNIX time stamps - which are the number of seconds since epoch. Luckily there's a nice UDF at CFLib to make that easy to work with. I noticed that the ranges included a start time of 6AM. When I did my query I wanted to drop that so I used a cf_sql_date instead of timestamp queryparam. I'll be coming back to this.

Once I've got my data, it was a simple matter to convert it to an array of structs. And that's it. Check out the demo:

The old demo has been removed. You can download it here: https://static.raymondcamden.com/enclosures/july162011B.zip

So - the one thing I'm kinda stuck on is the whole time issue. Remember above where I said the plugin would send a time of 6AM along with it's date range? I can't get rid of that. So if I have something at 5AM on the first day of the range it won't show up. Normally the first day is the previous month. On the demo now that is May 29th. But in January, 2012, the first day is the real first day of the month. Even though I return an event for that (in my local testing environment), the plugin wanted to render it for the previous day. It's got to be some timezone issue I don't fully understand.

That's it for now. Overall - it seems like a darn cool little plugin. Fellow ColdFusion-er Jim Leether is also using it. You can see his example here. Anyone else?

Edit on February 13, 2013: James Moberg noted below that my demo stopped working with the latest jQuery due to curCSS being removed from jQuery. Most likely the latest edition of this jQuery plugin fixes that. In order to make my demo work, I went from using the latest 1.* branch of jQuery to 1.7.1 specifically. I'd urge readers to see if the latest build of the plugin is corrected, and if not, to file a bug with the owner.

Raymond Camden's Picture

About Raymond Camden

Raymond is a senior developer evangelist for Adobe. He focuses on document services, JavaScript, and enterprise cat demos. If you like this article, please consider visiting my Amazon Wishlist or donating via PayPal to show your support. You can even buy me a coffee!

Lafayette, LA https://www.raymondcamden.com

Archived Comments

Comment 1 by Sean Coyne posted on 6/17/2011 at 4:38 PM

+1 for FullCalendar! We used it on the Middlesex Hospital website <a href="http://middlesexhospital.or...">http://middlesexhospital.or... it is a fantastic jQuery plugin. The best calendar plugin I have seen.

Comment 2 by Sean Coyne posted on 6/17/2011 at 4:39 PM

I guess I didn't need the anchor tag. Link again: http://middlesexhospital.or...

Comment 3 by Steve Withington posted on 6/17/2011 at 5:46 PM

@Sean, sweet job on the calender w/filtering!

Comment 4 by Jody Fitzpatrick posted on 6/17/2011 at 5:48 PM

Very nice Ray!

I wonder if this can be integrated with ben nadels calender? have you seen it?

Comment 5 by Sean Coyne posted on 6/17/2011 at 5:57 PM

@Steve Thanks. We also used it for an administration area. With FullCalendar's drag and drop support, we make it really easy for users to copy previously used calendar events. They search for an event, then drag and drop it onto a date in the calendar. This fires off an ajax request which copies the event, changes some dates and such and saves the new record. FullCalendar has some great event hooks that you can use to create some really cool interfaces.

Comment 6 by Steve Withington posted on 6/17/2011 at 6:03 PM

@Sean, what a perfect use case for the drag+drop. not to mention the use of jQuery UI for even details, etc. well done.

Comment 7 by Raymond Camden posted on 6/17/2011 at 6:19 PM

Jody - my understanding is that _any_ database could be used. All you need to do is write a wrapper. I mean look at my demo - it wasn't even "events" but blog entries. I just had to spit the data out in the right way.

Comment 8 by Raymond Camden posted on 6/17/2011 at 6:57 PM

Ditto Steve - Sean that's a nice calendar!

Comment 9 by PaulH posted on 6/17/2011 at 7:14 PM

not a JS expert but isn't it's epoch offset the same as java, in ms since 1-1-1970? if that's the case you can use dateTime.getTime() to get the epoch offset in cf & dateTime.setTime(epochOffset) to change back to a cf datetime.

flash player's behavior in changing incoming datetimes to client tz used to rub me the wrong way but i eventually went w/the flow & passed epoch offsets back & forth. never fallen into tz hell for a flex app since ;-)

Comment 10 by Mark Ross posted on 6/17/2011 at 8:59 PM


I haven't done any testing (I should but am busy today), but your timezone issue might be related to one of these lines in your cfc:

return DateAdd("s", epoch, "January 1 1970 00:00:00");
return DateDiff("s", "January 1 1970 00:00", datetime);

You aren't putting a timezone offset in either call. So its defaulting to GMT time (which is 5 hours off CST right now). That could be the issue. I recently ran into something similar in my code, so it caught my eye.

Sorry I couldn't test, but see if adding (-05) like this helps:

return DateAdd("s", epoch, "January 1 1970 00:00:00-05");

Comment 11 by C.J. posted on 6/17/2011 at 9:21 PM

How well does their solution work with multi-day events? I always seem to have an issue with cross-month, multiday events in these calendar systems. It definitely looks good though!

Comment 12 by Raymond Camden posted on 6/17/2011 at 9:30 PM

@CJ: Check the demo - they examples of multiday events.

@Mark: Hmmm. To be clear - when my db script ran for Jan 2012, it did get one result. Because I ignored times, it found my test. But when I returned it - it showed up in Dec 2011. So your saying my 'to epoch' code needs to be omdded.

Comment 13 by SuperAlly posted on 6/18/2011 at 1:05 AM

Thanks Ray. Great post.
Couldn't get the calendar to display the events for the life of me, until I realized debugging was on!

Comment 14 by Raymond Camden posted on 6/18/2011 at 1:06 AM

Heh, that's burned more than one person. Really hoping Adobe adds cfsetting to script-based CFCs in the next update.

Comment 15 by Chris posted on 6/18/2011 at 1:45 AM

We are using this same calendar and JQuery UI for drag and drop to add new events (emails, tweets, fb posts). When a new "event" is dropped onto the calendar, we open a modal w/ a form for that particular event type. We're also showing tooltips for each event since real estate on each date is limited (app requires a login, but here's a screenshot: http://emailer.emfluence.co....

One thing I'd like to see added is the ability to easily color-code the calendar days based on date (e.g. highlight this week or gray out past dates). Anyone had any success with that?

Comment 16 by Incircle Media posted on 6/18/2011 at 1:30 PM

Nice script for calender.

Comment 17 by Lola LB posted on 6/18/2011 at 2:11 PM

Wow . . . nice calendar! Bookmarking this entry for future reference . . .

Comment 18 by Glen posted on 6/20/2011 at 6:36 AM

Yes, I am using FullCalendar in conjunction with CFEXCHANGE.

Basically a read only view of an Exchange calendar for users to see when events are scheduled ... am yet to extend this so users can download the iCal for an event.

Would be nice to integrate it as a view on blog posts - i.e. a blog post would equate to an 'event'. Maybe better used on a blog aggregator?

Comment 19 by Raymond Camden posted on 6/20/2011 at 6:43 AM

Glen - did you try my demo? It's exactly that.

Comment 20 by Glen posted on 6/20/2011 at 6:48 AM

Doh! Maybe if I read the whole post I would see that you are using blog posts.

I'll get my coat.

Comment 21 by Raymond Camden posted on 6/20/2011 at 6:49 AM

Trust - I've done it plenty of times. Don't feel bad.

Comment 22 by Brad Newman posted on 6/20/2011 at 10:41 PM

This is fantastic! I would like to have a query on the page and display static events with this. Any idea of how I would create an array of events on the same page without passing this back in a JSON format?

Comment 23 by Raymond Camden posted on 6/20/2011 at 10:44 PM

The docs talk about this. Just check their examples of static data. Let me know if it doesn't make sense. I assume your data is still dynamic - you just don't want to load it via JSON?

Comment 24 by Brad Newman posted on 6/20/2011 at 11:47 PM

Thanks Ray, I'll have a look at the docs. And yes, I am trying to load dynamic data without the JSON call.

Comment 25 by Raymond Camden posted on 6/20/2011 at 11:49 PM

It's definitely possible then. If you have any issues getting CF to output it right, let me know.

Comment 26 by Jaana Gilbert posted on 6/21/2011 at 5:22 PM

That is one sweet momma calendar hehe. Later this year I have to rework over a 10yr old calendar/events app that I built originally in 2000 and this may be the solution. As soon as I figure out how to get the drag and drop to work with our strict business rules, this will be a absolutely winner!!

I'm going to be spending my evening looking into this plugin instead of farming :)

Thanks again!

Comment 27 by Travis posted on 7/19/2011 at 8:13 PM

Great post! I changed the code to use

Comment 28 by Kamil posted on 7/21/2011 at 7:52 PM

Ray, This post couldn't have come at a better time: I have used your code for a new project that needed a free-flowing, blog type calendar and one in regular calendar format. It is currently at its development site here: http://yourtowntv.rhapsodys...

Comment 29 by Raymond Camden posted on 7/24/2011 at 2:18 AM

Glad to help. FYI,your link leads to an error.

Comment 30 by Kamil posted on 7/24/2011 at 4:46 AM

Thanks for the heads up -- it has been fixed now. The new link is: http://www.yourtowntv.com/c...

Comment 31 by Marc Cerabona posted on 8/4/2011 at 7:40 PM

Did anyone have problems with the event displaying in the wrong month? I got the calendar to take my dates, and they look right in the source code, but the calendar puts them exactly one month ahead of the actual date. to the day.

Comment 32 by Raymond Camden posted on 8/4/2011 at 8:16 PM

Can you share the code? A link is better. If you can't, use Pastebin and share that link.

Comment 33 by Misty posted on 9/19/2011 at 12:17 AM

hey ray, gr8 work can u just try the same with user friendly cfcomponent tag,

that will be great if u do


Comment 34 by Raymond Camden posted on 9/19/2011 at 1:22 AM

Sorry - what? You mean a tag based component?

Comment 35 by Misty posted on 9/19/2011 at 11:20 AM

yes, tad Based Component

Comment 36 by Raymond Camden posted on 9/19/2011 at 2:02 PM

Well, it is just a query and a loop. I know the script syntax is a bit new for folks, but if you take it line by line, it should be easy to rewrite into tags.

Comment 37 by Pauly posted on 10/28/2011 at 8:09 AM

I guess this is CF9 code cos I'm getting errors in CF8 with that CFScript arrayappend block. Tried initially to rewrite in tag code:

<cfset arrayAppend(results,{"id"=id,"title"=title,"start"=start,"url"=url})>

But, its dishing up an error: Missing argument name.When using named parameters to a function, every parameter must have a name....

Comment 38 by Raymond Camden posted on 10/28/2011 at 3:02 PM

Change it to:
<cfset s = structNew()>
<cfset s.id = id>
and so on

<cfset arrayAPpend(results, s)>

Comment 39 by Pauly posted on 10/31/2011 at 2:17 AM

Thanks Ray,
Got the query returning data, apparently correctly according to Firebug. But, the event isn't displaying in the calendar. http://scrapbookcentral.01d.... Any idea why that might be?

Comment 40 by Pauly posted on 10/31/2011 at 2:56 AM

Further to above, I think the issue is with my JSON keys returning in uppercase. Running your demo, I see that yours are lowercase.

Comment 41 by Pauly posted on 10/31/2011 at 3:21 AM

Sorted with the following:
<cfset s = structnew()>
<cfset s["id"] = id>
<cfset s["url"] = url>
<cfset s["title"] = title>
<cfset s["start"] = start>
<cfset arrayappend(results, s)

Comment 42 by Raymond Camden posted on 10/31/2011 at 3:25 AM

Glad you got it.

Comment 43 by Pauly posted on 10/31/2011 at 3:38 AM

It was thanks to this post http://www.coldfusionjedi.c... :-)

Comment 44 by Shawn Bowman posted on 11/22/2011 at 9:13 PM

I just wanted to say thanks. I used this code and tied it with my current DB that has events with a start and an end date already entered which I just adjusted the query to accept it.

Comment 45 by Shawn Bowman posted on 11/23/2011 at 2:24 AM

I have been beating my head on how to exactly set the colors for each even other than allowing someone when setting the events to specify the color. I was thinking possibly checking the title and if it contained a specific word to then specify the color with an if then. Such as: if title.indexOf("something") then color="red" I am sure its rather easy but I seem to be rather stuck.

Comment 46 by Raymond Camden posted on 11/23/2011 at 2:38 AM

Did you try the support options over at the plugin?


Not saying to go away (grin), but it sounds like something you may get better luck with there.

Comment 47 by Shawn Bowman posted on 11/23/2011 at 3:09 AM

I will try there..thanks Ray...I didn't see the stackoverflow link until just now. Plus I'm lazy....

Comment 48 by Raymond Camden posted on 11/23/2011 at 3:24 AM

We all are. ;)

Comment 49 by Shawn Bowman posted on 11/23/2011 at 3:31 AM

Just to help out any future users looking for this answer.

The FullCalendar Eventsources allows you to specify different sources for events...so in essence you can call a function that pulls event group 1 assign it a color and then specify another source and call the function that pulls in group 2 and assign it a color.


eventSources: [

// your event source
url: '/myfeed.php',
type: 'POST',
data: {
custom_param1: 'something',
custom_param2: 'somethingelse'
error: function() {
alert('there was an error while fetching events!');
color: 'yellow', // a non-ajax option
textColor: 'black' // a non-ajax option

// any other sources...



Comment 50 by Raymond Camden posted on 11/23/2011 at 3:33 AM

Interesting - I would have assumed it could have allowed you to specify a key in your event data instead.

Comment 51 by Shawn Bowman posted on 11/23/2011 at 3:33 AM

Silly copy and paste....it has PHP ...anyways that's the general idea.

Comment 52 by Shawn Bowman posted on 11/23/2011 at 3:37 AM

Well my original thought was to place an if then looking for a specific word in the title of the event and changing the color based on that, but with the EventSources it may give me a bit more flexibility.

I also considered allowing admins who add events into the database to assign specific colors to individual items, but I will address it with the users and see what they prefer.

I prefer hard-coding the colors because some people just don't have a keen eye for color :)

Comment 53 by erik posted on 12/17/2011 at 1:10 AM

Upon clicking on each event how can I launch the dialog ui popup and load an external there.

Also the events are different type. That said based on the type the loaded page will be different

Comment 54 by Raymond Camden posted on 12/17/2011 at 8:05 PM

Erik, I'd recommend reading the docs on the site. There should be a way to handle that event.

Comment 55 by erik posted on 12/17/2011 at 8:15 PM

Hi Ray.
The examples that are given on the site only cover non conditional setup.

And do you know any sites that are using sophisticated fullcalendar plugin.

Comment 56 by Raymond Camden posted on 12/17/2011 at 8:25 PM

Not sure what you mean by non-conditional setup. The docs (I just checked) cover event clicks. Therefore you can handle a click on an event. If your event contains a type value, then you would be able to get that in the event handler. Not trying to be unhelpful here, but I do think the event click documentation is where you should check.

I just looked - and in the Event Object doc, they state you can include non-standard fields. So simply use that to include your 'type' attribute.

As for real examples, Im not seeing that on the site, but you could possibly reach out to the author of the plugin.

Comment 57 by james Moberg posted on 2/12/2013 at 10:27 PM

Your fullCalendar demo doesn't work. The latest jQuery library you are using is not compatible with the old fullCalendar scripts since fullCalendar used a now-deprecated curCSS() function.

Comment 58 by Raymond Camden posted on 2/13/2013 at 5:36 AM

Thanks James. So... I'd either ask folks to use an older version of jQuery or ping the author of fullCalenadar for an update.

Comment 59 by James Moberg posted on 2/13/2013 at 5:44 AM

No problem. I wanted to make sure that you were aware. I had recently upgraded the fullCalendar library and found your article while searching for some information regarding adding a US Holiday Google Calendar. I wanted to quickly view your demo to see what you had done, but couldn't because it was broken due to the updated core library. jQuery & fullCalendar are current/relevant technologies, your demo ranked high in the search engine and I didn't know if you were updating sample code when your site core libraries were updated.

Comment 60 by Raymond Camden posted on 2/13/2013 at 5:51 AM

Tomorrow I'll see about updating this to use a specific jQuery version. Both in the demo and in the blog post.

Comment 61 by Raymond Camden posted on 2/13/2013 at 4:46 PM

Demo fixed and note added to end of entry. Thanks James!

Comment 62 by Sans Nom posted on 2/28/2013 at 3:13 AM

Demo is broken again.

Comment 63 by Raymond Camden posted on 2/28/2013 at 3:28 AM

Weird, I fixed it in test2.html. I must have forgotten to change the link. Will do so now. In the meantime, just change test.html to test2.html.

Comment 64 by dwayne anderson posted on 9/19/2013 at 10:48 PM

another useful post Ray...

I've converted the script to tags, but even though the results are identical, the client is not recognizing it. Anything obvious I missed?

<cffunction name="getEvents" access="remote">
<cfargument name="site_id" type="any" required="false" />
<cfquery name="getallevents" >
Select event_id, event_name, event_start_datetime
from event
where site_id = <cfqueryparam value="#arguments.site_id#">
order by event_start_datetime
<cfset url.returnformat="json">
<cfset results = []>
<cfloop query = "getallevents">
<cfset s = structnew()>
<cfset s["id"] = event_id>
<cfset s["title"] = event_name>
<cfset s["start"] = getEpochTime(event_start_datetime)>
<cfset s["url"] = event_id>
<cfset arrayappend(results, s)>
<cfreturn results />

Comment 65 by dwayne anderson posted on 9/19/2013 at 11:27 PM

nevermind, I found the error on the client side. The tag based function posted above works well.

Comment 66 by dwayne anderson posted on 10/31/2013 at 11:01 PM

I've added an array of colors and fixed the data conversion. This is all in a cfc and working great.


<cffunction name="getEvents" access="remote">
<cfargument name="site_id" type="any" required="false" />

<cfquery name="getallevents" >
Select event_id, event_name, event_start_datetime, event_end_datetime, category_id
from event
where site_id = <cfqueryparam value="#arguments.site_id#">
order by event_start_datetime

<cfquery name="getallcolors" dbtype="query">
Select distinct category_id
from getallevents

<cfset colorlist="red,green,blue,yellow,black,brown,orange,grey,aqua,darkred,darkgreen,darkblue,darkgrey,purple">
<cfset colorpos=1>
<cfset colors = []>

<cfloop query = "getallcolors">
<cfset thecolor='#listgetat(colorlist,colorpos)#'>
<cfif colorpos eq listlen(colorlist)>
<cfset colorpos=0>
<cfset colorpos=colorpos+1>
<cfset colors[#category_id#] = thecolor>

<cfset url.returnformat="json">
<cfset results = []>
<cfloop query = "getallevents">
<cfset eventurl ="eventdetails.cfm?id=" & "#event_id#">
<cfset eventcolor ="#colors[category_id]#">
<cfset s = structnew()>
<cfset s["id"] = event_id>
<cfset s["title"] = event_name>
<cfset s["start"] = getEpochTime(event_start_datetime)>
<cfset s["end"] = getEpochTime(event_end_datetime)>
<cfset s["url"] = eventurl>
<cfset s["color"] = eventcolor>
<cfset s["allDay"] = false>
<cfset arrayappend(results, s)>

<cfreturn results>

<cffunction access="private" name="getEpochTime" returntype="date">
<cfargument name="thedatetime" type="date"/>
<cfif (ArrayLen(Arguments) is 0)>
<cfset thedatetime = Now() />
<cfelseif IsDate(Arguments[1])>
<cfset thedatetime=Arguments[1] />
return NULL;
<cfreturn DateDiff("s", DateConvert("utc2Local", "January 1 1970 00:00"), thedatetime) />


Comment 67 by coldfusionPaul posted on 11/1/2013 at 5:11 AM

you can short circuit that "epoch" time (using seconds, that's actually unix time) by simply doing a theDateTime.getTime() to get back java epoch in ms (see my comment from 2011).

Comment 68 by Bud Hines posted on 12/9/2013 at 10:16 AM

Hi Ray,
I see a number of people are running into problems seeing their results show up in their calendar. I am one of them. I then remembered the issues I had seeing my grid when working with the jqgrid when robust debugging was turned on. So, I turned off robust debugging in cfadmin and I magically saw the results in my Calendar.

I then turned off showdebugoutput and that had the same result without turning off robust debugging in cfadmin.

Please advise your followers who are struggling to see results to add:
<cfsetting showdebugoutput="false"> right under <cfcomponent>.

Their component should look like this:

<cfsetting showdebugoutput="false">

I was able to see results without using the epochTimeToDate function.

I hope this helps someone.


Comment 69 by Jan posted on 5/7/2014 at 8:18 PM

Thanks for the code Ray - is there anywhere that you know of that gets this working with the drag and drop and having that update the database - I found something on Google ages ago but can't for the life of me find it again!!



Comment 70 by Raymond Camden posted on 5/7/2014 at 9:48 PM

Sorry no, I haven't played with this (plugin) in a while. (Well, that's a lie - I used it for a HarpJS demo a bit ago.)