This tutorial shows how to use the DayPilot Pro MVC Event Calendar with MVC 4 and Razor engine. It will load calendar events from a database (SQL Server), and allow event creating using TimeRangeSelected event and event moving using drag&drop.

Note: See also the ASP.NET MVC 5 version of this tutorial: ASP.NET MVC 5 Event Calendar Tutorial (C#, VB, LINQ to SQL)

Features

  • ASP.NET MVC calendar (day view)

  • Sample SQL Server Database

  • C# Source Code

  • VB.NET Source Code

  • Visual Studio

Requirements

License

Licensed for testing and evaluation purposes. You can use the source code of the tutorial if you are a licensed user of DayPilot Pro for ASP.NET MVC.

Installation

DLL

  • Put DayPilot.Mvc.dll in the bin directory of the web application.

  • Add it to project references if you are using a compiled web project.

Scripts

Include the following script in the web page (the script can be found in Scripts/DayPilot directory):

  • daypilot-all.min.js

All the scripts are included in the site template (Views/Shared/_Layout.cshtml or Views/Shared/_Layout.vbhtml):

<head>
    <!-- ... -->
    <script src="@Url.Content("~/Scripts/DayPilot/daypilot-all.min.js")" type="text/javascript"></script>
</head>

CSS Themes

Include the Themes directory from the DayPilot demo project.

Include Themes/calendar_white.css stylesheet in the web page:

<head>
    <!-- ... -->
    <link href="@Url.Content("~/Themes/calendar_white.css")" rel="stylesheet" type="text/css" />
</head>

View

Add the Calendar control to the view (Views/Home/Index.cshtml or Index.vbhtml):

C#

@using DayPilot.Web.Mvc;
@using DayPilot.Web.Mvc.Events.Calendar;
@using DayPilot.Web.Mvc.Enums.Calendar;

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig{})

VB.NET

@imports DayPilot.Web.Mvc
@imports DayPilot.Web.Mvc.Events.Calendar
@imports DayPilot.Web.Mvc.Enums.Calendar

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig)

This will add an empty Calendar with default settings.

In order to show calendar data, we need to specify the backend url:

C#

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

VB.NET

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

Apply the CSS Theme

Apply the "calendar_white" CSS theme by setting CssOnly = true and CssClassPrefix="calendar_white".

C#

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
    BackendUrl = Url.Content("~/Calendar/Backend"),
    CssOnly = true,
    CssClassPrefix = "calendar_white"
})

VB.NET

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig With
{
    .BackendUrl = Url.Content("~/Calendar/Backend"),
    .CssOnly = true,
    .CssClassPrefix = "calendar_white"
})

Backend Controller

Create a new CalendarController class that will handle the backend requests. Add a Backend method:

C#

public class CalendarController : Controller
{
  public ActionResult Backend()
  {
    return null;
  }
}

VB.NET

Public Class CalendarController
  Inherits System.Web.Mvc.Controller

  Function Backend() As ActionResult
    Return Nothing
  End Function

End Class

Create a  new Dpc class that will inherit from DayPilot.Web.Mvc.DayPilotCalendar:

C#

public class Dpc : DayPilotCalendar
{
}

VB.NET

Public Class Dpc
    Inherits DayPilotCalendar

End Class

Modify the Backend action of the Calendar controller to pass control to a new instance of the Dpc class:

C#

public class CalendarController : Controller
{
  public ActionResult Backend()
  {
    return new Dpc().CallBack(this);
  }
}

VB.NET

Public Class CalendarController
  Inherits System.Web.Mvc.Controller

  Function Backend() As ActionResult
    Return New Dpc().CallBack(Me)
  End Function

End Class

Now override OnInit() method of the DayPilotCalendar class in the Dpc class in order to handle the Init event:

C#

public class Dpc : DayPilotCalendar
{
  protected override void OnInit(InitArgs initArgs)
  {
    Events = new EventManager().FilteredData(VisibleStart, VisibleEnd).AsEnumerable();

    DataStartField = "eventstart";
    DataEndField = "eventend";
    DataTextField = "name";
    DataIdField = "id";
                
    UpdateWithMessage("Welcome!");
  }
}

VB.NET

Public Class Dpc
  Inherits DayPilotCalendar

  Protected Overrides Sub OnInit(ByVal e As DayPilot.Web.Mvc.Events.Calendar.InitArgs)
    Dim em = New EventManager()
    Events = em.FilteredData(VisibleStart, VisibleEnd).AsEnumerable

    DataStartField = "eventstart"
    DataEndField = "eventend"
    DataTextField = "name"
    DataIdField = "id"

    UpdateWithMessage("Welcome!")
  End Sub
End Class

This OnInit() method does three things:

  1. It loads the event set to Events property.

  2. It maps the event set fields (id, start, end, text) to DayPilot fields.

  3. It tells the Calendar to refresh the events and show a welcome message on the client side.

EventManager is a helper class that loads data from a database:

C#

public class EventManager
{
  public DataTable FilteredData(DateTime start, DateTime end)
  {
    SqlDataAdapter da = new SqlDataAdapter("SELECT * FROM [event] WHERE NOT (([eventend] <= @start) OR ([eventstart] >= @end))", ConfigurationManager.ConnectionStrings["daypilot"].ConnectionString);
    da.SelectCommand.Parameters.AddWithValue("start", start);
    da.SelectCommand.Parameters.AddWithValue("end", end);

    DataTable dt = new DataTable();
    da.Fill(dt);

    return dt;
  }
}

VB.NET

Public Class EventManager
  Public Function FilteredData(ByVal start As DateTime, ByVal end_ As DateTime) As 

    Dim da As SqlDataAdapter = New SqlDataAdapter("SELECT * FROM [event] WHERE NOT (([eventend] <= @start) OR ([eventstart] >= @end))", ConfigurationManager.ConnectionStrings("daypilot").ConnectionString)
    da.SelectCommand.Parameters.AddWithValue("start", start)
    da.SelectCommand.Parameters.AddWithValue("end", end_)

    Dim dt = New DataTable
    da.Fill(dt)
    Return dt

  End Function
End Class

Adding a New Event

In order to handle time range selection event (selecting time cells using a mouse drag), add TimeRangeSelectedHandling property to the view:

C#

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

VB.NET

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig With
{
  .BackendUrl = Url.Content("~/Calendar/Backend"),
  .TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.CallBack
})

And override OnTimeRangeSelected method in the Dpc class:

C#

protected override void OnTimeRangeSelected(TimeRangeSelectedArgs e)
{
  new EventManager().EventCreate(e.Start, e.End, "New event");

  Events = new EventManager().FilteredData(StartDate, StartDate.AddDays(Days)).AsEnumerable();

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

  UpdateWithMessage("A new event was created");
}

VB.NET

Protected Overrides Sub OnTimeRangeSelected(ByVal e As TimeRangeSelectedArgs)
  Dim em = New EventManager()
  em.EventCreate(e.Start, e.End, "New event")

  Events = em.FilteredData(StartDate, StartDate.AddDays(Days)).AsEnumerable

  DataStartField = "eventstart"
  DataEndField = "eventend"
  DataTextField = "name"
  DataIdField = "id"

  UpdateWithMessage("A new event was created")
End Sub

The OnTimeRangeSelected() method does three things:

  1. It creates a new record in the database.

  2. It loads the event set to Events property.

  3. It maps the event set fields (id, start, end, text) to DayPilot fields.

  4. It tells the Calendar to refresh the events and show a welcome message on the client side.

You can see that the steps 2-4 are the same as in OnInit(). We can move the events reloading to an OnFinish() method which is called during every CallBack after the main event handler.

C#

protected override void OnInit(InitArgs initArgs)
{
  Events = new EventManager().FilteredData(StartDate, StartDate.AddDays(Days)).AsEnumerable();
  UpdateWithMessage("Welcome!");
}

protected override void OnTimeRangeSelected(TimeRangeSelectedArgs e)
{
  new EventManager().EventCreate(e.Start, e.End, "New event");
  UpdateWithMessage("A new event was created");
}

protected override void OnFinish()
{
  // update was not requested in the event handler using Update() or UpdateWithMessage()
  // skip event reloading
  if (UpdateType == CallBackUpdateType.None)
  {
    return;
  }

  Events = new EventManager().FilteredData(StartDate, StartDate.AddDays(Days)).AsEnumerable();

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

VB.NET

Protected Overrides Sub OnInit(ByVal e As DayPilot.Web.Mvc.Events.Calendar.InitArgs)
  UpdateWithMessage("Welcome!")
End Sub

Protected Overrides Sub OnTimeRangeSelected(ByVal e As TimeRangeSelectedArgs)
  Dim em = New EventManager()
  em.EventCreate(e.Start, e.End, "New event")
  UpdateWithMessage("A new event was created")
End Sub

Protected Overrides Sub OnFinish()
  REM update was not requested in the event handler using Update() or UpdateWithMessage()
  REM skip event reloading
  If (UpdateType = Enums.CallBackUpdateType.None) Then
    Return
  End If

  Dim em = New EventManager()
  Events = em.FilteredData(StartDate, StartDate.AddDays(Days)).AsEnumerable

  DataStartField = "eventstart"
  DataEndField = "eventend"
  DataTextField = "name"
  DataIdField = "id"
End Sub

Event Moving

Similar steps have to be applied in order to enable event moving using drag&drop.

Add EventMoveHandling property to the view:

C#

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig
{
  BackendUrl = Url.Content("~/Calendar/Backend"),
  EventMoveHandling = EventMoveHandlingType.CallBack,
  TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.CallBack    
})

VB.NET

@Html.DayPilotCalendar("dpc", new DayPilotCalendarConfig With
{
  .BackendUrl = Url.Content("~/Calendar/Backend"),
  .EventMoveHandling = EventMoveHandlingType.CallBack,
  .TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.CallBack
})

Override OnEventMove() method in the Dpc class:

C#

protected override void OnEventMove(EventMoveArgs e)
{
  new EventManager().EventMove(e.Id, e.NewStart, e.NewEnd);
  UpdateWithMessage("The event was moved");
}

VB.NET

Protected Overrides Sub OnEventMove(ByVal e As DayPilot.Web.Mvc.Events.Calendar.EventMoveArgs)
  Dim em = New EventManager()
  em.EventMove(e.Id, e.NewStart, e.NewEnd)
  UpdateWithMessage("The event was moved")
End Sub

See Also