Wednesday, February 1, 2012

Full Calendar with JSON data source using asp.net web service/ pagemethod/ webmethod

In this blog post we are going to discuss using full calendar plugin with JSON data source through asp.net webservice / pagemethod / webmethod. We can get the detail of the plugin here.

For using this plugin we need to add the reference of the following files-
    <script src="http://ajax.googleapis.com/ajax/libs/jquery/1.4.4/jquery.min.js" type="text/javascript"></script>
    <script src="http://ajax.googleapis.com/ajax/libs/jqueryui/1.8.6/jquery-ui.min.js" type="text/javascript"></script>
    <link rel='stylesheet' type='text/css' href='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.css' />
    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/jquery/jquery-ui-1.8.11.custom.min.js'></script>
    <script type='text/javascript' src='http://arshaw.com/js/fullcalendar-1.5.2/fullcalendar/fullcalendar.min.js'></script>
Basic style HTML infrastructure using for this implementation is as follows-
        #loading
        {
            width: 600px;
            height: 550px;
            position: absolute;
            background-color: gray;
            color: white;
            text-align: center;
            vertical-align: middle;
            display: table-cell;
        }
        #fullcal
        {
            width: 600px;
            height: 600px;
            position: absolute;
            display: none;
        }
    <div>
        <div id="loading">
            <label style="top: 50%; position: relative">
                loading events....</label>
        </div>
        <div id="fullcal">
        </div>
    </div>
In the div with id fullcal we will be loading the calendar control. By default this div is marked as hidden, and a place holder div (with id loading) is added in the place. This is just to show while server data is getting loaded from server. Once the data is loaded on the calendar we will show back the calendar and hide the placeholder.

The script used for activating calendar is as follows-
    $('div[id*=fullcal]').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        events: list of event here
    });
Now in full calendar the event object has lots of information. We can get more information about the event object here. Lets represent the event as a C# class as follows-
public class Event
{
    public int EventID { get; set; }
    public string EventName { get; set; }
    public string StartDate { get; set; }
    public string EndDate { get; set; }
}
There are many other properties for the event object. For the sack of implementation we are taking these only. And I think the class properties are self explanatory. We can get the data for the event from database. For this post we are creating in memory object for data source. The page method used for data retrieval is as follows-
   [WebMethod]
    public List GetEvents()
    {
        List events = new List();
        events.Add(new Event()
        {
            EventID = 1,
            EventName = "EventName 1",
            StartDate = DateTime.Now.ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(2).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 2,
            EventName = "EventName 2",
            StartDate = DateTime.Now.AddDays(4).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(5).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 3,
            EventName = "EventName 3",
            StartDate = DateTime.Now.AddDays(10).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(11).ToString("MM-dd-yyyy")
        });
        events.Add(new Event()
        {
            EventID = 4,
            EventName = "EventName 4",
            StartDate = DateTime.Now.AddDays(22).ToString("MM-dd-yyyy"),
            EndDate = DateTime.Now.AddDays(25).ToString("MM-dd-yyyy")
        });
        return events;
    }
Now we can read the web service data using jQuery and fill the full calendar using server driven event list like following-
    $.ajax({
        type: "POST",
        contentType: "application/json",
        data: "{}",
        url: "FullcalenderwithWebservice.asmx/GetEvents",
        dataType: "json",
        success: function(data) {
            $('div[id*=fullcal]').fullCalendar({
                header: {
                    left: 'prev,next today',
                    center: 'title',
                    right: 'month,agendaWeek,agendaDay'
                },
                editable: true,
                events: data.d
     });
            $("div[id=loading]").hide();
            $("div[id=fullcal]").show();
        },
        error: function(XMLHttpRequest, textStatus, errorThrown) {
            debugger;
        }
    });
Now here is a slight problem, the calendar will get loaded but not the list of events returned. Few points we need to remember here-
  1.  The full calendar event object has certain naming like EventID should be id, EventName – title, StartDate – start, EndDate – end and so on. So, we have to map the returned object to full calendar’s desired object.
  2. One more thing that we need to remember is that the start and end need to be in date type. The proper conversation is as follows-
    $('div[id*=fullcal]').fullCalendar({
        header: {
            left: 'prev,next today',
            center: 'title',
            right: 'month,agendaWeek,agendaDay'
        },
        editable: true,
        events: $.map(data.d, function(item, i) {
                    var event = new Object();
                    event.id = item.EventID;
                    event.start = new Date(item.StartDate);
                    event.end = new Date(item.EndDate);
                    event.title = item.EventName;
                    return event;
                })
    });
We can note one more thing that we are returning the date in MM-dd-yyyy format (DateTime.Now.ToString("MM-dd-yyyy")). The reason is that we can pass such a string to Date constructor in JavaScript to create the date.

We can download the full source code from here.

27 comments:

  1. hey can u tell code for inserting data into mssql after event creation.....thnx

    ReplyDelete
    Replies
    1. Hi,
      I have added another post regarding this-
      http://growingtech.blogspot.in/2012/03/full-calendar-saving-event-using-ajax.html

      Delete
  2. Good Example. Do u have any example for binding json object from MV3 controller method. If so please post the same.

    ReplyDelete
    Replies
    1. Sorry for late reply. You can simply call controller method from JavaScript. As an example you can check the post -
      http://forums.asp.net/p/1650403/4292279.aspx#4292279

      Delete
  3. I downloaded and run the code and it appears always that is "loading events....". Any ideia of what could be happining?

    ReplyDelete
    Replies
    1. If you directly run the code, it should work. There can be problem with the css and js file reference issue.

      Delete
  4. Thanks, Huge help. I downloaded the fullcalendar and jquery files from owners and made local ref. Worked perfectly

    ReplyDelete
  5. Hello Sir, I have a table In which I have defined Start date End Date and Start time/End Time as well.
    How can apply my start time and end time in
    events.Add(new Event()
    {
    EventID = 1,
    EventName = "EventName 1",
    StartDate = new DateTime(y, m, d).ToString(),
    EndDate = new DateTime(y, m+1, d).ToString()
    });

    Help Me!!!!!!!!!!

    ReplyDelete
  6. I see one issue... When pulling the data from a database, you must retrieve all records. That could eventually become a pretty large set of data. I would rather only pull events for the currently displayed time period, in my case, the current month. Your method pulls the data, then creates the calendar. A better way would be to let FullCalendar grab the data since it passes the start and end dates when calling the web service.

    ReplyDelete
  7. Thanks for your clear writing and working examples, it helped me to get up and running.

    ReplyDelete
  8. hi i am using full calender control how can i add events from wcf restful services

    ReplyDelete
    Replies
    1. You just need to replace jQuery ajax call with restful ajax call.

      Delete
  9. Hi Anup Das Gupta,
    i downloded this fullcalendar but how to execute this program

    ReplyDelete
  10. This can be executed like a web application. You need to use visual studio.

    ReplyDelete
  11. Cant get output ,still loading. i am using vs2010

    ReplyDelete
    Replies
    1. Still loading means ajax call is not successful. Can you check in the ajax error method for the detail.

      Delete
  12. Hi how would you separate the UI from the code when trying to implement this solution into a web api? How can you get a list of events from an API instead of the .asmx file?

    ReplyDelete
    Replies
    1. There should not be any difference. Web api is REST service. You can use it like a json data source.

      Delete
  13. Hi Anup Das Gupta,
    i downloded this fullcalendar ..its working fine but in firefox events won't diasplay ..but same code working in IE and Chrome.

    ReplyDelete
    Replies
    1. Can you please check in firebug and look at console for any error.

      Delete
  14. Superb article bro. Struggled for a week to solve my problem regarding this fullcalendar and yeah finally this helped me.. :) Thanks alot..

    ReplyDelete
  15. Cant get output ,still loading. i am using vs2010

    ReplyDelete
  16. U did n't give javascript file

    ReplyDelete
    Replies
    1. Source code is there as a download zip file at the end of the post.

      Delete
  17. Replies
    1. Ajax call is already there in the sample. Please go through the post one more time or download the source code(end of the post)

      Delete
  18. Hello Anup Das,

    I like to thank you for the post, This is real awesome man!! Clears all my doubt-- Shared with my colleagues too. Thumps Up

    ReplyDelete