1. Original Entry + Comments2. Write a Comment3. Preview Comment
New comments for this entry are disabled.


February 10, 2004  |  ASP.NET Calendar Questions: a pop-up calendar  |  65956 hit(s)

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.




Colt   11 Feb 04 - 6:46 AM

Yeah, you just start a FAQ :-)

I saw lots of discussion about "PopUp *" from times to times. After publishing my "PopUp Calendar" article, I received lots of emails asking a "follow-up" question - How to close the PopUp calendar without clicking the "Close" button, but just close it by clicking on any date directly?

And you just answer this question by generating the client script for the OnSelectedChanged event like your Button_Click event.

BTW, There're lots of Q&A regarding Calendar control by my observation, two of them are: 1. How can I build a scheduler by using calendar control? (Day_Redner) 2. How to select today's date if I set the visible date to today's date programmatically? :)

* = AnythingHere


 
Mike   11 Feb 04 - 7:54 AM

Yes, I've seen (2) a couple of times. The scheduler is a really a question about how to data bind the Calendar control, I think. The second one, hmmmm.

 
Datagrid Girl   15 Mar 04 - 8:01 AM

Hi Mike, just caught up to this post (I'm a bit behind in my blog reading). Maybe you could call yourself the Calendar Control Cobbler :)

--Marcie


 
Raj   08 Sep 05 - 5:33 AM

I saw yr code to call a pop up calender.

Would like to know that, how do i pass my date back from a Pop Up calender into a Textbox found in my Datagrid.

It works well if use a textbox. But I cant seem to pass the date value back to my textbox that is found inside a datagrid?

How do i solve this problem.

Thanks in advance.


 
Colt   08 Sep 05 - 5:38 AM

Hi Raj,

For using the pop up calendar inside a datagrid, you may take a look at this article: http://www.dotnetjunkies.com/tutorial/a5af72fe-281a-449d-8804-517b35a920a7.dcik

Colt


 
M. M.   09 Apr 10 - 7:30 AM

I realize this article is quite old, but I REALLY need this information and this site no longer exists: http://www.dotnetjunkies.com/tutorial/a5af72fe-281a-449d-8804-517b35a920a7.dcik

Is there anywhere else I can get find out how to get the date from the pop-up calendar into the text box in a datagrid/gridview? It all works up to the calendar close, but nothing shows in the textbox. And please don't send me to that dotjohn site, been there, done that, not what I need. (btw, what happened to dotnetjunkies? I loved that site, it sucks now)


 
mike   09 Apr 10 - 9:56 AM

In a DataGrid or GridView control, any TextBox control will have a dynamically generated ID, which is going to complicate the issue of reading a value into it. You've seen this -- ?

http://www.mikepope.com/blog/DisplayBlog.aspx?permalink=1504

I assume so, but that's what I know so far about popup calendars ...