Features

This is a beginner tutorial that shows how to setup an ASP.NET MVC project that uses the event calendar control from DayPilot Pro for ASP.NET MVC package.

  • ASP.NET MVC 5
  • Weekly event calendar
  • Drag and drop event creating
  • Drag and drop event moving
  • Drag and drop event resizing
  • Event deleting
  • Loading events from SQL Server database using LINQ to SQL

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. Buy a license.

New ASP.NET MVC Project

1. Create a new Web Project using File -> New -> Project.. in Visual Studio 2013. Choose "ASP.NET Web Application".

asp.net-mvc-5-event-calendar-new-web-application.png

2. Select "MVC" project template.

asp.net-mvc-5-event-calendar-mvc-project.png

3. Add a reference to DayPilot.Mvc.dll from DayPilot Pro for ASP.NET MVC package (Binary/Mvc5 folder).

asp.net-mvc-5-event-calendar-add-reference.png

4. Browse for DayPilot.Mvc.dll and press "Add".

asp.net-mvc-5-event-calendar-reference-browse.png

5. Copy daypilot-all.min.js from the DayPilot package (Scripts folder) to Scripts/DayPilot folder of your MVC project.

asp.net-mvc-5-event-calendar-javascript-library.png

Basic Setup

asp.net-mvc-5-event-calendar-simple.png

Include the DayPilot JavaScript library in the MVC view (Views/Home/Index.cshtml):

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

Create the event calendar control using @Html.DayPilotCalendar helper.

C#

@Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
    BackendUrl = Url.Action("Backend", "Calendar")
})

VB

@Html.DayPilotCalendar("dp", New DayPilotCalendarConfig With
{
    .BackendUrl = Url.Action("Backend", "Calendar")
})

The BackendUrl property points to the controller action that will be processing the AJAX requests.

Create the controller and action method and create a new DayPilotCalendar class instance that will handle the requests for you:

C#

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

  class Dpc : DayPilotCalendar
  {
      protected override void OnInit(InitArgs e)
      {
          UpdateWithMessage("Welcome!", CallBackUpdateType.Full);
      }
  }
}

VB

Public Class CalendarController
  Inherits Controller

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

  Private Class Dpc
    Inherits DayPilotCalendar

    Protected Overrides Sub OnInit(ByVal e As InitArgs)
      UpdateWithMessage("Welcome!", CallBackUpdateType.Full)
    End Sub

  End Class
End Class

The OnInit() method is called when the event calendar control is initialized on the client side. This sample OnInit() method displays a welcome message.

Weekly Calendar

asp.net-mvc-5-event-calendar-week.png

By default the event calendar shows a day view. We can switch to a week view using ViewType property:

C#

@Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
  BackendUrl = Url.Action("Backend", "Calendar"),
  ViewType = ViewType.Week
})

VB

@Html.DayPilotCalendar("dp", New DayPilotCalendarConfig With
{
  .BackendUrl = Url.Action("Backend", "Calendar"),
  .ViewType = ViewType.Week
})

Database Schema

asp.net-mvc-5-event-calendar-database-schema.png

We will use a simple database with just one table called [Event]. It has the following schema:

CREATE TABLE [dbo].[Event]
(
  [Id] INT NOT NULL PRIMARY KEY IDENTITY, 
  [Start] DATETIME NOT NULL, 
  [End] DATETIME NOT NULL, 
  [Text] NVARCHAR(200) NULL
)

LINQ to SQL

asp.net-mvc-5-event-calendar-linq-to-sql.png

Create a new LINQ to SQL file (Calendar.dbml) and drag the [Event] table there from the Server Explorer.

Loading Calendar Event Data

We will load the data in OnFinish() method which is called at the end of every callback.

We will only load the events if the calendar update is requested using Update() or UpdateWithMessage() methods. We can detect it by checking the UpdateType status.

C#

class Dpc : DayPilotCalendar
{
  CalendarDataContext dc = new CalendarDataContext();

  protected override void OnInit(InitArgs e)
  {
      UpdateWithMessage("Welcome!", CallBackUpdateType.Full);
  }

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

      DataIdField = "Id";
      DataStartField = "Start";
      DataEndField = "End";
      DataTextField = "Text";

      Events = from e in dc.Events where !((e.End <= VisibleStart) || (e.Start >= VisibleEnd)) select e;
  }
}

VB

Public Class CalendarController
  Inherits Controller

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

  Private Class Dpc
    Inherits DayPilotCalendar

    Private dc As New CalendarDataContext()

    Protected Overrides Sub OnInit(ByVal e As InitArgs)
      UpdateWithMessage("Welcome!", CallBackUpdateType.Full)
    End Sub

    Protected Overrides Sub OnFinish()
      If UpdateType = CallBackUpdateType.None Then
        Return
      End If

      DataIdField = "Id"
      DataStartField = "Start"
      DataEndField = "End"
      DataTextField = "Text"

      Events = From e In dc.Events Where Not ((e.End <= VisibleStart) Or (e.Start >= VisibleEnd)) _
               Select e
    End Sub
  End Class
End Class

We load the events using LINQ and map the Event object fields to the event calendar using Data*Field properties.

Creating Calendar Events

asp.net-mvc-5-event-calendar-event-creating-drag-drop.png

You can enable drag and drop event creating support using TimeRangeSelectedHandling property in the config. We will set the value to JavaScript. This means the JavaScript code specified using TimeRangeSelectedJavaScript property will be fired.

C#

@Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
    BackendUrl = Url.Action("Backend", "Calendar"),
    ViewType = ViewType.Week,
    TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.JavaScript,
    TimeRangeSelectedJavaScript = "create(start, end)"
})

VB

@Html.DayPilotCalendar("dp", New DayPilotCalendarConfig With
{
    .BackendUrl = Url.Action("Backend", "Calendar"),
    .ViewType = ViewType.Week,
    .TimeRangeSelectedHandling = TimeRangeSelectedHandlingType.JavaScript,
    .TimeRangeSelectedJavaScript = "create(start, end)"
})

asp.net-mvc-5-event-calendar-create-modal.png

The create() JavaScript function will open Event/Create view in a modal dialog.

<script type="text/javascript">

    function create(start, end) {
        var m = new DayPilot.Modal();
        m.closed = function () {
            if (this.result == "OK") {
                dp.commandCallBack('refresh');
            }
            dp.clearSelection();
        };
        m.showUrl('@Url.Action("Create", "Event")?start=' + start + '&end=' + end);
    }

</script>

The modal dialog will request a refresh of the event calendar using .commandCallBack() call when it is closed. This will fire OnCommand method on the server side:

C#

protected override void OnCommand(CommandArgs e)
{
  switch (e.Command)
  {
      case "refresh":
          Update();
          break;
  }
}

VB

Protected Overrides Sub OnCommand(ByVal e As CommandArgs)
  Select Case e.Command
    Case "refresh"
      Update()
  End Select
End Sub

Drag and Drop Event Moving

asp.net-mvc-5-event-calendar-drag-drop-moving.png

Enable drag and drop event moving using EventMoveHandling property of the config:

C#

@Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
    BackendUrl = Url.Action("Backend", "Calendar"),
    // ...
    EventMoveHandling = EventMoveHandlingType.Notify
})

VB

@Html.DayPilotCalendar("dp", New DayPilotCalendarConfig With
{
    .BackendUrl = Url.Action("Backend", "Calendar"),
    ' ...
    .EventMoveHandling = EventMoveHandlingType.Notify
})

The default value is "Disabled". You can set it either to Notify or CallBack. 

  • The Notify mode will update the calendar immediately as soon as the user drops the event at the new location and the server is notified afterwards (OnEventMove method).
  • The CallBack mode will fire the the server-side OnEventMove first. You need to refresh the event set on the server side using Update().

We will use the faster Notify model in this tutorial.

The server-side event handler (OnEventMove method) updates the database.

C#

protected override void OnEventMove(EventMoveArgs e)
{
  var item = (from ev in dc.Events where ev.Id == Convert.ToInt32(e.Id) select ev).First();
  if (item != null)
  {
      item.Start = e.NewStart;
      item.End = e.NewEnd;
      dc.SubmitChanges();                    
  }
}

VB

Protected Overrides Sub OnEventMove(ByVal e As EventMoveArgs)
  Dim item = ( _
      From ev In dc.Events _
      Where ev.Id = Convert.ToInt32(e.Id) _
      Select ev).First()
  If item IsNot Nothing Then
    item.Start = e.NewStart
    item.End = e.NewEnd
    dc.SubmitChanges()
  End If
End Sub

Event Deleting

asp.net-mvc-5-event-calendar-delete.png

The event calendar control includes built-in support for event deleting. You can enable it using EventDeleteHandling property:

C#

@Html.DayPilotCalendar("dp", new DayPilotCalendarConfig
{
    BackendUrl = Url.Action("Backend", "Calendar"),
    // ...
    EventDeleteHandling = EventDeleteHandlingType.CallBack
})

VB

@Html.DayPilotCalendar("dp", New DayPilotCalendarConfig With
{
    .BackendUrl = Url.Action("Backend", "Calendar"),
    ' ...
    .EventDeleteHandling = EventDeleteHandlingType.CallBack
})

This time we will use the "Notify" update model. It means we have to call Update() in the server-side OnEventDelete event handler.

C#

protected override void OnEventDelete(EventDeleteArgs e)
{
  var item = (from ev in dc.Events where ev.Id == Convert.ToInt32(e.Id) select ev).First();
  dc.Events.DeleteOnSubmit(item);
  dc.SubmitChanges();
  Update();
}

VB

Protected Overrides Sub OnEventDelete(ByVal e As EventDeleteArgs)
  Dim item = ( _
      From ev In dc.Events _
      Where ev.Id = Convert.ToInt32(e.Id) _
      Select ev).First()
  dc.Events.DeleteOnSubmit(item)
  dc.SubmitChanges()
  Update()
End Sub