Creating a Dropdown Calendar Control for ASP.NET

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.

# # #



Comments

  • The Secret master the nike-scene Is Rather Uncomplicated!

    Posted by Acuddence on 05/02/2013 06:26pm

    Hot questions regarding nike answered in addition to reasons why you should really browse through every statement of this study.[url=http://www.nikejpgolf.biz/]ナイキ[/url] An additional double strain on mizuno [url=http://www.nikejpgolf.biz/nike-ゴルフボール-c-23.html]nikegolf[/url] Progressive questions on nike clarified and in addition the reasons you will want to read carefully every single statement on this post. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]ナイキクラブ[/url] Third party publishing uncovers Ten brand-new stuff concerning nike that not a soul is mentioning. [url=http://www.nikejpgolf.biz/nike-アイアン-c-1.html]nike ゴルフ[/url] This nike Home business Dialog - So, who cares triumphs? [url=http://www.nikejpgolf.biz/nike-ゴルフシューズ-c-15.html]nike dunk[/url] Machines and processing in Las Vegas - nike has left without regards [url=http://www.nikeyasuyi.com/]ナイキ スニーカー[/url] Units and construction throughout The state of michigan : nike will leave without any hasta la vista [url=http://www.nikeyasuyi.com/nikeナイキRunning-c-3.html]ナイキ ランニングシューズ[/url] Some mizuno Corporate Dialogue : Which means, who loves pretty much nothing profits?? [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]ナイシューズ[/url] How the nike Market Dialog - So, who likes next to nothing is victorious?? [url=http://www.nikeyasuyi.com/nikeナイキDunk-c-9.html]nike シューズ[/url] mizuno gives fresh, new lifespan for an old problem. . . defacto industry-standard

    Reply
  • calendar

    Posted by vinoth on 09/12/2012 02:04am

    i need this coding for c#

    Reply
  • wish

    Posted by Mahesvani on 07/28/2012 12:14am

    thank u so much. this is very helpful to me. but i need this coding for c#

    Reply
  • contact

    Posted by rsmachado90 on 06/02/2007 06:39pm

    Hi, I was wondering if should be possible for you send a working pages of this sample. In mine setting, it doesn't work at all. Thank you in advance. Best regards. Ricardo Machado rsmachado@wavenet.com.br

    Reply
  • Data aware

    Posted by tjh@esh.dk on 07/13/2005 11:56am

    How do i make this fine usercontrol dataaware, so that i can, in a formview databinde to the calendar?

    Reply
  • help with cut/pasted code

    Posted by stu greenberg on 04/29/2005 11:30am

    hey. admittedly i'm doing something stupid. when i cut/paste the html code into a ascx page, i get the < and > code which i replace. when i replace it, the code looks strange and doesn't work. here's the code in my ascx page:
    
    <%@ 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>

    • Reply to stu greenberg

      Posted by Pramod Nair on 02/05/2014 11:21pm

      Your calendar id was mismatched according to your code i.e. your asp tag calendar id is calendar1 and in script function onclick divCalendar. Hope this definitely help

      Reply
    Reply
  • The codes works fine, but I have one question. Please help!!!

    Posted by hvo2 on 04/15/2004 12:57am

    I tried the code with C#, and it works very well. However, when I selected a day in another month, the calendar closed before I can select a day. Which means I can only select a day in the current month dropped down from the calendar. So please if you would, send me the codes or show me how to be able to select a day in another month without having the calendar closed before I can select a day in C#. Thanks.

    • Re: Panel Solution to prevent postback

      Posted by smajr on 05/05/2005 12:27pm

      Could you please help us out a little with this one? I haven't used the pannel control before.

      Reply
    • Re: The codes works fine, but I have one question. Please help!!!

      Posted by hpkevertje on 05/22/2004 08:48am

      What you say is not entierly true. When you click select an other month the calendar will disapear, but if you re-open the calendar you'll see that the new month is there. When you select a new month, a postback is trigered, and the complete page is re-loaded. You have made the calendar visible with client scripting (javascript). The changes you made with client scripting will not be kept in the viewstate of your page. When the page is re-loaded after you selected an other month the div will have visible set false again. In order to avoid this you can use a pannel, which is a server control, and the status of this pannel will be kept in the viewstate (it will stay visible, even after a postback). The drawback of this is that you'll need a postback to show the calendar, which makes everything a bit slower.

      Reply
    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • On-demand Event Event Date: September 10, 2014 Modern mobile applications connect systems-of-engagement (mobile apps) with systems-of-record (traditional IT) to deliver new and innovative business value. But the lifecycle for development of mobile apps is also new and different. Emerging trends in mobile development call for faster delivery of incremental features, coupled with feedback from the users of the app "in the wild." This loop of continuous delivery and continuous feedback is how the best mobile …

  • As mobile devices have pushed their way into the enterprise, they have brought cloud apps along with them. This app explosion means account passwords are multiplying, which exposes corporate data and leads to help desk calls from frustrated users. This paper will discover how IT can improve user productivity, gain visibility and control over SaaS and mobile apps, and stop password sprawl. Download this white paper to learn: How you can leverage your existing AD to manage app access. Key capabilities to …

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds