About

I'm Mike Pope. I live in the Seattle area. I've been a technical writer and editor for over 35 years. I'm interested in software, language, music, movies, books, motorcycles, travel, and ... well, lots of stuff.

Read more ...

Blog Search


(Supports AND)

Feed

Subscribe to the RSS feed for this blog.

See this post for info on full versus truncated feeds.

Quote

Women can actually love us for ourselves, bless their hearts, even when we can't love ourselves.

Roger Ebert



Navigation





<December 2024>
SMTWTFS
24252627282930
1234567
891011121314
15161718192021
22232425262728
2930311234

Categories

  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  
  RSS  

Contact Me

Email me

Blog Statistics

Dates
First entry - 6/27/2003
Most recent entry - 9/4/2024

Totals
Posts - 2655
Comments - 2677
Hits - 2,715,618

Averages
Entries/day - 0.34
Comments/entry - 1.01
Hits/day - 347

Updated every 30 minutes. Last: 2:13 PM Pacific


  11:21 PM

I've been meaning for a while to gather up the various questions I've seen about the ASP.NET Calendar control. In much the way Marcie likes the DataGrid control, I like (that is, I feel "affinitized to") the Calendar control, although I cannot claim a tenth of much expertise with the Calendar as DataGridGirl does with her control of choice.

Update 16 May 2006 For yet another take on pop-up calendars, have a look at another example that I posted today.

Nonetheless, I find questions about the Calendar control on the ASP.NET forums weirdly compelling, so I seize on those and have a small collection of links and samples. I had it in mind to create a FAQ, but it hasn't come together. Partly, I think, it's because so many of the A part of the Q&A are variations on "use the DayRender event." However, I'll get around to posting some of those. All in good time.

I'm positive that the single most common question is "How do I create a pop-up calendar?" The desire is to be able to use the Calendar control, but to hide it until needed. It does after all take up a lot of room.

I have an example here to show you the general idea.

Many people have tackled this question. Here's a short list of the links I have that pertain to exactly this question:

From my fellow blogger Colt:
http://authors.aspalliance.com/Colt/Articles/Article4.aspx

4 Guys From Rolla
http://aspnet.4guysfromrolla.com/articles/030202-1.aspx

Code Project:
http://www.codeproject.com/vb/net/dwDatePickerArticle.asp

DotNetJohn:
http://dotnetjohn.com/articles/articleid88.aspx

Some of the many forum posts:
http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=259315

http://www.asp.net/Forums/ShowPost.aspx?tabindex=1&PostID=64986

I personally first saw this at a .NET DA user group meeting in Seattle, when Doug Seven showed us his version as part of a "tips and tricks" talk, so his is the technique that I know. However, I believe that most of these articles suggest roughly the same strategy. The sample I have, and the description below, is based closely on Doug Seven's own writeup of the technique, which you can find here.

It seems odd to reiterate what you can read elsewhere, but oh well. I wanna. :-)

The Basics of a Popup Calendar
Creating a popup calendar with ASP.NET requires two .aspx pages. The first is your source page, the one with the text box (or whatever) that you want to populate with a date. This page also contains a button or link of some sort to invoke the calendar. This button-or-link does not/should not be an ASP.NET control; it will run some client script, and in fact, you don't want it to post back.

The second .aspx page contains a calendar -- the ASP.NET Calendar control -- and a way to close the window.

Popping Up the Popup
Causing the calendar to pop up is a client-side job. The task leverages the JavaScript window.open() method. The method opens a browser window and displays a specified page in it. You can pass a bunch of parameters to the open() method to specify stuff like location, size (height, width), window decoration (menu bar, scrollbars). A very important parameter is target -- that is, whether to open in a new window. We do, so it will "pop up."

The call I use[1] in the example is this:
window.open("CalendarPopUp_child.aspx?src=" + Src, "_blank", 
"height=260, width=250, left=100, top=100, " +
"location=no, menubar=no, resizable=no, " +
"scrollbars=no, titlebar=no, toolbar=no", true) ;
If you've called window.open() before, this will be familiar. Here, we're calling the second page (CalendarPopUp_child.aspx). The call appends a query string onto the URL, which I'll explain in a moment.

The Calendar Page
The Calendar page itself (CalendarPopUp_child.aspx) is just a normal .aspx page. The Calendar works as it would in any page. The interesting part is in what happens to close the page and in how the source and popup pages talk to each other.

Passing the Date Back to the Source Page
The whole trick with this business is in how the calendar can pass a date back to the calling page. Here's how I'm doing it for the example:

1) The source page passes to the popup page the ID (as a string) of the control where we want the date. In the example, it's "TextBox1," because I want to inject the calendar date into the text box.

2) In the popup page, the Close link (actually a LinkButton) dynamically creates a chunk of client script that looks like this when it runs:
<script language=javascript>
window.opener.document.all[control].value = Calendar.SelectedDate.ToString("d");
window.close(); // Closes the popup window
</script>
The magic is in window.opener, which gets a reference to the page that called the popup, i.e, to the source page. Given that reference, you can work with controls on the source page. Here, the code sets the value property of a designated control to the selected date.

How does the popup client script know what control to populate? Aha. That's the value that was passed in the query string to the popup page in Step 1.

The Code
Here's what the source page looks like:
<%@ Page Language="VB" %>
<html>
<head>
<script language="JavaScript">
function pickDate(Src){
window.open("CalendarPopUp_child.aspx?src=" + Src, "_blank",
"height=260, width=250, left=100, top=100, " +
"location=no, menubar=no, resizable=no, " +
"scrollbars=no, titlebar=no, toolbar=no", true) ;
}
</script>
</head>
<body>
<form runat="server">
Click the button to select a date
<asp:TextBox id="TextBox1" runat="server" Width="95px" />
<button
onclick="pickDate('TextBox1')"
type="button">Choose Date
</button>
</form>
</body>
</html>
Notice that the button is a client button only. Its onclick attribute is hardcoded to invoke the (JavaScript) pickDate() function and pass it the ID of the TextBox control.

The popup page, CalendarPopUp_child.aspx, is also straightforward (I'm sparing you the formatting stuff):
<%@ Page Language="VB" %>
<script runat="server">
Sub Page_Load()
If Not IsPostBack
Calendar1.SelectedDate = DateTime.Today
End If
End Sub

Sub buttonClose_Click(sender As Object, e As EventArgs)
Dim returnScript As String = ""
returnScript &= "<script language=javascript>"
returnScript &= "window.opener.document.all['"
returnScript &= Request.QueryString("Src")
returnScript &= "'].value = '"
returnScript &= Calendar1.SelectedDate.ToString("d")
returnScript &= "';window.close();"
returnScript &= "<" & "/" & "script>"
Page.RegisterStartupScript("", returnScript)
End Sub
</script>
<html>
<body>
<form runat="server">
<asp:Calendar id="Calendar1" runat="server" />
<p>
<asp:LinkButton
id="buttonClose"
onclick="buttonClose_Click"
runat="server" text="Close" />
</p>
</form>
</body>
</html>
The code to create the client script dynamically is a little messy because of all the concatenation. (Refer to the sample earlier to see what the code would look like when running.) There are just a couple of notes:
  • The name of the control has to be concatenated into the window.opener... string. That's a particularly fussy string, what with having to get all the quotation marks in there.
  • The Close button actually performs a postback. In the Click handler, the Close button generates the client script dynamically and then injects it into the page as a "startup script" -- in other words, as a hunk of client script that will execute as soon as the page is finished loading. (More use for the Page object's client script methods.) So when you click Close, the popup page performs a postback, injects script into the page, and then renders. When the browser (the popped-up window) gets the client script, it does its window.opener thing and then closes itself.

Pretty neat, actually, although subject to the usual problems of javascript. If client script is disabled, no joy. A popup is also subject to popup killers, alas.

But there you have it, one of the many variations on a popup calendar using the ASP.NET Calendar control. With that out of the way, I'll now be able to turn my attention to those other Calendar questions. :-)

[1] Just to so there's no mistake here, this is mostly Doug Seven's code.

[categories]  

[7] |