asp tutorials, asp.net tutorials, sample code, and Microsoft news from 15Seconds
Data Access  |   Troubleshooting  |   Security  |   Performance  |   ADSI  |   Upload  |   Email  |   Control Building  |   Component Building  |   Forms  |   XML  |   Web Services  |   ASP.NET  |   .NET Features  |   .NET 2.0  |   App Development  |   App Architecture  |   IIS  |   Wireless
 
Pioneering Active Server
 Power Search





Active News
15 Seconds Weekly Newsletter
• Complete Coverage
• Site Updates
• Upcoming Features

More Free Newsletters
Reference
News
Articles
Archive
Writers
Code Samples
Components
Tools
FAQ
Feedback
Books
Links
DL Archives
Community
Messageboard
List Servers
Mailing List
WebHosts
Consultants
Tech Jobs
15 Seconds
Home
Site Map
Press
Legal
Privacy Policy
internet.commerce














internet.com
IT
Developer
Internet News
Small Business
Personal Technology
International

Search internet.com
Advertise
Corporate Info
Newsletters
Tech Jobs
E-mail Offers

HardwareCentral
Compare products, prices, and stores at Hardware Central!

Creating a Popup Date Picker
By Conrad Jalali
Rating: 4.0 out of 5
Rate this article


  • email this article to a colleague
  • suggest an article

    Prerequisites

    Introduction

    Recently, I was working on a Web Form and I wanted to give users an easy way to enter a date into a TextBox control. Back in the days of Classic ASP, I frequently used a small ASP page, opened in a popup window, to display a calendar. Users could go to the previous/next month, and when a date was clicked, the selected date would populate the input field via some basic JavaScript.

    But we're in the .NET world now. I wanted to come up with an easy way to do this that would rely on the rich controls that Microsoft included with ASP.NET. After a quick trip to Google, I found a solution; add a new EventHandler to the ASP.NET Calendar control's SelectionChanged event that emits the JavaScript needed to set the value of the TextBox.

    All was well in the world. I had a solution that provided the functionality that I needed, and I didn't have to use a third party control or write my own from scratch. But then I started testing the solution...

    While everything worked, there was an annoying delay between the user's click selecting a date, and the date populating the TextBox. This pause, which lasted a few seconds, was driving me crazy. It didn't take long to find the culprit; the PostBack.

    Even though the Calendar control was using JavaScript to set the value of the TextBox, it was doing so when the SelectionChanged event fired. This event is fired on PostBack, so there was a delay between the user's click and the data filling in the TextBox. Remember, the PostBack submits a Web Form back to itself. This causes the user to wait unnecessarily, and needlessly adds to the Web server's load.

    Back to the Drawing Board

    I still didn't want to create my own custom calendar control, and I wasn't satisfied with the PostBack option, so I decided to explore extending the functionality of the ASP.NET Calendar control. Specifically, the Calendar control's DayRender method piqued my interest, so I let my IntelliSense do the walking.

    I found that I could clear the standard date link from each day in the calendar and create my own link. My link would include the HTML and JavaScript needed to populate the TextBox and close the popup window. Now I was in business.

    Building the Solution

    Let's look at the elements that will make up our solution:

    • A Web Form with a TextBox control whose value will be populated by the calendar
    • A link on the Web Form with some JavaScript to launch the date picker popup
    • A Web Form for the date picker popup
    • A Calendar control on the date picker page with an extra DayRenderEventHandler attached
    • A DayRenderEventHandler delegate to replace the standard date links with a custom JavaScript link

    The Web Form is straight forward:

    Here is the HTML for the "pick" link, which launches the date picker popup:

    <a href="javascript:;" onclick="calendarPicker('Form1.txtEventDate');" title="Pick Date from Calendar">pick</a>

    Note that since the tag does not have the runat="server" attribute, the onClick event will fire on the client-side (in the browser), not on the server.

    As you can see, the link calls a JavaScript function called, calendarPicker. I prefer to call a function with the link, rather than writing the code in-line, as there may be more than one date field on a form. If we write the code in a function that uses a parameter to specify the reference to the field that we want to set, we can reuse the code for as many TextBox controls as we like on a single page. We can also debug JavaScript functions, but more on that, later.

    I like to pass the calendarPicker function the name of the field that we want to edit in the format, "FormName.FieldName". You might have occasion to substitute your own form ID for VS .NET's standard "Form1", so I don't like to hard code this.

    Here is the calendarPicker function:

    <script language="javascript" type="text/javascript">

                /// <summary>

                /// Launches the DatePicker page in a popup window,

                /// passing a JavaScript reference to the field that we want to set.

                /// </summary>

                /// <param name="strField">String. The JavaScript reference to the field that we want to set,

    /// in the format: FormName.FieldName

                /// Please note that JavaScript is case-sensitive.</param>

                function calendarPicker(strField)

                {

                            window.open('DatePicker.aspx?field=' + strField, 'calendarPopup', 'width=250,height=190,resizable=yes');

                }

    </script>

    The calendarPicker function opens a page called DatePicker.aspx in new window. It passes the name of the field that we want the calendar to set in the QueryString. I like to use Visual Studio-style comments for my client-side scripts since it gets me in the habit of documenting my code.

    Next, the DatePicker ASPX page:

    The DatePicker page contains one standard ASP.NET Calendar control:

    <%@ Page language="c#" Codebehind="DatePicker.aspx.cs" AutoEventWireup="false" Inherits="CalendarPopup.DatePicker" %>

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN" >

    <html>

                <head>

                            <title>DatePicker</title>

                            <meta name="GENERATOR" content="Microsoft Visual Studio .NET 7.1">

                            <meta name="CODE_LANGUAGE" content="C#">

                            <meta name="vs_defaultClientScript" content="JavaScript">

                            <meta name="vs_targetSchema" content="http://schemas.microsoft.com/intellisense/ie5">

                            <style type="text/css">

                            BODY { PADDING-RIGHT: 0px; PADDING-LEFT: 0px; PADDING-BOTTOM: 0px; MARGIN: 4px; PADDING-TOP: 0px }

                            BODY { FONT-SIZE: 9pt; FONT-FAMILY: Verdana, Geneva, Sans-Serif }

                            TABLE { FONT-SIZE: 9pt; FONT-FAMILY: Verdana, Geneva, Sans-Serif }

                            TR { FONT-SIZE: 9pt; FONT-FAMILY: Verdana, Geneva, Sans-Serif }

                            TD { FONT-SIZE: 9pt; FONT-FAMILY: Verdana, Geneva, Sans-Serif }

                            </style>

                </head>

                <body onblur="this.window.focus();" ms_positioning="FlowLayout">

                            <form id="Form1" method="post" runat="server">

                                        <div align="center">

                                        <asp:calendar id="Calendar1" runat="server" showgridlines="True" bordercolor="Black">

                                                    <todaydaystyle forecolor="White" backcolor="#FFCC66"/>

                                                    <selectorstyle backcolor="#FFCC66"/>

                                                    <nextprevstyle font-size="9pt" forecolor="#FFFFCC"/>

                                                    <dayheaderstyle height="1px" backcolor="#FFCC66"/>

                                                    <selecteddaystyle font-bold="True" backcolor="#CCCCFF/>

                                        <titlestyle font-size="9pt" font-bold="True" forecolor="#FFFFCC" backcolor="#990000"/>

                                                                <othermonthdaystyle forecolor="#CC9966"/>

                                                    </asp:calendar>

                                        </div>

                            </form>

                </body>

    </html>

    The BODY tag contains a simple script that runs in the onBlur event (clientside) to turn the popup into a modal dialog box. Since we want the popup to be small, and its only purpose is to set a field value in the main page, there's no reason to let the user switch back to the other window.

    The magic happens in a method that we attach to the Calendar's DayRender event:

    /// <summary>

    /// Replaces the standard post-back link for each calendar day

    /// with the javascript to set the opener window's TextBox text.

    /// Eliminates a needless round-trip to the server.

    /// </summary>

    /// <param name="sender"></param>

    /// <param name="e"></param>

    private void Calendar1_DayRender(object sender, System.Web.UI.WebControls.DayRenderEventArgs e)

    {

                // Clear the link from this day

                e.Cell.Controls.Clear();

     

                // Add the custom link

                System.Web.UI.HtmlControls.HtmlGenericControl Link = new System.Web.UI.HtmlControls.HtmlGenericControl();

                Link.TagName = "a";

                Link.InnerText = e.Day.DayNumberText;

                Link.Attributes.Add("href", String.Format("JavaScript:window.opener.document.{0}.value = \'{1:d}\'; window.close();", Request.QueryString["field"], e.Day.Date));

               

                // By default, this will highlight today's date.

                if(e.Day.IsSelected)

                {

                            Link.Attributes.Add("style", this.Calendar1.SelectedDayStyle.ToString());

                }

     

                // Now add our custom link to the page

                e.Cell.Controls.Add(Link);

    }

    This method will be called each time the Calendar control renders a day. The first thing that our method does is clear the contents of the table cell for the day that's being rendered. Next, we programmatically create a hyperlink (an <A> tag). We use the current day number from the Calendar as the InnerText for the link, just like the Calendar control would normally have done. We set the "HREF" property of the link by building a string that has the JavaScript needed to set the value of the TextBox control in the opener window, and then close the DatePicker window.

    In the JavaScript, "opener" is a keyword that refers to the window that opened the current window via a window.open command. ASP.NET TextBox controls are renedered as <INPUT> tags in HTML. The script continues by setting the value of the particular field that we want to change, and in this case, we're specifying that the selected date be used (formatted with the ShortDatePattern) to set the value of the field.

    In our Calendar1_DayRender method, we then check to see if the day that we're on represents today's date. Since we haven't specified the Calendar's SelectedDate property, it will select today's date by default. I like to give users a reference point, so I add a "style" attribute to our link and use the Calendar's SelectedDayStyle.

    We wrap everything up by inserting our replacement hyperlink in the table cell for the day that we're on.

    Things are going along fine, but we still haven't re-wired the Calendar control to call our custom method. To attach Calendar1_DayRender to the DayRender event for the Calendar, we can either edit DatePicker.aspx in Design mode in VisualStudio .NET or directly modify the page's InitializeComponent method in the code-behind file.

    To avoid messing with the auto-generated code in the InitializeComponent method, we can add the EventHander by viewing the DatePicker page in Design mode. Click on the Calendar control and then click on the Events icon (the lightning bolt) in the Properties box. We should be able to select the method, Calendar1_DayRender, in the drop down menu next to the DayRender action.

    VS .NET populates the available choices in the drop down menu by searching the code-behind file for any methods that match the ASP.NET Calendar control's DayRender event delegate signature. (The DayRenderEventHandler delegate takes two parameters; an object and a DayRenderEventArgs type.)

    If we prefer to attach the custom delegate ourselves (or simply want to take a look at the changes made through the VS.net IDE), we can find the InitializeComponent method in the code-behind file in a region labeled "Web Form Designer generated code".

    /// <summary>

    /// Required method for Designer support - do not modify

    /// the contents of this method with the code editor.

    /// </summary>

    private void InitializeComponent()

    {

                this.Calendar1.DayRender += new System.Web.UI.WebControls.DayRenderEventHandler(this.Calendar1_DayRender);

                this.Load += new System.EventHandler(this.Page_Load);

    }

    Notice that we're adding our DayRenderEventHandler, not replacing the Calendar control's built-in EventHandler. This is indicated by the += syntax. Let's let ASP.NET do the work of creating the HTML table for the calendar, and all of the days in the month. We're just going to substitute our own content for each day's table cell.

    Testing >>

  • Rate This Article
    Not HelpfulMost Helpful
    1 2 3 4 5
    Other Articles
    Apr 21, 2004 - Creating a Web Custom Control
    Conrad Jalali shows how to build Web custom controls by creating one that displays checkboxes in a categorized, hierarchical view.
    [Read This Article]  [Top]
    Oct 23, 2003 - Creating a Custom .NET Web Control With Events
    This article covers some of the essentials of building reusable Web controls. Learn how to create a Web control and its custom events and event arguments, as well as how to use the control properly within a page.
    [Read This Article]  [Top]
    Aug 12, 2003 - Creating a Generic Pager Control
    ASP.NET provides only one control that supports paging, the DataGrid. Tomasz Kaszuba shows how to build and implement a custom pager for different controls that change depending on the data source or presentation.
    [Read This Article]  [Top]
    Jun 10, 2003 - Hosting .NET Windows Forms Controls in IE
    Windows Forms within Web pages work in a manner similar to Java applets. Thiru Thangarathinam shows how to host Windows Forms controls in Internet Explorer and how to utilize .NET Code Access Security to configure what the control can do when running within the browser.
    [Read This Article]  [Top]
    May 6, 2003 - Building a Simple Mask Control
    James Culshaw shares his experiences building his first working custom control, a basic mask control that allows input of time values, and offers advice and tips to those just starting out.
    [Read This Article]  [Top]
    Mar 3, 2003 - Creating a Server Control for JavaScript Testing
    Learn how to create an ASP.NET server control that detects if a browser supports JavaScript AND if JavaScript is enabled.
    [Read This Article]  [Top]
    Jan 21, 2003 - Protecting Users from Suspect Textual Data
    Learn the ins and outs of composite controls by creating an application that prevents users from submitting offending text.
    [Read This Article]  [Top]
    Nov 26, 2002 - Introduction to the .NET Speech SDK
    Rob Chartier offers a tour of the .NET Speech SDK Beta 2 and its use of the industry specification SALT. The article shows you how to create a basic speech-enabled Web user control.
    [Read This Article]  [Top]
    Aug 27, 2002 - Creating "Self Populating" Controls
    In this article, Luther Stanton shows how to combine inheritance and server controls to create a self-populating drop-down-list control.
    [Read This Article]  [Top]
    Apr 30, 2002 - Building ASP.NET User and Server Controls, Part 2
    Solomon Shaffer explains custom controls, describes the complexities and issues surrounding building such controls, and walks through a useful example.
    [Read This Article]  [Top]
    Mailing List
    Want to receive email when the next article is published? Just Click Here to sign up.

    Support the Active Server Industry

    internet.comearthweb.comDevx.commediabistro.comGraphics.com

    Search:

    Jupitermedia Corporation has two divisions: Jupiterimages and JupiterOnlineMedia

    Jupitermedia Corporate Info

    Legal Notices, Licensing, Reprints, Permissions, Privacy Policy.
    Advertise | Newsletters | Tech Jobs | Shopping | E-mail Offers