Monthly Calendar Tutorial: SQL Server, UpdatePanel, ModalPopupExtender (ASP.NET, C#, VB.NET)

November 2, 2010

tutorial-month-sql.png

Download

Includes C# and VB.NET source code of the tutorial and DayPilot Pro 6.1 Trial DLL.

Database Schema

This tutorial uses a very simple table with just four columns:

CREATE TABLE [dbo].[event](
  [id] [int] IDENTITY(1,1) NOT NULL,
  [name] [varchar](50),
  [eventstart] [datetime] NOT NULL,
  [eventend] [datetime] NOT NULL,
  CONSTRAINT [PK_event] PRIMARY KEY
)

Basic Setup

month-calendar-default-look.png

DayPilotMonth Control

 <DayPilot:DayPilotMonth ID="DayPilotMonth1" runat="server" 
DataEndField="eventend"
DataStartField="eventstart" 
DataTextField="name" 
DataValueField="id" 
DataTagFields="name, id"
DataSourceID="SqlDataSourceEvents"
... />

SqlDataSource Declaration

<asp:SqlDataSource ID="SqlDataSourceEvents" runat="server" ConnectionString="<%$ ConnectionStrings:daypilot %>"
SelectCommand="SELECT [id], [name], [eventstart], [eventend], [allday] FROM [event] WHERE NOT (([eventend] <= @start) OR ([eventstart] >= @end + 1))">
<SelectParameters>
<asp:ControlParameter Name="start" ControlID="DayPilotMonth1" PropertyName="VisibleStart" />
<asp:ControlParameter Name="end" ControlID="DayPilotMonth1" PropertyName="VisibleEnd" />
</SelectParameters>
</asp:SqlDataSource>

CSS Styling

 month-calendar-css-styling.png

To enable the silver theme, define the CssClassPrefix:

CssClassPrefix="month_silver_"

Add the styles to demo.css:

/* Month silver theme */
.month_silver_header 
{
    background-image: url(Media/month_silver_top20.gif);
    background-repeat: repeat-x;
    background-color: #CFCFCF;
}
.month_silver_event 
{
    background-image: url(Media/month_silver_event20.gif);
    background-repeat: repeat-x;
    background-color: #CFCFCF;
}

Copy the required images to Media directory:

  • month_silver_top20.gif
  • month_silver_event20.gif

Month Navigation

We are using DayPilot MonthPicker control for navigation.

month-picker-highlighted.png

The setup is simple:

<DayPilot:MonthPicker ID="MonthPicker1" runat="server" />
<asp:Button ID="Button1" runat="server" Text="Show" OnClick="Button1_Click" />

The Button1_Click event handler changes the StartDate of DayPilotMonth1 control:

C#

    protected void Button1_Click(object sender, EventArgs e)
    {
        DayPilotMonth1.StartDate = MonthPicker1.StartDate;
        DayPilotMonth1.DataBind();
        UpdatePanelCalendar.Update();
    }

VB.NET

    Protected Sub Button1_Click(ByVal sender As Object, ByVal e As EventArgs) Handles Button1.Click
        DayPilotMonth1.StartDate = MonthPicker1.StartDate
        DayPilotMonth1.DataBind()
        UpdatePanelCalendar.Update()
    End Sub

Basic Event Handling

The DayPilot Month control is placed inside an UpdatePanel control (UpdatePanelCalendar). That means all PostBack events will be handled using partial AJAX refresh.

The TimeRangeSelected event and EventClick event are handled using PostBack:

EventClickHandling="PostBack"
TimeRangeSelectedHandling="PostBack" 

Using an UpdatePanel usually makes things easier (you can modify other controls in your UpdatePanel, such as Labels, DropDownLists). However, it will be a bit slower because the UpdatePanel gets fully redrawn.

You can handle selected events using much faster CallBacks:

EventMoveHandling="CallBack" 
EventResizeHandling="CallBack" 

During CallBacks, you can directly update only the DayPilotMonth control itself (other controls can be updated using JavaScript). You will be rewarded with much faster responses (only the necessary parts of DayPilot Month will be reloaded).

Don't forget to call DayPilotMonth.Update() in CallBack event handlers.

C#

    protected void DayPilotMonth1_EventMove(object sender, EventMoveEventArgs e)
    {
        using (SqlConnection con = new SqlConnection(ConfigurationManager.ConnectionStrings["daypilot"].ConnectionString))
        {
            con.Open();
            SqlCommand cmd = new SqlCommand("UPDATE [event] SET [eventstart] = @start, [eventend] = @end WHERE [id] = @id", con);
            cmd.Parameters.AddWithValue("id", e.Value);
            cmd.Parameters.AddWithValue("start", e.NewStart);
            cmd.Parameters.AddWithValue("end", e.NewEnd);
            cmd.ExecuteNonQuery();
        }
        DayPilotMonth1.DataBind();
        DayPilotMonth1.Update();
    }

VB.NET

    Protected Sub DayPilotMonth1_EventMove(ByVal sender As Object, ByVal e As DayPilot.Web.UI.Events.EventMoveEventArgs) Handles DayPilotMonth1.EventMove
        Dim con As SqlConnection = New SqlConnection(ConfigurationManager.ConnectionStrings("daypilot").ConnectionString)
        con.Open()
        Dim cmd As SqlCommand = New SqlCommand("UPDATE [event] SET [eventstart] = @start, [eventend] = @end WHERE [id] = @id", con)
        cmd.Parameters.AddWithValue("id", e.Value)
        cmd.Parameters.AddWithValue("start", e.NewStart)
        cmd.Parameters.AddWithValue("end", e.NewEnd)
        cmd.ExecuteNonQuery()
        con.Close()
        DayPilotMonth1.DataBind()
        DayPilotMonth1.Update()
    End Sub

Event Editing

Both TimeRangeSelected and EventClick events will open a modal dialog with event details.

edit-dialog.png

C#

    protected void DayPilotMonth1_EventClick(object sender, EventClickEventArgs e)
    {
        EventDetail.ChangeMode(DetailsViewMode.Edit);
        SqlDataSourceDetail.SelectParameters["id"].DefaultValue = e.Value;
        EventDetail.DataBind();
        UpdatePanelDetail.Update();
        ModalPopup.Show();
    }

VB.NET

    Protected Sub DayPilotMonth1_EventClick(ByVal sender As Object, ByVal e As DayPilot.Web.UI.Events.EventClickEventArgs) Handles DayPilotMonth1.EventClick
        EventDetail.ChangeMode(DetailsViewMode.Edit)
        SqlDataSourceDetail.SelectParameters("id").DefaultValue = e.Value
        EventDetail.DataBind()
        UpdatePanelDetail.Update()
        ModalPopup.Show()
    End Sub

The modal popup is created using a combination of several controls:

  • ModalPopupExtender
  • Panel (pnlPopup)
    • UpdatePanel (UpdatePanelDetail)
      • DetailsView (EventDetail)

The .aspx code:

    <ajaxToolkit:ModalPopupExtender ID="ModalPopup" runat="server" TargetControlID="ButtonDummy"
        PopupControlID="pnlPopup" BackgroundCssClass="modalBackground" />
    <asp:Panel ID="pnlPopup" runat="server" Style="display: none" CssClass="modalPopup"
        Width="500px">
        <asp:UpdatePanel ID="UpdatePanelDetail" runat="server" UpdateMode="Conditional">
            <Triggers>
                <asp:AsyncPostBackTrigger ControlID="DayPilotMonth1" EventName="EventMenuClick" />
            </Triggers>
            <ContentTemplate>
                <asp:DetailsView ID="EventDetail" runat="server" DefaultMode="Edit" OnItemUpdated="EventDetail_ItemUpdated"
                    DataSourceID="SqlDataSourceDetail" DataKeyNames="id" AutoGenerateEditButton="True" OnItemCommand="EventDetail_ItemCommand"
                    Width="500px" OnItemUpdating="EventDetail_ItemUpdating" AutoGenerateInsertButton="True" AutoGenerateRows="False" OnItemInserted="EventDetail_ItemInserted"
                    CssClass="detail" GridLines="None">
                    <HeaderStyle HorizontalAlign="Right" />
                    <Fields>
                        <asp:BoundField DataField="name" HeaderText="Name" SortExpression="name" />
                        <asp:BoundField DataField="eventstart" HeaderText="Start" SortExpression="eventstart" />
                        <asp:BoundField DataField="eventend" HeaderText="End" SortExpression="eventend" />
                    </Fields>
                </asp:DetailsView>
                <asp:SqlDataSource ID="SqlDataSourceDetail" runat="server" ConnectionString="<%$ ConnectionStrings:daypilot %>"
                    SelectCommand="SELECT [id], [name], [eventstart], [eventend] FROM [event] WHERE ([id] = @id)"
                    UpdateCommand="UPDATE [event] SET [name] = @name, [eventstart] = @eventstart, [eventend] = @eventend WHERE [id] = @id"
                    InsertCommand="INSERT INTO [event] ([name], [eventstart], [eventend]) values (@name, @eventstart, @eventend)"
                    >
                    <SelectParameters>
                        <asp:Parameter Name="id" Type="Int32" />
                    </SelectParameters>
                </asp:SqlDataSource>
            </ContentTemplate>
        </asp:UpdatePanel>
    </asp:Panel>

DayPilot for JavaScript, ASP.NET WebForms, ASP.NET MVC, Java