Login | Register   
RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX


What You Need to Know About Web Controls : Page 3

Knowing the flaws in Web server controls and how to work around them before you use them can save you hours of time.

Working with the Calendar
The Calendar is a Web server control that can be used to display a month-by-month calendar. The end user can use the calendar to select a date. On most forms, however, you don't want to display a calendar. Rather, you want to display a Textbox and an Image that, when clicked, will drop down a calendar as shown with the Active Date in Figure 1 and Figure 2. It doesn't seem that this task should be difficult—but it is.

Figure 2: When the end user clicks on the calendar icon, the Calendar control is displayed.
If you want a perfect date picker control, your best answer is to purchase a third-party product that provides a control with the features you need. Or download an open source control, such as the one provided with the book, Developing Microsoft ASP.NET Server Controls and Components, by Nikhil Kothari and Vandana Datye.

If a simple solution will suffice, you can place the Calendar control on a Panel control and hide and show the Panel when the calendar Image control is clicked. This section details this simple solution.

Start by putting a Textbox Web Server control on a Web form with an ID of txtActiveDate. Add a simple HTML Image control (IMG) to display an appropriate calendar image as shown in Figure 1. The resulting HTML is as follows:

<asp:textbox id="txtActiveDate" Runat="server" Width="200"></asp:textbox> <IMG alt="Display Calendar" src="images/cal.gif">

Define the Textbox control as a Web Server control so that it can be accessed in the code-behind running on the server. Create the Image control as a simple HTML control because it does not need to be processed on the server.

Next, define a Panel Web Server control and put the Calendar Web Sever control on the panel. Depending on the styles you apply to your Calendar control, your HTML will be similar to the following:

<asp:panel id="pnlActiveDate" style="DISPLAY: none; Z-INDEX: 100; POSITION: absolute" runat="server"> <asp:Calendar id="calActiveDate" Runat="server" Width="180px" BorderWidth="1px" Height="120px" ShowGridLines="True" BorderColor="#FFCC66" Font-Names="Verdana" Font-Size="8pt" ForeColor="#663399" DayNameFormat="FirstLetter" BackColor="#FFFFCC"> <DayStyle CssClass="formitem" /> <TodayDayStyle ForeColor="White" BackColor="#FFCC66"/ > <SelectorStyle BackColor="#FFCC66"/> <NextPrevStyle Font-Size="9pt" ForeColor="#FFFFCC"/> <DayHeaderStyle CssClass="formitem" Height="1px" BackColor="#FFCC66"/> <SelectedDayStyle Font-Bold="True" BackColor="#CCCCFF"/> <TitleStyle CssClass="formitem" ForeColor="#FFFFCC" BackColor="#990000"/> <OtherMonthDayStyle CssClass="formitem" ForeColor="#CC9966"/> </asp:Calendar> </asp:panel>

The styles on the Calendar control can be set to any desired value. The important settings are in the Panel control's Style attribute. The Display setting defines how the panel is displayed. Define a value of None so that the panel is hidden, which is the desired initial value.

Set the Z-Index to a large number to ensure that the Panel will appear over all of the other controls when it is dropped down. Note, however, that there is a known problem whereby any HTML Select controls (which is what ASP.NET outputs for DropDownList controls) will appear over any other control, regardless of their Z-Index value. So you need to place the Panel control in a position such that it won't drop down over Select or DropDownList controls or, put the Select or DropDownList controls in a Panel where they can be hidden when the calendar panel is dropped down.

Finally, set the Position of the Style attribute to Absolute so that it will allow other controls to flow around it. Otherwise the layout will not appear appropriately.

Now that all of the controls are in place, there are two basic ways to hide and show the Panel containing the Calendar. One way is to change the Image HTML control to a Button Web Server control and handle the button click on the server. The downside of this approach is two-fold: you have the performance hit of a server-side call and you have the flashing of the page caused by the repost.

Alternatively you can use the HTML Image, like in this example, and write some client-side scripting code to hide and show the panel when the image is clicked. The following presents the required client-side JavaScript code.

<script> function DisplayCalendar(pnl) { var ele = document.getElementById(pnl); if (ele != null) { if (ele.style.display=="none") { ele.style.display="block"; } else { ele.style.display="none"; } } } </script>

Insert this code in the <head> portion of the HTML for the Web form. The function takes the name of the Panel control as a parameter, allowing for multiple occurrences of the "date picker". As you are writing this code, don't forget that JavaScript is case sensitive!

The code in the DisplayCalendar function uses the getElementById method of the document (Web page) to find the Panel control on the page. Then, if the panel is hidden, it shows it by setting the Display style to block. If the panel is shown, it hides it by setting the Display style to none. This has the effect of showing the panel containing the calendar when the end user first clicks the image and then hiding the panel if the end user clicks the image again.

For this script to work, it has to be connected to the OnClick event for the Image control:

<IMG onclick="DisplayCalendar('pnlActiveDate');" alt="Display Calendar" src="images/cal.gif">

Now for the code-behind.... When the end user selects a date in the Calendar control, the date should appear in the associated Textbox control and the Panel control containing the calendar should again be hidden. You do this by handling the SelectionChanged event of the calendar:

Private Sub calActiveDate_SelectionChanged( _ ByVal sender As System.Object, _ ByVal e As System.EventArgs) _ Handles calActiveDate.SelectionChanged txtActiveDate.Text = _ calActiveDate.SelectedDate.ToShortDateString pnlActiveDate.Style.Item("display") = "none" End Sub

This code puts the short date version of the date into the Textbox control. It then hides the Panel containing the Calendar control. Notice that the Display style of the Panel control is used instead of the Visible attribute of the control. Setting the Visible attribute of a Web Server control prevents the control from appearing in the HTML, which means that it cannot be accessed from any client-side scripting. Since this example uses client-side scripting to access this control, the Display style is used instead.

The last event that the code needs to handle is the VisibleMonthChanged event:

Private Sub calActiveDate_VisibleMonthChanged( _ ByVal sender As Object, _ ByVal e As WebControls.MonthChangedEventArgs) _ Handles calActiveDate.VisibleMonthChanged pnlActiveDate.Style.Item("display") = "block" End Sub

The existing code will cause the panel containing the calendar to be hidden when the end user clicks on a date, which is desired. But the code will also cause the calendar to be hidden when the end user clicks on the arrows to change the month, which is not desired. So code in the VisibleMonthChanged event will ensure that the panel remains shown as the end user clicks through the months.

There you have it, a poor man's date picker control using the Microsoft Calendar control.

It is often not the every-day coding that impacts our productivity and causes us to miss our deadlines and overrun our budgets. Rather, it is how quickly we can find answers when .NET does not provide us with the results we expected.

Knowing about the roadblocks ahead of you and how to get around them will make it easier for you to get to your destination on time.

Comment and Contribute








