Click here to Skip to main content
Click here to Skip to main content

AJAX Event Calendar (Scheduler) for ASP.NET MVC in 80 Lines of Code

By , 24 Apr 2013
 

AJAX Event Calendar for ASP.NET MVC 3

This sample project shows how to build an AJAX Event Calendar (Scheduler) using the open-source DayPilot Lite  for ASP.NET MVC library (Apache Software License 2.0). We will build our sample with ASP.NET MVC 3, Visual Studio 2010, and SQL Server Express 2005.  

Online Demos:     

The monthly event calendar view is supported since DayPilot Lite for MVC 1.3 release. 

We will need only 80 lines for code for the full drag&drop functionality (event creating, moving and resizing).     

Three steps are necessary:    

  • Library: Include DayPilot.Web.Mvc.dll and scripts in  your project and add a reference to it.
  • View: Create a new MVC 3 Razor view and add DayPilot  Calendar widget using Html.DayPilotCalendar extension.  
  • Controller: Create a MVC 3 controller that will supply  the data.

1. DayPilot.Web.Mvc Library 

Download DayPilot Lite for  ASP.NET MVC open-source package.

Copy DayPilot JavaScript files from the Scripts folder of the package to your project (Scripts/DayPilot):

  • calendar.js
  • common.js 

Copy DayPilot.Web.Mvc.dll from the Binary folder of the package to your project (Bin).

Add a reference to DayPilot.Web.Mvc.dll:

Add reference to DayPilot.Web.Mvc.dll

2. MVC 3 View (8 Lines of Code)

Create a new MVC 3 view (Views/Home/Index.cshtml):

@{ ViewBag.Title = "MVC 3 Razor Event Calendar"; }
<h2>MVC 3 Razor Event Calendar</h2>

Add DayPilot JavaScript libraries:

<script src="@Url.Content("~/Scripts/DayPilot/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/DayPilot/calendar.js")" type="text/javascript"></script>

Add the event calendar initialization code:

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
  BackendUrl = Url.Content("~/Home/Backend"),
})

Note that the minimum required code is quite short. It only has to point to  the backend MVC controller ("~/Home/Backend") that will supply the calendar  event data using an AJAX call.

Don't forget to add DayPilot.Web.Mvc namespace to  /Views/Web.config so it recognizes the Html.DayPilotCalendar helper:

<configuration>
  <system.web.webPages.razor>
    <pages pageBaseType="System.Web.Mvc.WebViewPage">
      <namespaces>
        ...
        <add namespace="DayPilot.Web.Mvc"/>
      </namespaces>
    </pages>
  </system.web.webPages.razor>
</configuration>

This is the complete code of our new MVC view with the event  calendar:

@{ ViewBag.Title = "MVC 3 Razor Event Calendar"; }

<h2>MVC 3 Razor Event Calendar</h2>

<script src="@Url.Content("~/Scripts/DayPilot/common.js")" type="text/javascript"></script>
<script src="@Url.Content("~/Scripts/DayPilot/calendar.js")" type="text/javascript"></script>

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
  BackendUrl = Url.Content("~/Home/Backend"),
})

3. MVC 3 Controller (34 Lines of Code)

Create a new MVC 3 controller (Controllers/HomeController.cs):

public class HomeController : Controller
{
  public ActionResult Index()
  {
    return View();
  }
}

Add a new action handler for the calendar backend. It will be accessible as  /Home/Backend.

public ActionResult Backend()
{
  return new Dpc().CallBack(this);
}

This action will pass control to a new instance of a custom Dpc class that  derives from DayPilotCalendar:

class Dpc : DayPilotCalendar
{
  protected override void OnInit(InitArgs e)
  {
    var db = new DataClasses1DataContext();
    Events = from ev in db.events select ev;

    DataIdField = "id";
    DataTextField = "text";
    DataStartField = "eventstart";
    DataEndField = "eventend";

    Update();
  }
} 

We have loaded the calendar event data from a simple MS SQL table called  "events" using a LINQ to SQL classes generated using Visual Studio 2010 wizard  (DataClasses1.dbml).

LINQ to SQL

The "events" table has a very simple structure:

Events table structure

The table fields (id, text, eventstart, eventend) are mapped to the required  DayPilotCalendar fields using Data*Field properties:

DataIdField = "id";
DataTextField = "text";
DataStartField = "eventstart";
DataEndField = "eventend";

Calling Update() will send the calendar event data to the client and update  the display:

ASP.NET Event Calendar for ASP.NET MVC Day View

And here is the complete code of the MVC controller that  supplies the calendar event data to the client using AJAX:

using System;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using DayPilot.Web.Mvc;
using DayPilot.Web.Mvc.Events.Calendar;

namespace DayPilotCalendarMvc3.Controllers
{
  public class HomeController : Controller
  {
    public ActionResult Index()
    {
      return View();
    }

    public ActionResult Backend()
    {
      return new Dpc().CallBack(this);
    }

    class Dpc : DayPilotCalendar
    {
      protected override void OnInit(InitArgs e)
      {
        var db = new DataClasses1DataContext();
        Events = from ev in db.events select ev;

        DataIdField = "id";
        DataTextField = "text";
        DataStartField = "eventstart";
        DataEndField = "eventend";

        Update();
      }
    }
  }
}

4. Adding AJAX Drag&Drop Functionality (38 Lines of Code)

AJAX Event Calendar for ASP.NET MVC Drag&Drop

In order to enable the drag&drop functionality (event creating, moving, and  resizing) we need to add the following lines to the view (4 new lines):

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
  BackendUrl = Url.Content("~/Home/Backend"),
  EventMoveHandling = DayPilot.Web.Mvc.Events.Calendar.EventMoveHandlingType.CallBack,
  EventResizeHandling = DayPilot.Web.Mvc.Events.Calendar.EventResizeHandlingType.CallBack,
  TimeRangeSelectedHandling = DayPilot.Web.Mvc.Events.Calendar.TimeRangeSelectedHandlingType.JavaScript,
  TimeRangeSelectedJavaScript = "dpc.timeRangeSelectedCallBack(start, end, null, { name: prompt('New Event Name:', 'New Event') });"
})

The controller must be extended as well. It will handle the events (EventMove,  EventResize, and TimeRangeSelected) and update the database (34 new lines):

using System;
using System.Linq;
using System.Web.Mvc;
using DayPilot.Web.Mvc;
using DayPilot.Web.Mvc.Enums;
using DayPilot.Web.Mvc.Events.Calendar;

namespace DayPilotCalendarMvc3.Controllers
{
    public class HomeController : Controller
    {
        public ActionResult Index()
        {
            return View();
        }

        public ActionResult Backend()
        {
            return new Dpc().CallBack(this);
        }

        class Dpc : DayPilotCalendar
        {
            DataClasses1DataContext db = new DataClasses1DataContext();

            protected override void OnInit(InitArgs e)
            {
                Update(CallBackUpdateType.Full);
            }

            protected override void OnEventResize(EventResizeArgs e)
            {
                var toBeResized = (from ev in db.Events where ev.id == Convert.ToInt32(e.Id) select ev).First();
                toBeResized.eventstart = e.NewStart;
                toBeResized.eventend = e.NewEnd;
                db.SubmitChanges();
                Update();
            }

            protected override void OnEventMove(EventMoveArgs e)
            {
                var toBeResized = (from ev in db.Events where ev.id == Convert.ToInt32(e.Id) select ev).First();
                toBeResized.eventstart = e.NewStart;
                toBeResized.eventend = e.NewEnd;
                db.SubmitChanges();
                Update();
            }

            protected override void OnTimeRangeSelected(TimeRangeSelectedArgs e)
            {
                var toBeCreated = new Event {eventstart = e.Start, eventend = e.End, text = (string) e.Data["name"]};
                db.Events.InsertOnSubmit(toBeCreated);
                db.SubmitChanges();
                Update();
            }

            protected override void OnFinish()
            {
                if (UpdateType == CallBackUpdateType.None)
                {
                    return;
                }

                Events = from ev in db.Events select ev;

                DataIdField = "id";
                DataTextField = "text";
                DataStartField = "eventstart";
                DataEndField = "eventend";
            }
        }
    }
}

5. Bonus: Week View (+1 Line)

AJAX Event Calendar for ASP.NET MVC Week View

Switching to week view is a simple as adding a single line of code to the  view:

ViewType = DayPilot.Web.Mvc.Enums.Calendar.ViewType.Week,

It goes here:

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
  BackendUrl = Url.Content("~/Home/Backend"),
  ViewType = DayPilot.Web.Mvc.Enums.Calendar.ViewType.Week,
  EventMoveHandling = DayPilot.Web.Mvc.Events.Calendar.EventMoveHandlingType.CallBack,
  EventResizeHandling = DayPilot.Web.Mvc.Events.Calendar.EventResizeHandlingType.CallBack,
  TimeRangeSelectedHandling = DayPilot.Web.Mvc.Events.Calendar.TimeRangeSelectedHandlingType.JavaScript,
  TimeRangeSelectedJavaScript = "dpc.timeRangeSelectedCallBack(start, end, null, { name: prompt('New Event Name:', 'New Event') });"
})

Other supported ViewType modes are WorkWeek and Days (custom number of days, set using Days property).  

Month View 

Monthly AJAX Event Calendar for ASP.NET MVC 

See also the Monthly Event Calendar tutorial:  

See Also  

History    

License

This article, along with any associated source code and files, is licensed under The Apache License, Version 2.0

About the Author

Dan Letecky
Czech Republic Czech Republic
Member
My open-source AJAX controls:
 
DayPilot
DayPilot MVC
DayPilot Java
Outlook-Like Calendar/Scheduling Controls

Sign Up to vote   Poor Excellent
Add a reason or comment to your vote: x
Votes of 3 or less require a comment

Comments and Discussions

 
Hint: For improved responsiveness ensure Javascript is enabled and choose 'Normal' from the Layout dropdown and hit 'Update'.
You must Sign In to use this message board.
Search this forum  
    Spacing  Noise  Layout  Per page   
QuestionNicememberLiuxf30 Apr '13 - 3:38 
AnswerRe: NicememberDan Letecky30 Apr '13 - 3:40 
GeneralMy vote of 5professionalEdo Tzumer25 Apr '13 - 1:26 
GeneralRe: My vote of 5memberDan Letecky25 Apr '13 - 2:25 
GeneralMy vote of 5memberHumayun Kabir Mamun25 Apr '13 - 0:44 
GeneralRe: My vote of 5memberDan Letecky25 Apr '13 - 2:25 
GeneralMy vote of 5memberPrasad Khandekar24 Apr '13 - 5:05 
GeneralRe: My vote of 5memberDan Letecky24 Apr '13 - 5:43 
GeneralMy vote of 5memberigambin20 Mar '13 - 2:02 
GeneralRe: My vote of 5memberDan Letecky20 Mar '13 - 2:10 
GeneralMy vote of 5memberMaa_7720 Mar '13 - 0:04 
GeneralRe: My vote of 5memberDan Letecky20 Mar '13 - 0:37 
GeneralMy vote of 5memberShubham Choudhary19 Mar '13 - 20:36 
GeneralRe: My vote of 5memberDan Letecky20 Mar '13 - 0:37 
GeneralMy vote of 5memberRenju Vinod19 Mar '13 - 20:22 
GeneralRe: My vote of 5memberDan Letecky20 Mar '13 - 0:37 
GeneralMy vote of 5memberAbinash Bishoyi19 Mar '13 - 6:34 
GeneralRe: My vote of 5memberDan Letecky19 Mar '13 - 7:36 
QuestionGreat !!memberMohamedKamalPharm11 Dec '12 - 23:32 
AnswerRe: Great !!memberDan Letecky20 Mar '13 - 0:36 
GeneralRe: Great !!memberMohamedKamalPharm20 Mar '13 - 7:40 
Questionan awesome articlememberMd. YaSiR aRaFaT21 Nov '12 - 20:51 
AnswerRe: an awesome articlememberDan Letecky22 Nov '12 - 20:42 
GeneralMy vote of 5memberMd. YaSiR aRaFaT21 Nov '12 - 20:50 
GeneralRe: My vote of 5memberDan Letecky22 Nov '12 - 20:41 
GeneralMy vote of 5memberfahad1221 Nov '12 - 18:34 
GeneralRe: My vote of 5memberDan Letecky22 Nov '12 - 20:41 
GeneralMy vote of 5memberMonjurul Habib16 Oct '12 - 10:30 
GeneralRe: My vote of 5memberDan Letecky17 Oct '12 - 1:09 
Questionsome enhancement [modified]membermelvintcs3 Oct '12 - 20:18 
AnswerRe: some enhancementmemberDan Letecky15 Oct '12 - 8:08 
GeneralGood work!memberPavel Vladov4 Sep '12 - 22:07 
GeneralRe: Good work!memberDan Letecky15 Oct '12 - 8:06 
GeneralMy vote of 5memberPritesh Aryan3 Aug '12 - 4:10 
GeneralRe: My vote of 5memberDan Letecky5 Aug '12 - 6:13 
GeneralMy vote of 5memberUnque11 Jul '12 - 3:17 
GeneralRe: My vote of 5memberDan Letecky11 Jul '12 - 3:54 
QuestionSeconds featurememberStewie0079 Jul '12 - 23:09 
AnswerRe: Seconds featurememberDan Letecky11 Jul '12 - 3:53 
GeneralRe: Seconds featurememberStewie00711 Jul '12 - 4:05 
GeneralRe: Seconds featurememberDan Letecky11 Jul '12 - 4:18 
GeneralMy vote of 5memberSpliffa9 Jul '12 - 5:56 
GeneralRe: My vote of 5memberDan Letecky9 Jul '12 - 11:06 
GeneralMy vote of 5memberJigneshSE23 Jun '12 - 15:46 
GeneralRe: My vote of 5memberDan Letecky25 Jun '12 - 4:14 

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

Permalink | Advertise | Privacy | Mobile
Web03 | 2.6.130516.1 | Last Updated 24 Apr 2013
Article Copyright 2012 by Dan Letecky
Everything else Copyright © CodeProject, 1999-2013
Terms of Use
Layout: fixed | fluid