Building Database Driven Event Calendar using Asp.Net C# VB.Net

Tracking events based on date is one of the most common requirements in our daily lives. Event calendar is one of the most popular solution where user can easily track his/her or agents or subordinates daily most important activities. Most of the free components probably can’t implement your demand. In asp.net you can use calendar control to fulfill custom demands. But i am trying to develop a calendar without using calendar control. To do this I choose DataList because here i can define column no & repeat direction which make me interested. I want to produce my output like below:

Related Article:
How to Create Runtime Dynamic Event Calendar using ASP.NET Calendar Control in C# VB.Net

ASP.Net Database Driven Event Calendar

At first add a DataList control in your page. Use a HeaderTemplate column to generate custom header where you will place year DropDownList and month navigation link. Add ItemTemplate to create day wise block within the calendar. The code looks like:

<asp:Content ID="BodyContent" runat="server" ContentPlaceHolderID="MainContent">
<asp:DataList ID="dlCalendar" runat="server" RepeatColumns="7" Width="600px" BorderStyle="None" RepeatDirection="Horizontal" OnItemDataBound="dlCalendar_ItemDataBound">

<HeaderTemplate>
<table width="100%" border="0" cellpadding="0" cellspacing="0" style="background-color:#00BFFF;height:20px"><tr><td width="33%"><asp:DropDownList runat="server" ID="cboPrev" AutoPostBack="true" Width="70px" OnSelectedIndexChanged="RfreshData"></asp:DropDownList>
<asp:Label runat="server" ID="lblLeft" ></asp:Label>
</td><td width="33%" align="center"><asp:Label runat="server" ID="lblMiddle" >
</asp:Label></td><td width="33%" align="right">
<asp:Label runat="server" ID="lblRight" ></asp:Label>
<asp:DropDownList runat="server" ID="cboNext" Width="70px" AutoPostBack="true" OnSelectedIndexChanged="RfreshData"></asp:DropDownList></td></tr>
</table>
</HeaderTemplate>

<ItemTemplate><table border="0" style="background-color:Silver;height:100px" width="130px" cellpadding="0" cellspacing="0" ><tr><td align="left" valign="top"">
<asp:Label ID="Label1" runat="server" Text='<%# DataBinder.Eval(Container.DataItem, "Data") %>' Width="100%"></asp:Label>
</td></tr></table>
</ItemTemplate>

</asp:DataList>
</asp:Content>

For simplicity here I use DataTable. But you can easily replace the DataTable by populating data from database. So at first i need to populate event data then combined this data with date block of the calendar. To do that I need to write the below code under Page Load Event:

C# Code to Build an Event Calendar:

    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
            DateTime dDate;
            if (Request["SpecificMonth"] != null)
                dDate = Convert.ToDateTime(Request["SpecificMonth"]);
            else
                dDate = DateTime.Now;

            // Here you need to made the datastructure in such a way that you can bind the data in your datalist easily.
            // So give concentration on database query to produce data like below:
            // You can display each event, description if you can make the data row appropriately.

            DataTable dtEvents = new DataTable("DailyEvents");
            dtEvents.Columns.Add(new DataColumn("EventDate", System.Type.GetType("System.DateTime")));
            dtEvents.Columns.Add(new DataColumn("EventType"));
            dtEvents.Columns.Add(new DataColumn("EventDescription"));
            dtEvents.Columns.Add(new DataColumn("Done"));
            dtEvents.Columns.Add(new DataColumn("Note"));

            dtEvents.Rows.Add(DateTime.Now, "Meeting", "BSSOM", "Attended?", "Agenda: 1)Indexing problem in ABC server. 2) Fix time to go Live. 3) Who will be responsible to maintain it?");

            dtEvents.Rows.Add(DateTime.Now.AddDays(5), "Travel", " <a href='about.aspx'>Coxsbazar</a>", "Visited?", "Agenda: 1) Go to barmiz market 2) Buy few cloths for my wife 3) Eat rupchanda fish");

            dtEvents.Rows.Add(DateTime.Now, "Assignment", "Audit", "R&D Done?", "");
            dtEvents.Rows.Add(DateTime.Now, "Rport", "Fin. report", "Ready?", "");
            dtEvents.Rows.Add(DateTime.Now.AddDays(5), "Birthday", " <a href='about.aspx?dDate=" + DateTime.Now.AddDays(5).ToString("dd/MM/yyyy") + "'>Shumon</a>", "Send gift?", "");

            DataTable datatable = new DataTable();
            datatable.Columns.Add("Day"); //day contains day of the month
            datatable.Columns.Add("Data"); //run time produce html & just place on it.
            DataRow oRow;

            for (int i = 1; i <= DateTime.DaysInMonth(dDate.Year, dDate.Month); i++)
            {

                DateTime dCalendarDay = new DateTime(dDate.Year, dDate.Month, i);
                oRow = datatable.NewRow(); // here i am preparing data for a specific day. 
                // bworkingday method return: does the day is off or not. 
                // You can apply you business logic in this function to reurn data. 
                // by getEvents method i collect this day events from my all data. 
                // you can add control & event handler in runtime for more interactive calendar.

                if (!bWorkingDay(dCalendarDay))
                    oRow["Data"] = i.ToString() + "<br/><div style='color:Olive'>" + dCalendarDay.ToString("ddd") + " " + getEvents(dCalendarDay, dtEvents);
                else
                    oRow["Data"] = i.ToString() + "<br/><div style='color:Red'>" + dCalendarDay.ToString("ddd") + " " + getEvents(dCalendarDay, dtEvents);
                datatable.Rows.Add(oRow);

            }

            dlCalendar.DataSource = datatable;
            dlCalendar.DataBind();

            // here just i am making current date block. 
            if (dDate.Year == DateTime.Now.Year && dDate.Month == DateTime.Now.Month)
            {
                foreach (DataListItem oItem in dlCalendar.Items)
                {
                    if (oItem.ItemIndex == DateTime.Now.Day - 1)
                    {
                        oItem.BorderStyle = BorderStyle.Solid;
                        oItem.BorderColor = System.Drawing.Color.DeepSkyBlue; oItem.BorderWidth = 2;
                    }// if closed 
                }// for closed
            }// if closed

        }// !IsPostBack
    }// Page_Load

Note: Don’t forget to add “System.Data” namespace.

VB.Net Code to Build an Event Calendar:

    Protected Sub Page_Load(sender As Object, e As System.EventArgs) Handles Me.Load
        If Not IsPostBack Then
            Dim dDate As DateTime
            If Request("SpecificMonth") IsNot Nothing Then
                dDate = Convert.ToDateTime(Request("SpecificMonth"))
            Else
                dDate = DateTime.Now
            End If

            ' Here you need to made the datastructure in such a way that you can bind the data in your datalist easily.
            ' So give concentration on database query to produce data like below:
            ' You can display each event, description if you can make the data row appropriately.

            Dim dtEvents As New DataTable("DailyEvents")
            dtEvents.Columns.Add(New DataColumn("EventDate", System.Type.[GetType]("System.DateTime")))
            dtEvents.Columns.Add(New DataColumn("EventType"))
            dtEvents.Columns.Add(New DataColumn("EventDescription"))
            dtEvents.Columns.Add(New DataColumn("Done"))
            dtEvents.Columns.Add(New DataColumn("Note"))

            dtEvents.Rows.Add(DateTime.Now, "Meeting", "BSSOM", "Attended?", "Agenda: 1)Indexing problem in ABC server. 2) Fix time to go Live. 3) Who will be responsible to maintain it?")

            dtEvents.Rows.Add(DateTime.Now.AddDays(5), "Travel", " <a href='about.aspx'>Coxsbazar</a>", "Visited?", "Agenda: 1) Go to barmiz market 2) Buy few cloths for my wife 3) Eat rupchanda fish")

            dtEvents.Rows.Add(DateTime.Now, "Assignment", "Audit", "R&D Done?", "")
            dtEvents.Rows.Add(DateTime.Now, "Rport", "Fin. report", "Ready?", "")
            dtEvents.Rows.Add(DateTime.Now.AddDays(5), "Birthday", " <a href='about.aspx?dDate=" & DateTime.Now.AddDays(5).ToString("dd/MM/yyyy") & "'>Shumon</a>", "Send gift?", "")

            Dim datatable As New DataTable()
            datatable.Columns.Add("Day")
            'day contains day of the month
            datatable.Columns.Add("Data")
            'run time produce html & just place on it.
            Dim oRow As DataRow

            For i As Integer = 1 To DateTime.DaysInMonth(dDate.Year, dDate.Month)

                Dim dCalendarDay As New DateTime(dDate.Year, dDate.Month, i)
                oRow = datatable.NewRow()
                ' here i am preparing data for a specific day. 
                ' bworkingday method return: does the day is off or not. 
                ' You can apply you business logic in this function to reurn data. 
                ' by getEvents method i collect this day events from my all data. 
                ' you can add control & event handler in runtime for more interactive calendar.
                If Not bWorkingDay(dCalendarDay) Then
                    oRow("Data") = i.ToString() & "<br/><div style='color:Olive'>" & dCalendarDay.ToString("ddd") & " " & getEvents(dCalendarDay, dtEvents)
                Else
                    oRow("Data") = i.ToString() & "<br/><div style='color:Red'>" & dCalendarDay.ToString("ddd") & " " & getEvents(dCalendarDay, dtEvents)
                End If

                datatable.Rows.Add(oRow)
            Next

            dlCalendar.DataSource = datatable
            dlCalendar.DataBind()

            ' here just i am making current date block. 
            If dDate.Year = DateTime.Now.Year AndAlso dDate.Month = DateTime.Now.Month Then
                For Each oItem As DataListItem In dlCalendar.Items
                    If oItem.ItemIndex = DateTime.Now.Day - 1 Then
                        oItem.BorderStyle = BorderStyle.Solid
                        oItem.BorderColor = System.Drawing.Color.DeepSkyBlue
                        oItem.BorderWidth = 2
                        ' if closed 
                    End If
                    ' for closed
                Next
                ' if closed
            End If
        End If
        ' !IsPostBack

    End Sub

Note: Don’t forget to add “System.Data” namespace.

In the above code block I have used few helper functions like:
C# Code:

    public string getEvents(DateTime dDate, DataTable dTable)
    {
        string str = "<br/>";
        foreach (DataRow oItem in dTable.Rows)
        {
            if (Convert.ToDateTime(oItem["EventDate"].ToString()).ToString("dd MMM, yyyy") == dDate.ToString("dd MMM, yyyy"))
            {
                str = str + " " + oItem["EventType"] + ":" + oItem["EventDescription"] + " ";
            }
        }
        return str;
    }

    public bool bWorkingDay(DateTime bDate)
    {
        // here i am assuming the sunday as holiday but you can make it more efficiently
        // by using a databse if you want to generate country based calendar.
        // In different country they have different holidays schedule.
        if (bDate.ToString("ddd") == "Sun")
            return true;
        return false;
    }

VB.Net Code:

    Public Function getEvents(dDate As DateTime, dTable As DataTable) As String
        Dim str As String = "<br/>"
        For Each oItem As DataRow In dTable.Rows
            If Convert.ToDateTime(oItem("EventDate").ToString()).ToString("dd MMM, yyyy") = dDate.ToString("dd MMM, yyyy") Then
                str = ((str & " ") + oItem("EventType") & ":") + oItem("EventDescription") & " "
            End If
        Next
        Return str
    End Function

    Public Function bWorkingDay(bDate As DateTime) As Boolean
        ' here i am assuming the sunday as holiday but you can make it more efficiently
        ' by using a databse if you want to generate country based calendar.
        ' In different country they have different holidays schedule.
        If bDate.ToString("ddd") = "Sun" Then
            Return True
        End If
        Return False
    End Function

Now add the dlCalendar_ItemDataBound handler to populate header row of the DataList:
C# Code:

    protected void dlCalendar_ItemDataBound(object sender, DataListItemEventArgs e)
    {
        // Just populationg my header section
        DateTime dDate;
        if (Request["SpecificMonth"] != null)
        dDate = Convert.ToDateTime(Request["SpecificMonth"]);
        else
        dDate = DateTime.Now;
        if (e.Item.ItemType == ListItemType.Header)
        {
        DropDownList oPrev = (DropDownList)e.Item.FindControl("cboPrev");
        DropDownList oNext = (DropDownList)e.Item.FindControl("cboNext");
        DataTable dtYear = new DataTable();
        dtYear.Columns.Add("year4");
        dtYear.Columns.Add("sValue");
        //here i am assuming that when user click on 2009 he wants to see january 2009 calendar.
        //it will be more interective if you generate the current month(shown in the page) calendar.
        dtYear.Rows.Add("2014", "01 Jan, 2014");
        dtYear.Rows.Add("2015", "01 Jan, 2015");
        oPrev.DataTextField = "year4";
        oPrev.DataValueField = "sValue";
        oPrev.DataSource = dtYear;
        oPrev.DataBind();
        oNext.DataTextField = "year4";
        oNext.DataValueField = "sValue";
        oNext.DataSource = dtYear;
        oNext.DataBind();

        ((Label)e.Item.FindControl("lblLeft")).Text = "<a style=color:Black href=default.aspx?SpecificMonth=" + dDate.AddMonths(-1).ToString("dd-MMMM-yyyy") + ">" + dDate.AddMonths(-1).ToString("MMMM yyyy") + "</a>";
        ((Label)e.Item.FindControl("lblMiddle")).Text = dDate.ToString("MMMM yyyy");
        ((Label)e.Item.FindControl("lblRight")).Text = "<a style=color:Black href=default.aspx?SpecificMonth=" + dDate.AddMonths(+1).ToString("dd-MMMM-yyyy") + ">" + dDate.AddMonths(+1).ToString("MMMM yyyy") + "</a>";

        }
    }

VB.Net Code:

    Protected Sub dlCalendar_ItemDataBound(sender As Object, e As DataListItemEventArgs)
        ' Just populationg my header section
        Dim dDate As DateTime
        If Request("SpecificMonth") IsNot Nothing Then
            dDate = Convert.ToDateTime(Request("SpecificMonth"))
        Else
            dDate = DateTime.Now
        End If
        If e.Item.ItemType = ListItemType.Header Then
            Dim oPrev As DropDownList = DirectCast(e.Item.FindControl("cboPrev"), DropDownList)
            Dim oNext As DropDownList = DirectCast(e.Item.FindControl("cboNext"), DropDownList)
            Dim dtYear As New DataTable()
            dtYear.Columns.Add("year4")
            dtYear.Columns.Add("sValue")
            'here i am assuming that when user click on 2009 he wants to see january 2009 calendar.
            'it will be more interective if you generate the current month(shown in the page) calendar.
            dtYear.Rows.Add("2014", "01 Jan, 2014")
            dtYear.Rows.Add("2015", "01 Jan, 2015")
            oPrev.DataTextField = "year4"
            oPrev.DataValueField = "sValue"
            oPrev.DataSource = dtYear
            oPrev.DataBind()
            oNext.DataTextField = "year4"
            oNext.DataValueField = "sValue"
            oNext.DataSource = dtYear
            oNext.DataBind()

            DirectCast(e.Item.FindControl("lblLeft"), Label).Text = "<a style=color:Black href=default.aspx?SpecificMonth=" & dDate.AddMonths(-1).ToString("dd-MMMM-yyyy") & ">" & dDate.AddMonths(-1).ToString("MMMM yyyy") & "</a>"
            DirectCast(e.Item.FindControl("lblMiddle"), Label).Text = dDate.ToString("MMMM yyyy")

            DirectCast(e.Item.FindControl("lblRight"), Label).Text = "<a style=color:Black href=default.aspx?SpecificMonth=" & dDate.AddMonths(+1).ToString("dd-MMMM-yyyy") & ">" & dDate.AddMonths(+1).ToString("MMMM yyyy") & "</a>"
        End If
    End Sub

Now almost completed our calendar except corner side Year DropDownList. To raise the selectedeventchange event, must set AutoPostBack property to true. When user select a year then we just redirect him by a querystring and then we generate the calendar based on user selection by reading the query string. Code like:

C# Code:

    protected void RfreshData(object sender, System.EventArgs e)
    {
        //redirect by date thats why page can render the calendar according to user selection
        Response.Redirect("default.aspx?SpecificMonth=" + ((DropDownList)sender).SelectedValue);
    }

VB.Net Code:

    Protected Sub RfreshData(sender As Object, e As System.EventArgs)
        'redirect by date thats why page can render the calendar according to user selection
        Response.Redirect("default.aspx?SpecificMonth=" + DirectCast(sender, DropDownList).SelectedValue)
    End Sub

Conclusion:
This approach requires more coding and I am recommending don’t go with this until extreme need to customize an event calendar. You can reduce your half of effort by using built in calendar control.

Download Code Example C#        Download Code Example VB.Net

Posted in .Net, Asp.net, C#, DataList, VB.Net
4 comments on “Building Database Driven Event Calendar using Asp.Net C# VB.Net
  1. Dan B says:

    Great Code – works very well. This would be great for a personal calendar, but I can’t use it as a business solution as it’s too confusing not having Sunday locked in as the first column. (For readers — In this solution, whatever day the first of the month falls on is the first column in the calendar. So for one month, if the 1st falls on a Tuesday, the first column would be Tuesday… for the next month if the first falls on a Friday, the first column would be Friday, etc.) I had to tweak the C# dropdown list code for years as they were a little buggy.. I made the year selection dynamic also (see below). int year = DateTime.Now.Year; DateTime firstDay = new DateTime(year, 1, 1); dtYear.Rows.Add(“Select Year”, “0”); dtYear.Rows.Add(year-1, new DateTime(year -1, 1, 1)); dtYear.Rows.Add(year, new DateTime(year, 1, 1)); dtYear.Rows.Add(year+1, new DateTime(year+1, 1, 1)); dtYear.Rows.Add(year+2, new DateTime(year+2, 1, 1)); dtYear.Rows.Add(year + 3, new DateTime(year+3, 1, 1)); protected void RfreshData(object sender, System.EventArgs e) { if (((DropDownList)sender).SelectedValue != “0”) {//redirect by date thats why page can render the calendar according to user selection Response.Redirect(“default.aspx?SpecificMonth=” + ((DropDownList)sender).SelectedValue); } }

  2. Shawpnendu Bikash says:

    Thanks for your contribution–though i have not tested yet. Thanks again.

  3. Dan B says:

    Is there anyway to print this with one month per page? I have my data in a DB, so I’m open to suggestions.

  4. Celeste S says:

    Has anyone modified this so Monday appears in the same position – note Dan B’s comment.

Leave a Reply

Your email address will not be published. Required fields are marked *

     

*