Microsoft & .NETASPCreating a Dropdown Calendar Control for ASP.NET

Creating a Dropdown Calendar Control for ASP.NET

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

Recently, while building some administrative Web pages for a framework, a dropdown calendar control was requested for a date field. Being a judicious developer and working on someone else’s dime, my first activity was to double check the Toolbox. ASP.NET doesn’t seem to include a dropdown calendar, so my next step was to search the Internet. The Web contains several well-written dropdown-style calendar controls. Unfortunately, those discovered all seemed to require a post back to the server to show the calendar control, and each opened a new page on top of the current page. While a second page approach is functional, that extra post back to the server and page seemed a bit too costly. Assuredly, the clever people at Microsoft are aware of this deficit, but an interim solution was needed. The objective was to create a dropdown-style calendar control right in one page, eliminating the extra page and post back to the Web server to open and close the calendar. In this article, you will see my solution.

Creating the CalendarControl UserControl

Our mutual goal is to create an aggregate control that looks and acts like a dropdown calendar control. In case you are new to .NET or haven’t explored the relationship between ASP.NET and code-behind, we will start with some fundamentals.

To begin, start Visual Studio .NET—I used VS.NET 2003 for the example but it should run on version 1.0. Create a new ASP.NET Web Application from the File|New Project menu item. After you select the ASP.NET Web Application template, VS.NET will create a bare bones Web project from the template files that ship with .NET. The template project will create an AssemblyInfo.vb file, a global.asax file, a Web.config file, and a blank ASP.NET Web Form named WebForm1.aspx.

The next step—where the real work begins—is to add a Web UserControl to the project from the Project|Add Web User Control menu item. In the Add New Item dialog, name the control CalendarControl and click Open.

Designing the UserControl

The UserControl is comprised of a TextBox, an HTML Input button, and an HTML <DIV> with a Calendar control from the Web Forms tab of the Toolbox. The visual result should look roughly like the figure (see Figure 1).

Figure 1: The design-time view of the Calendar control.

The next step is to add the HTML/ASP code that will dictate the position and behavior of the control at runtime.

Coding the HTML

The basic behavior of the control is that at runtime we only see the Button and the TextBox. When the button is clicked, the <DIV> display style is toggled, making the calendar control appear to expand or collapse—that is, appear to drop down or fold up, depending on its current state.

The button acts like a toggle switch: It changes the state of the DIV containing the calendar. If the calendar is retracted, pushing the button will show the calendar. If the calendar is expanded, clicking the button will retract the calendar. This behavior occurs on the client without a round trip to the server. Additionally, the position of the calendar control needs to appear as it hangs from the bottom of the TextBox. All of this behavior is managed with attribute values and client-side script as summarized:

  • Manage the <DIV> tag’s display style
  • Absolutely position the calendar control immediately below the TextBox and Button
  • Respond to the Button’s Click event on the client
  • Respond to a selection in the calendar

Listing 1 shows the HTML supporting all of these behaviors except the last one, which we will implement in the code-behind.

Listing 1: HTML supporting the calendar control.

<%@ Control Language="vb" AutoEventWireup="false"
    Codebehind="CalendarControl.ascx.vb"
    Inherits="Calendar.CalendarControl"
    TargetSchema="http://schemas.microsoft.com/intellisense/ie5" %>
<%asp:TextBox id="TextBox1" runat="server"><%/asp:TextBox>
  <%INPUT type="button" value="..." onclick="OnClick()"><%br>
<%div id="divCalendar" style="DISPLAY: none; POSITION: absolute">
  <%asp:Calendar id="Calendar1" runat="server" BorderWidth="2px"
                BackColor="White" Width="200px"
    ForeColor="Black" Height="180px" Font-Size="8pt"
                      Font-Names="Verdana" BorderColor="#999999"
    BorderStyle="Outset" DayNameFormat="FirstLetter" CellPadding="4">
    <%TodayDayStyle ForeColor="Black" BackColor="#CCCCCC">
      <%/TodayDayStyle>
    <%SelectorStyle BackColor="#CCCCCC"><%/SelectorStyle>
    <%NextPrevStyle VerticalAlign="Bottom"><%/NextPrevStyle>
    <%DayHeaderStyle Font-Size="7pt" Font-Bold="True"
                    BackColor="#CCCCCC"><%/DayHeaderStyle>
    <%SelectedDayStyle Font-Bold="True" ForeColor="White"
                      BackColor="#666666"><%/SelectedDayStyle>
    <%TitleStyle Font-Bold="True" BorderColor="Black"
                BackColor="#999999"><%/TitleStyle>
    <%WeekendDayStyle BackColor="#FFFFCC"><%/WeekendDayStyle>
    <%OtherMonthDayStyle ForeColor="#808080"><%/OtherMonthDayStyle>
  <%/asp:Calendar>
<%/div>
<%script>
function OnClick()
{
  if( divCalendar.style.display == "none")
    divCalendar.style.display = "";
  else
    divCalendar.style.display = "none";
}
<%/script>

The various parts of the implementation described in the summary block are shown in bold font. The HTML style=”DISPLAY: none; POSITION: absolute” indicates how and where the Calendar is displayed. DISPLAY: none means the <DIV> and its contents are effectively invisible. The style POSITION: absolute means that the calendar will show up precisely where it was placed, resulting in its appearing to be attached to the TextBox.

The <script> block contains a function named OnClick. This function is the OnClick event handler for the HTML button Input control (near the top of the listing). The OnClick event toggles the display style of the <DIV> control. A value of “none” means the <DIV> is invisible and a value of “” means that the <DIV> and the Calendar it contains are visible.

Implementing the Code-Behind

The code-behind is very straightforward. A SelectionChanged event was added for the Calendar control. When the date is selected, a postback does occur and the TextBox is updated to reflect the selected date.

In Listing 2, we go through some extra gyrations to find the client-side <DIV> control and change its display state to “none”, concealing it after the date is selected (see Listing 2).

Listing 2: The code-behind implementing the SelectionChanged event.

Private Sub Calendar1_SelectionChanged(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles Calendar1.SelectionChanged

  TextBox1.Text = Calendar1.SelectedDate.ToShortDateString()
  Dim div As System.Web.UI.Control = Page.FindControl("divCalendar")

  If TypeOf div Is HtmlGenericControl Then
    CType(div, HtmlGenericControl).Style.Add("display", "none")
  End If
End Sub

Testing the Finished Product

The finished product should look like Figure 2 at runtime. When the button—an HTML Input control is used so that it runs on the client instead of a click causing a postback—is clicked, the calendar is displayed, as shown in Figure 3.

Figure 2: Before the calendar is dropped down.

Figure 3: After the calendar is dropped down.

What to Do if You Need Multiple Calendars

Because the client-side code and the code-behind refers to a specifically named <DIV> control, we cannot add multiple copies of the CalendarControl to the same Web page. The reason is that the first <DIV> named divCalendar would always be found, no matter which button we clicked.

If you need multiple date fields, you can solve this predicament by creating a UserControl with all of the controls repeated and two precisely named <DIV> tags or you can write some more client-side script and code-behind to try to dynamically figure out which client-side button was clicked and which <DIV> is affected. For example, in our control event.srcElement.nextSibling.nextSibling.style.display will yield two siblings over from the Input control, which is the divCalendar. While not a robust solution—if the control changed, the code would break—it will yield the DIV adjacent to the Input button.

Alternatively, you have the option of using a Web Forms button and handling the click event on the server. This will provide you with precisely the DIV and calendar that should be toggled, although your application will be a bit less responsive because the button will post back to the server prior to setting the <DIV> tag’s display style.

Summary

Script is alive and well in ASP.NET. While as a practical matter using script is not as widely encouraged as it used to be, you can still use client-side scripts to create some snappy results.

In this article, you learned how to use ASP.NET and HTML controls and both script and code-behind to dynamically simulate a dropdown Calendar control and store a selected date value in an associated TextBox.

About the Author

Paul Kimmel is the VB Today columnist for codeguru.com and developer.com and has written several books on object-oriented programming, including the recently released Visual Basic .NET Power Coding from Addison-Wesley and the upcoming Excel VBA 2003: Programmer’s Reference from Wiley. He is the chief architect for Software Conceptions and is available to help design and build your next application.

The Lansing, Michigan area has a great opportunity to form a .NET Users Group. A well-run group offers great learning and networking opportunities and occasionally some free pizza and door prizes. Contact me at pkimmel@softconcepts.com if you live in mid-Michigan and are interested in participating.

# # #

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories