I recently needed to do a proof of concept to ensure TypeScript would work with the FullCalendar plugin, as I was planning on using these together in a new app I’m working on. When I searched for any information on this combination, I didn’t find much, which is why I’m writing this.
Now if you’ve found your way here, then I’m sure you’re already familiar with TypeScript so I won’t go into detail on what TypeScript is and how it works. The TypeScript site does that so well itself anyway so if you’re curious, check it out here – http://www.typescriptlang.org/.
The good new is, THEY DO WORK TOGETHER! The even better news is, someone has already written a type definition which has been included in the DefinitelyTyped project. So it’s quite quick and easy to get up and running with this. As I mentioned, this is a proof of concept so I haven’t spent too much time on code structure so please don’t take the structure of my code as the best way, this is just to show you quickly, how I proved this will work.
I’ve got a basic Web Application in Visual Studio. I’ve then used nuget to install the following packages:
- jQuery (2.0.3 in this case, the latest at the time of writing)
- jquery.TypeScript.DefinitelyTyped (the jquery.d.ts file)
- fullCalendar.TypeScript.DefinitelyTyped (the fullCalendar.d.ts file)
I’ve also manually added the FullCalendar files (1.6.4 in this case, the latest at the time of writing). I also created a TypeScript file, which I’ve called App.ts which is where I’m going to put all my TypeScript code (this is what I was referring to earlier when I said please don’t take my code structure as the right way to do it. In a proper application I would have split my classes out etc).
Apologies for the not great formatting of the code. I really need to find a newer theme that deals with code snippets a bit better. I have also uploaded the whole Visual Studio project (it’s a VS2013 project so apologies if you can’t open it, but you will still be able to look at any of the files in Notepad etc). Links are at the end.
Ok, so first up, my reference paths at the top of my TypeScript file are:
/// <reference path="../typings/fullCalendar/fullCalendar.d.ts" />
/// <reference path="../typings/jquery/jquery.d.ts" />
Now my first class, my AppGlobal class. A simple class that has a function called InitiateCalendar which does the required setup of FullCalendar:
class AppGlobal {
InitiateCalendar(calEvents: CalendarEvent[]): void {
var calendar: JQuery = $("#calendar");
calendar.fullCalendar({
header: {
left: "month,agendaWeek,agendaDay",
center: "title",
right: "today prev,next"
},
events: calEvents,
firstDay: 1,
weekMode: "fluid",
dayClick: (date: Date, allDay: boolean, jsEvent: Event, view: FullCalendar.View) => {
goToDay(calendar, date, view);
}
});
}
}
You may have noticed that InitiateCalendar is expecting an array of CalendarEvent objects. This is another class I’ve created, inheriting from the FullCalendar EventObject defined in the fullCalendar.d.ts file. Here’s my CalendarEvent class:
class CalendarEvent implements FullCalendar.EventObject {
id: any; // String/number
title: string;
allDay: boolean;
start: Date;
end: Date;
url: string;
className: any; // string/Array
editable: boolean;
source: FullCalendar.EventSource;
color: string;
backgroundColor: string;
borderColor: string;
textColor: string;
// Constructor only requires the first 5 parameters, the rest are optional (this is personal choice)
constructor(id: any, title: string, allDay: boolean, start: Date, end: Date, url?: string, className?: any, editable?: boolean, source?: FullCalendar.EventSource,
color?: string, backgroundColor?: string, borderColor?: string, textColor?: string) {
this.id = id;
this.title = title;
this.allDay = allDay;
this.start = start;
this.end = end;
this.url = url;
this.className = className;
this.editable = editable;
this.source = source;
this.color = color;
this.backgroundColor = backgroundColor;
this.borderColor = borderColor;
this.textColor = textColor;
}
}
One of things that slowed me down a little in getting this up and running, was how best to call the methods such as gotoDate and changeView. You may notice in InitiateCalendar that I am calling a function goToDate on dayClick, so here is that function:
function goToDay(calendar: JQuery, date: Date, currentView: FullCalendar.View) {
if (currentView.name !== "agendaDay") {
calendar.fullCalendar("changeView", "agendaDay");
}
calendar.fullCalendar("gotoDate", date);
}
Again, I’m not saying this IS the best. It’s just the best way I’ve thought of myself so far. If you have a suggestion, please leave a comment! 🙂 My reasons for doing it this way at this point were:
- By saving $(“#calendar”) to a variable, I am only asking jQuery to select it once which means I am gaining a small performance increase each time I use it after that
- Every time I want to use the variable, it’s shorter and easier to write, especially as intellisense completes it for me
- Separating it out into a named function instead of leaving it in the anonymous function makes it accessible for unit testing if required
So the final part, at the end of my TypeScript file, I have the following:
$(document).ready(() => {
var app = new AppGlobal();
var events: CalendarEvent[] = [
new CalendarEvent(1, "Test Event 1", false, new Date(2013, 8, 1, 12, 0, 0, 0), new Date(2013, 8, 1, 13, 0, 0, 0)),
new CalendarEvent(2, "Test All Day Event 1", true, new Date(2013, 8, 2, 0, 0, 0, 0), new Date(2013, 8, 2, 0, 0, 0))
];
app.InitiateCalendar(events);
});
I hope this makes sense! As promised anyway, you can download a zip file with the Visual Studio 2013 solution here – https://dl.dropboxusercontent.com/u/88673025/FullCalendarWithTypescript.zip. Alternatively, if you’d prefer to just look at the TypeScript, you can get that here – https://dl.dropboxusercontent.com/u/88673025/App.ts
Hopefully this helps someone even if it just saves someone else doing a proof of concept 🙂 Any questions, leave a comment and I’ll try and help!