Sample Project

The sample project includes:

Online Demo

Requirements

  • .NET Framework 4.0 or higher
  • Visual Studio 2017
  • Microsoft SQL Server 2014+ (Express) 

Features

This tutorial shows how to create an AJAX timetable in an ASP.NET web application. It supports custom time slots (blocks), drag&drop event moving and resizing, and custom event colors.

  • Weekly timetable view
  • Displays time slots (blocks) with custom size (block number is mapped to the hour component of the DateTime)
  • Inline editing of the block properties using active areas.
  • Custom event color in combination with CssOnly mode (CSS styling).
  • Loads events and blocks from SQL Server database.
  • Full calendar CSS styling (calendar_green theme).
  • Integrates DayPilot Navigator for switching the week.
  • C# and VB.NET source code included.
  • Sample database included.

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

Introduction

This tutorial doesn't cover DayPilot Calendar basics. For more information about  configuring the week view, loading events from a database or enabling the AJAX drag and drop operations (moving, resizing) please see the following tutorial:

1. Mapping Timetable Slots to Hours

Internally, the ASP.NET calendar control works with time slots of equal size. The maximum supported slot size is 60 minutes (CellDuration property).

In order to show a timetable with custom blocks, it is necessary to map the block to the hour part of the DateTime. This allows a maximum of 24 slots per day. It would be possible to map it to the minute part as well if needed (modify TimetableManager.cs/TimetableManager.vb class).

Day (February 1, 2013)

  • Block 1 => mapped as 2013-02-01T01:00:00
  • Block 2 => mapped as 2013-02-01T02:00:00
  • etc.

Day 2 (February 2, 2013)

  • Block 1 => mapped as 2013-02-02T01:00:00
  • Block 2 => mapped as 2013-02-02T02:00:00
  • etc.

We will limit the display to 7 time slots (using DayBeginsHour, DayEndsHour, HeightSpec properties), each taking one hour (CellDuration property). We will increase the default time cell size to 70 pixels (CellHeight property):

    <DayPilot:DayPilotCalendar
        ID="DayPilotCalendar1" 
        runat="server" 
        ...
        CellDuration="60"
        CellHeight="70"
        DayBeginsHour="1"
        DayEndsHour="8"
        HeightSpec="Full"
    />

timetable-asp.net-week-default.png

Now we will use BeforeTimeHeaderRender to customize the time headers (vertical axis). We will replace the default text with the block name (start and end) as defined in the database. The real block start and end times are defined in [Block] database table:

timetable-asp.net-sql-block-names.png

The block start and end times (BlockStart, BlockEnd) are stored as DateTime fields but only the time part is significant.

Our BeforeTimeHeaderRender handler looks like this:

C#

protected void DayPilotCalendar1_OnBeforeTimeHeaderRender(BeforeTimeHeaderRenderEventArgs ea)
{
    int id = ea.Start.Hours;
    DataRow r = FindBlock(id);
    ea.InnerHTML = String.Format("Block {0}<br/>{1}<br/>{2}", id, TimeFormatter.GetHourMinutes((DateTime)r["BlockStart"], DayPilotCalendar1.TimeFormat), TimeFormatter.GetHourMinutes((DateTime)r["BlockEnd"], DayPilotCalendar1.TimeFormat));
}

VB.NET

Protected Sub DayPilotCalendar1_OnBeforeTimeHeaderRender(ByVal ea As BeforeTimeHeaderRenderEventArgs)
	Dim id As Integer = ea.Start.Hours
	Dim r As DataRow = FindBlock(id)
	ea.InnerHTML = String.Format("Block {0}<br/>{1}<br/>{2}", id, TimeFormatter.GetHourMinutes(CDate(r("BlockStart")), DayPilotCalendar1.TimeFormat), TimeFormatter.GetHourMinutes(CDate(r("BlockEnd")), DayPilotCalendar1.TimeFormat))
End Sub

It will replace the default header text (e.g. "1 AM") with the block details:

timetable-asp.net-time-slot-names.png

2. Timetable Block Editing

We will make the block properties (start and end time) editable by adding an active area to each time header cell:

timetable-asp.net-active-area.png

The active area is added in BeforeTimeHeaderRender event handler:

C#

protected void DayPilotCalendar1_OnBeforeTimeHeaderRender(BeforeTimeHeaderRenderEventArgs ea)
{
	// ...

	ea.Areas.Add(new Area().Width(15).Top(0).Bottom(0).Right(0).CssClass("resource_action_menu").Html("<div><div></div></div>").JavaScript("editBlock(e);"));
}

VB.NET

Protected Sub DayPilotCalendar1_OnBeforeTimeHeaderRender(ByVal ea As BeforeTimeHeaderRenderEventArgs)
	Rem ...
	ea.Areas.Add((New Area()).Width(15).Top(0).Bottom(0).Right(0).CssClass("resource_action_menu").Html("<div><div></div></div>").JavaScript("editBlock(e);"))
End Sub

It specifies the area dimensions, CSS class and associated action. This active area will execute editBlock() JavaScript method when clicked. The editBlock() methods opens a dialog box with block details:

timetable-asp.net-block-edit.png

3. Custom Timetable Event Colors

The new event dialog (NewDialog.aspx) allows users to add events to the timetable and specify event properties, including description and color.

timetable-asp.net-new-event.png

Blocks are loaded from the database:

New.aspx.cs

C#

private void FillDropDownListStart()
{
	DataTable blocks = new DataManager().GetBlocks();

	foreach(DataRow r in blocks.Rows)
	{
		int id = Convert.ToInt32(r["BlockId"]);
		DateTime start = (DateTime) r["BlockStart"];
		DateTime end = (DateTime)r["BlockEnd"];
		string name = String.Format("Block {0} ({1} - {2})", id, TimeFormatter.GetHourMinutes(start, TimeFormat.Auto), TimeFormatter.GetHourMinutes(end, TimeFormat.Auto));
		ListItem item = new ListItem(name, id.ToString());
		DropDownListStart.Items.Add(item);
	}
}

VB.NET

Private Sub FillDropDownListStart()
	Dim blocks As DataTable = (New DataManager()).GetBlocks()

	For Each r As DataRow In blocks.Rows
		Dim id As Integer = Convert.ToInt32(r("BlockId"))
		Dim start As Date = CDate(r("BlockStart"))
		Dim [end] As Date = CDate(r("BlockEnd"))
		Dim name As String = String.Format("Block {0} ({1} - {2})", id, TimeFormatter.GetHourMinutes(start, TimeFormat.Auto), TimeFormatter.GetHourMinutes([end], TimeFormat.Auto))
		Dim item As New ListItem(name, id.ToString())
		DropDownListStart.Items.Add(item)
	Next r
End Sub

DataManager.cs

C#

public DataTable GetBlocks()
{
	var da = CreateDataAdapter("select * from [Block] order by [BlockId]");
	DataTable dt = new DataTable();
	da.Fill(dt);
	return dt;
}

VB.NET

Public Function GetBlocks() As DataTable
	Dim da = CreateDataAdapter("select * from [Block] order by [BlockId]")
	Dim dt As New DataTable()
	da.Fill(dt)
	Return dt
End Function

The event details are saved in [Assignment] table:

timetable-asp.net-sql-schema-assignment.png

The event color field (AssignmentColor) is used to store the event color. This field can't be mapped to the event color directly but we can do it in BeforeEventRender event handler:

C#

protected void DayPilotCalendar1_BeforeEventRender(object sender, DayPilot.Web.Ui.Events.Calendar.BeforeEventRenderEventArgs e)
{
	string color = (string) e.DataItem["AssignmentColor"];
	if (!String.IsNullOrEmpty(color))
	{
		e.BackgroundColor = color;
		e.BorderColor = color;
		e.FontColor = "#ffffff";
	}
}

VB.NET

Protected Sub DayPilotCalendar1_BeforeEventRender(ByVal sender As Object, ByVal e As DayPilot.Web.Ui.Events.Calendar.BeforeEventRenderEventArgs)
	Dim color As String = CStr(e.DataItem("AssignmentColor"))
	If Not String.IsNullOrEmpty(color) Then
		e.BackgroundColor = color
		e.BorderColor = color
		e.FontColor = "#ffffff"
	End If
End Sub