Click here to Skip to main content
15,867,568 members
Articles / Web Development / ASP.NET

Event Calendar for an ASP.NET MVC Application

Rate me:
Please Sign up or sign in to vote.
4.83/5 (49 votes)
5 Feb 2018GPL35 min read 312.8K   15.9K   127   72
The article explains how to integrate dhtmlxScheduler, an AJAX-based, interactive event calendar, in your ASP.NET MVC application.

Introduction

This tutorial explains the steps required to integrate a Google-like interactive event calendar in an ASP.NET MVC application. We will use dhtmlxScheduler, an Open-Source JavaScript calendar that provides an event scheduling interface with drag-and-drop capabilities and AJAX support. Events can be displayed in Day/Week/Month/Year views and edited by the end-user on the client side.

dhtmlxScheduler interface

Going through this article, you will learn how to put this AJAX-based event calendar on a web page, load events from .NET sever side, and update them in the database when the user makes changes in the browser.

Getting Started

First of all, we need to create a new ASP.NET MVC project. We'll call it, for example, "My Calendar". After that, create a database (or use any valid one) where you will save the calendar events. In the database, create the table "Events" with the following set of fields (all fields are mandatory):

Field Type Description
id identity, primary key event ID
text text event description
start_date datetime start date and time of event
end_date datetime end date and time of event

While the DB tool is open, you can add some test data to the "Events" table. In the attached sample package, you will find the MyCalendar.mdf file which already contains the necessary table and data.

Then we need to download the dhtmlxScheduler package - you can find the download link on the scheduler homepage. When the package is downloaded, unpack it and copy the contents from the folder 'codebase' to the folder 'Scripts' of your project. The result of this step should be similar to this:

Directory

Now everything is ready and all the necessary files are in place, so we can proceed to the next step.

Initialization

At the first set-out, we need to create a default view. Add a new controller "CalendarController" and create the "Index" view for it. Here is the content of the Index.aspx file:

XML
<%@ Page Language="C#" Inherits="System.Web.Mvc.ViewPage<dynamic>" %>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
      "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" >
<head  runat="server">
<title>Index</title>
<script src="http://www.codeproject.com/Scripts/dhtmlxscheduler.js" 
            type="text/javascript"></script>
<link href="http://www.codeproject.com/Scripts/dhtmlxscheduler.css" 
            rel="stylesheet" type="text/css" />
<style type="text/css">
html, body
{
height:100%;
padding:0px;
margin:0px;
}
</style>
<script type="text/javascript">
function init() {
scheduler.init("scheduler_here",new Date(2010,6,1),"month");
}
</script>
</head>
<body  önload="init()">
<div id="scheduler_here" class="dhx_cal_container" style='width:100%; height:100%;'>
<div class="dhx_cal_navline">
<div class="dhx_cal_prev_button"> </div>
<div class="dhx_cal_next_button"> </div>
<div class="dhx_cal_today_button"></div>
<div class="dhx_cal_date"></div>
<div class="dhx_cal_tab" name="day_tab" style="removed:204px;"></div>
<div class="dhx_cal_tab" name="week_tab" style="removed:140px;"></div>
<div class="dhx_cal_tab" name="month_tab" style="removed:76px;"></div>
</div>
<div class="dhx_cal_header">
</div>
<div class="dhx_cal_data">
</div>
</div>
</body>
</html>

The default view loads the .js and .css files of dhtmlxScheduler and inits a full-screen scheduler. The second and third parameters in the scheduler.init command define the default date and mode, which will be in the calendar just after initialization. Except for the first line, the code doesn't have anything .NET MVC specific. Actually, it's fully taken from the standard dhtmlxScheduler sample.

Now we need to do one more thing - update the default route. Switch the default route of the app to the newly created controller in Global.asax.cs:

C#
public static void RegisterRoutes(RouteCollection routes)
{
    routes.IgnoreRoute("{resource}.axd/{*pathInfo}");

    routes.MapRoute(
    "Default", // Route name
    "{controller}/{action}/{id}", // URL with parameters
    new { controller = "Calendar", action = "Index", 
          id = UrlParameter.Optional } // Parameter defaults
    );
}

When everything is done and correct, you can run the app and see the following screen:

Calendar preview

If you don't see such a view, most probably you haven't copied the scheduler's files to the folder 'Scripts' correctly, so check it again.

The calendar created with dhtmlxScheduler has a clean and user-friendly interface, and managing the events is quite easy. To create new events, use double click or click-and-drag commands. By clicking on the tabs in the right corner, you can switch views: Day, Week, Month.

Loading Data

The view we have constructed in the previous steps looks fine, but it doesn't contain any data so we need to change this. At first, add 'Model' to your application (just use "Model > Add > Add new item" and select "Data", "Link to SQL Classes"). To complete the process, drag-and-drop the "Events" table to the Model Designer, and then add one more action to CalendarController.cs:

C#
public ActionResult Data()
{
    MyEventsDataContext data = new MyEventsDataContext();
    return View(data.Events);
}

Define the view for that action - Data.aspx:

ASP.NET
<%@ Page Language="C#" 
   Inherits="System.Web.Mvc.ViewPage<dynamic>" ContentType="text/xml" %>
<data>
<% foreach (var myevent in Model) { %>
<event id="<%=myevent.id%>">
<start_date>
 <![CDATA[<%= String.Format("{0:MM/dd/yyyy HH:mm}",
                            myevent.start_date) %>]]>
</start_date>
<end_date><![CDATA[<%= String.Format("{0:MM/dd/yyyy HH:mm}",
                       myevent.end_date) %>]]></end_date>
<text><![CDATA[<%= myevent.text%>]]></text>
</event>
<% } %>
</data>

Note that this template outputs not HTML, but XML data. For each event, it will output a block of XML data. The extra bit of the code is used to provide the data in the necessary format. If you need to add extra fields to the model, just add the extra tags to the view.

Then we adjust the initialization code of our scheduler in Index.aspx:

JavaScript
<script type="text/javascript">
function init() {
    scheduler.config.xml_date = "m/d/Y H:m"; // format of dates in XML
    scheduler.init("scheduler_here", new Date(2010, 6, 1), "month");
    scheduler.load("/Calendar/Data");  //path to the newly created action
}
</script>

We have just configured the date format (the same as in Data.aspx) and have defined the path to the action 'Data'. At this step, the running application will look like this:

Scheduler with events

Well, we are in the middle. After the next step, the major part of the job will be done.

Saving to the Database

After all the manipulations described above, we've got the scheduler which loads the events data from the database, but that's not enough. The next goal is to save changes made on the client side to the server. First of all, create one more action - CalendarController.cs:

C#
public ActionResult Save(FormCollection actionValues)
{
    String action_type = actionValues["!nativeeditor_status"];
    Int64 source_id = Int64.Parse(actionValues["id"]);
    Int64 target_id = source_id;

    MyEventsDataContext data = new MyEventsDataContext();
    Event myevent;
    try{
        switch (action_type)
        {
            case "inserted":
                myevent = new Event();
                myevent.start_date = DateTime.Parse(actionValues["start_date"]);
                myevent.end_date = DateTime.Parse(actionValues["end_date"]);
                myevent.text = actionValues["text"];
                data.Events.InsertOnSubmit(myevent);
                break;
            case "deleted":
                myevent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                data.Events.DeleteOnSubmit(myevent);
            break;
            default: // "updated"
                myevent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                myevent.start_date = DateTime.Parse(actionValues["start_date"]);
                myevent.end_date = DateTime.Parse(actionValues["end_date"]);
                myevent.text = actionValues["text"];
                break;
        }
        data.SubmitChanges();
        target_id = myevent.id;
    }
    catch
    {
        action_type = "error";
    }

    return View(new CalendarActionResponseModel(action_type, source_id, target_id));
}

It seems that it's a lot of code but it's quite simple in its logic. In the first lines, we've got the type of the action from the incoming request. Then, according to the type, we insert, delete, or update the data in the database. And after the DB operation has completed, we render a response to the client-side scheduler.

The file Save.aspx will look like this:

ASP.NET
<%@ Page Language="C#" 
    Inherits="System.Web.Mvc.ViewPage<scheduler.ActionResponseModel>" 
    ContentType="text/xml"%>
<data>
<action type="<%= Model.Status %>" sid="<%= Model.Source_id %>" 
             tid="<%= Model.Target_id %>"></action>
</data>

The view shown above uses the class CalendarActionResponseModel to transfer the necessary information from the action to the View. In CalendarController.cs, we add:

C#
public class CalendarActionResponseModel
{
    public String Status;
    public Int64 Source_id;
    public Int64 Target_id;
    public CalendarActionResponseModel(String status, 
           Int64 source_id, Int64 target_id)
    {
        Status = status;
        Source_id = source_id;
        Target_id = target_id;
    }
}

Now we update Index.aspx one more time (add a code that will link updates on the client-side scheduler with the action 'Save'):

JavaScript
<script type="text/javascript">
function init() {
    scheduler.config.xml_date = "%m/%d/%Y %H:%i";
    scheduler.init("scheduler_here", new Date(2010, 6, 1), "month");
    scheduler.load("/Calendar/Data");

    var dp = new dataProcessor("/Calendar/Save");
    dp.init(scheduler);
    dp.setTransactionMode("POST", false);
}
</script>

So now, all the changes or new events will be saved to the DB. In addition, the calendar will correctly restore after page reloading. One final step left - improvements.

Improvements

The code we are using in 'SaveController' can be improved by using automatic bindings. In CalendarController.cs:

C#
public ActionResult Save(Event changedEvent, FormCollection actionValues)
{
    String action_type = actionValues["!nativeeditor_status"];
    Int64 source_id = Int64.Parse(actionValues["id"]);
    Int64 target_id = source_id;
    MyEventsDataContext data = new MyEventsDataContext();
    try{
        switch (action_type)
        {
            case "inserted":
                data.Events.InsertOnSubmit(changedEvent);
                break;
            case "deleted":
                changedEvent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                data.Events.DeleteOnSubmit(changedEvent);
                break;
            default: // "updated"
                changedEvent = data.Events.SingleOrDefault(ev => ev.id == source_id);
                UpdateModel(changedEvent);
                break;
        }
        data.SubmitChanges();
        target_id = changedEvent.id;
    }
    catch
    {
        action_type = "error";
    }
    return View(new CalendarActionResponseModel(action_type, source_id, target_id));
}

To give the calendar a more slick and glossy look, or to customize the coloring scheme, use the online SkinBuilder for dhtmlxScheduler. Select one of the "Glossy" skins to get a more modern look for the calendar. When you're done with the customization, download the skin package (CSS files and images) and unpack them in the folder 'Scripts' (it will overwrite some old scheduler files).

The running app after those updates will produce the final look:

Final look of the calendar

So we have implemented a web-based calendar that can be used in ASP.NET MVC and provides all the necessary functions: loading, saving, deleting, and updating calendar events.

If needed, you may define extra fields, add/move calendar views, and redefine scales and templates configuration (please refer to dhtmlxScheduler documentation). All those modifications can be achieved by adding extra JavaScript commands in the "Index" view. There is no need for any further updates in the "CalendarController.cs" code.

Note that the dhtmlxScheduler sources are distributed under GNU GPL v2. For the licensing details, visit the DHTMLX website.

License

This article, along with any associated source code and files, is licensed under The GNU General Public License (GPLv3)


Written By
Software Developer (Senior)
Russian Federation Russian Federation
Building web apps since 2001. Rich experience in HTML frontends for different platforms.

Comments and Discussions

 
QuestionAntonio Pin
Member 128351408-Oct-19 19:44
Member 128351408-Oct-19 19:44 
QuestionDHTMLX is not free Pin
ovisariesdk20-Feb-18 19:38
ovisariesdk20-Feb-18 19:38 
QuestionIs this Event Calendar is free Pin
Mou_kol5-Feb-18 21:25
Mou_kol5-Feb-18 21:25 
AnswerRe: Is this Event Calendar is free Pin
ovisariesdk20-Feb-18 18:56
ovisariesdk20-Feb-18 18:56 
QuestionIn visual 2013 Pin
Member 1240374620-Mar-16 8:14
Member 1240374620-Mar-16 8:14 
QuestionMy Vote of 5 Pin
Mohammad A. Amer13-Feb-16 23:17
professionalMohammad A. Amer13-Feb-16 23:17 
GeneralThanks a lot for such a detailed tutorial! Pin
Sergey Laptik16-Aug-15 23:00
Sergey Laptik16-Aug-15 23:00 
QuestionWould this work for my application? Pin
Member 996303511-Aug-15 2:55
Member 996303511-Aug-15 2:55 
QuestionError following The Steps Pin
Member 115230611-Apr-15 7:48
Member 115230611-Apr-15 7:48 
Questionhow to start week on sunday instead of monday Pin
Member 31330863-Mar-15 4:40
Member 31330863-Mar-15 4:40 
Questioncan't save event on scheduler when hosting IIS 7 Pin
n3eck4-Dec-14 17:12
n3eck4-Dec-14 17:12 
QuestionLanguage Pin
Member 1065595115-Jul-14 1:21
Member 1065595115-Jul-14 1:21 
QuestionEvent Mgmt required Pin
NandaKishore 235-Jun-14 21:32
NandaKishore 235-Jun-14 21:32 
QuestionWhat happens on saving an event? Pin
Member 100665211-Jan-14 19:45
Member 100665211-Jan-14 19:45 
QuestionNot able to create Events Pin
Robert Clove24-Aug-13 3:47
Robert Clove24-Aug-13 3:47 
GeneralPlease help help.....I need to resolve this urgent Pin
Jayakumar13-Aug-13 22:04
Jayakumar13-Aug-13 22:04 
GeneralRe: Please help help.....I need to resolve this urgent Pin
Member 824043114-Aug-13 3:15
Member 824043114-Aug-13 3:15 
GeneralSmall popup calendar for week selection Pin
Jayakumar13-Aug-13 19:37
Jayakumar13-Aug-13 19:37 
QuestionEvent Calendar for an ASP.NET MVC Razor view engine Pin
Mohammed Salah8-May-13 5:31
Mohammed Salah8-May-13 5:31 
QuestionHow do I test out the application? Pin
WENDARIEN10-Feb-13 23:55
WENDARIEN10-Feb-13 23:55 
GeneralThanks Pin
Member 805831215-Jan-13 23:45
Member 805831215-Jan-13 23:45 
Questionerror: Object doesn't support property or method 'load' Pin
martina loescher20-Oct-12 10:14
martina loescher20-Oct-12 10:14 
QuestionJQuery Pin
Brian Herbert15-May-12 0:27
Brian Herbert15-May-12 0:27 
QuestionError Pin
dana_131014-May-12 21:14
dana_131014-May-12 21:14 
QuestionDispaly Event Infromation on Mouse hover Pin
prashantvk15-Mar-12 0:10
prashantvk15-Mar-12 0:10 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.