24 August 2009

jQuery FullCalendar and ASP.NET MVC

Recently I had to integrate jQuery FullCalendar into ASP.NET MVC application. Up to now I was not able to find such an example, so I will try to provide one. I assume that you are familiar with ASP.NET MVC, jQuery and FullCalendar component, so I’m not going to introduce each technology.
image I will use the default ASP.NET MVC Web Application template to create new project. Please, note that the jQuery is included by default, so there is no need to download and reference it.
The first step would be to place FullCalendar JavaScript and style-sheet files inside project’s Scripts and Content directory as shown in the picture.
Then we need to reference the files we just added to our project. I will do it by placing the following lines of code inside the <head> section of Site.Master file:
<head runat="server">
   <title><asp:ContentPlaceHolder ID="TitleContent" runat="server" /></title>
   <link href="../../Content/Site.css" rel="stylesheet" type="text/css" />
   <link href="../../Content/fullcalendar.css" rel="stylesheet" type="text/css" />
   <script src="../../Scripts/jquery-1.3.2.js" type="text/javascript"></script>
   <script src="../../Scripts/fullcalendar.js" type="text/javascript"></script>
</head>
Now we are ready to use the calendar routines inside our views. How to do it? Just create a div tag and render the calendar’s HTML code inside. Here is how to modify Home’s Index.aspx:
<asp:Content ID="indexContent" ContentPlaceHolderID="MainContent" runat="server">

   <script type="text/javascript">
       $(document).ready(function() {
           $('#calendar').fullCalendar({
               events: "/Home/CalendarData"
           });
       });  
   </script>

   <div id="calendar">
   </div>
</asp:Content>
The code above will render the calendar’s HTML inside a div with id=”calendar”. The calendar data will be delivered by invoking the following URL: /Home/CalendarData. This corresponds to CalendarData method from the Home controller. This controller is supposed to return the data in Json format. Here is a sample implementation:
    [HandleError]
   public class HomeController : Controller
   {
       public ActionResult CalendarData()
       {
           IList<CalendarDTO> tasksList = new List<CalendarDTO>();

           tasksList.Add(new CalendarDTO
           {
               id = 1,
               title = "Google search",
               start = ToUnixTimespan(DateTime.Now),
               end = ToUnixTimespan(DateTime.Now.AddHours(4)),
               url = "www.google.com"
           });
           tasksList.Add(new CalendarDTO
           {
               id = 1,
               title = "Bing search",
               start = ToUnixTimespan(DateTime.Now.AddDays(1)),
               end = ToUnixTimespan(DateTime.Now.AddDays(1).AddHours(4)),
               url = "www.bing.com"
           });

           return Json(tasksList);
       }

       private long ToUnixTimespan(DateTime date)
       {
           TimeSpan tspan = date.ToUniversalTime().Subtract(
    new DateTime(1970, 1, 1, 0, 0, 0));

           return (long)Math.Truncate(tspan.TotalSeconds);
       }

       public ActionResult Index()
       {
           return View();
       }

       public ActionResult About()
       {
           return View();
       }
   }
The code above creates two calendar entries called “Google search” and “Bing search”. Everything should be pretty simple, except the stuff around ToUnixTimespan routine.
There is well known problem with serialization of dates in Json format. There is no strict standard, so there are several approaches to this problem. For example, take a look here. The implementation adopted by Microsoft was not recognized by FullCalendar, so I had to introduce the ToUnixTimespan routine. Basically, this routine returns the seconds after 1/1/1970.
Because of the above, you should notice that the start and end dates are represented as int:
    public class CalendarDTO
   {
       public int id { get; set; }
       public string title { get; set; }
       public long start { get; set; }
       public long end { get; set; }
       public string url { get; set; }
   }
If you have done everything correct, the final result will be
image

Enjoy!

Edit: Due to the higher interset I have published the source code of this post here. Please note that Visual Studio 2008 is used and you need to convert the project if more recent version is used.

17 comments:

CmdrTallen said...

My hats off to you sir, my project went from 3 days to 1 hour. Woot!

Anonymous said...

thank you sir, been stressing with this for a long time now.

Anonymous said...

I copied everything you did, when building and navigating to Home/CalendarData I get a save file dialog.
The dialog contains all the json info. Any idea what I'm doing wrong?

Stephan Zahariev said...

You have to open the Home/Index URL. The Home/CalendarData is used by the FullCalendar to fetch data from the server.

Anonymous said...

Thanks for the quick reply!
However, navigating to Home/Index, renders nothing, and I get only the contents of my master page.

Red Swan said...

This is great application. but some how i am unable to stick the events which comes from action on my fullcalender control. what have to ?

Anonymous said...

Hello Sir,

Please help me. I copied all code but did not get any events in calendar. what m i doing wrong?

Unknown said...

add JsonRequestBehavior.AllowGet like so.
i.e change return Json(tasksList);
To
return Json(tasksList,JsonRequestBehavior.AllowGet);

Unknown said...

Great; may always be prosperity on all you do.

Thanks.

Anonymous said...

Thank you!!!!

Unknown said...

like some other posters I dont get any events in the calendar

as far as i can see i copied the code exactly

thanks in advance

Graham said...

Shouldn't CalendarData be declared as JsonResult?

Stephan Zahariev said...

@neal
Most probably your jQuery setup is not correct. Please make sure that the jQuery and the FullCalendat bits are correctly referenced.

@Graham
Yes, you could declare it as JsonResult.

Anonymous said...

I have a stupid question: How on earth do you remove an event that you already created? I would like to know how can I delete an event after I have placed it on the calendar. There must be a simple way to do this

Anonymous said...

i want to use this full calendar in my application inside the wizard can anyone pls help me... it is not calling ashx page when i click on Next button

Unknown said...

Great tutorial. Issue: on document.ready, full calender binds all the event details including the start & end date, but not time i.e the event is rendered in appropriate date slot as expected, but not in appropriate time slot.

Ling said...

is there any VB.net version instead of C#? That will be great if it have. Thanks.