ASP.Net MVC, jQuery and FullCalendar

I’ve been teaching myself two popular Model-View-Controller web developer frameworks lately:  ASP.Net MVC and Ruby on Rails.  Rails is the very popular (and successful) open source MVC framework based on the Ruby programming language, and ASP.Net MVC is Microsoft’s own open source (MS-PL) MVC framework.  As a .Net developer, I’m very comfortable with VB.Net and C#, so ASP.Net MVC feels like home to me, but there’s no denying the flexibility and power of Rails, largely due to the terseness and elegance of the Ruby language, which is a dynamically typed powerhouse.

However, I thought I would take some time today to discuss my ASP.Net MVC discoveries, particularly the goodness that is MVC and its ease of use with the jQuery javascript library.  I simply love jQuery, since it makes working with the DOM a joy.  Since discovering it some time ago, I have never, ever had to write a single GetElementbyID JavaScript function.  Praise God (well, actually…John Resig, the author of jQuery)!

The jQueryUI library (not part of the jQuery core, but a lovely addition…) makes advanced styling choices for MVC easy as well.  You can add accordion controls, dialog boxes, button, and date pickers with just a few lines of code.

My MVC app is an on-call tracking application to allow people to see who is on-call for which system.  The first (and perhaps most fun) part of recoding this in MVC was the ease by which I was able to get the application’s CRUD (Create/Read/Update/Delete) functionality working.  It was trivial and took less than an hour to do.  Strongly typed views and helper methods, combined with the data annotations for validation that MVC provides meant that I had to write very little code to have relatively “user-proof” application running.

Now, I wanted to spiff up the UI a bit.  The basic idea was to use an in-line date picker widget from jQueryUI to allow a person to select any date, and then display who is on-call for that date.  Normally, I would have just returned the oncall information in either a table or an unordered list, but I happened to stumble across the FullCalendar jQuery plugin, and sweetness abounded:

On-Call App Screenshot
using jQuery and FullCal for a better effect...

So the datepicker (the calendar at left) is wired up to the FullCalendar plugin (on the right).  All updates are delivered via AJAX, so there are no unnecessary postbacks to the page.  It’s light, fast and elegant, and it was ridiculously easy to implement.  Here’s the JavaScript code:

 //Set up the date picker and wire it's onSelect function
 //to the FullCalendar plugin.
    $("#datepicker").datepicker({
        inline: true,
        onSelect: function (dateText, inst) {
            var d = new Date(dateText);
            $('#calendar').fullCalendar('gotoDate', d);
        }
    });

    //Set some defaults for the fullCalendar, including the URL to
    //get the data from...
    $('#calendar').fullCalendar(
        {
            theme: true,
            defaultView: "basicWeek",
            firstDay: 1,
            events: "/Schedule/GetCalendar/"
        });

So, we instantiate an inline datepicker, and set its onSelect event to tell the FullCalendar widget which date to go to, and that’s it!  Very easy and very, very slick!  Of more interest, however, is the events: method in the FullCalendar code itself.  The URL “/Schedule/GetCalendar” is where (via AJAX) the FullCalendar will get its list of oncalls (events) from.

ASP.Net MVC makes this simple.  Here’s the controller code:

   public JsonResult GetCalendar(double start, double end)
        {
            var events = new List<MvcOncall.Event>();
            var dtstart = ConvertFromUnixTimestamp(start);
            var dtend = ConvertFromUnixTimestamp(end);
            var onCalls = from oc in _ctx.OncallScheds
                          where oc.oncallDate >= dtstart
                          select oc;
            DateTime currStart;
            DateTime currEnd;
            foreach(OncallSched oc in onCalls)
            {
                currStart = Convert.ToDateTime(oc.oncallDate);
                currEnd = Convert.ToDateTime(oc.oncallEnds);
                events.Add(new MvcOncall.Event()
                {
                 id = oc.ID,
                 title = oc.Team.TeamName + ": " + oc.Contact.ContactName,
                 start = currStart.ToString("s"),
                 end = currEnd.ToString("s"),
                 allDay = false,
                 url = "/Schedule/Details/" + oc.ID.ToString() + "/"
              });
            }
            var rows = events.ToArray();
            return Json(rows,JsonRequestBehavior.AllowGet);
        }

This is pretty simple stuff, but there are a few points to highlight.  Note that the method GetCalendar() returns a JSONResult (not an ActionResult), since we will be serializing our data using the nifty JSON format.  We could have used XML, but we’re sane, so we don’t do that.

I did have to do some UNIX date conversion for this to work (note the ConvertFromUnixTimestamp() function calls), but I found a c# routine on the Net that made this trivial.

First, we query the model using LinQ to Entities (our model here is built by Entity Framework) and retrieve a collection of onCallSched items for the appropriate date range.  Finally, we convert the oncallScheds into generic objects with the properties required by FullCalendar, and return an array of these objects, again serialized as JSON.

Simple, elegant and fun!

4 thoughts on “ASP.Net MVC, jQuery and FullCalendar

    1. Well, that depends on what you mean. In my example, my events are coming from the db (via Entity Framework), so if you mean after a new event added to the db how do you update the calendar to include that new data, then the answer is that you need to trigger fullCal to do a refresh (probably with a refreshEvents call). You could use something like signalR to provide the trigger mechanism, or you could just capture the button click on the form that creates the event, and then call refreshEvents in your click event.

      Hope that helps!

      John

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s