Tuesday, 16 May 2006
08:16 PM
THe topic of creating a pop-up calendar seems to be a perennial favorite.[1] I played around with one some time ago, which in that case mostly consisted of channeling someone else's ideas.
And so again. My friend Michael B was working on his own version, which involved what I thought was a significant improvement: rather than popping up the calendar in a pop-up (that is, using window.open), he was using CSS attributes to show and hide a calendar. The problem with using window.open is that it can be blocked by pop-up blockers. But simply showing and hiding a calendar should be no problem, assuming JavaScript is enabled.
The basic concept is this. A normal ASP.NET calendar lurks on the page, but its style visibility attribute is initially set to hidden. A client-side show-the-calendar button runs JavaScript to set the style visibility attribute to visible. Gentle User selects a date (the postback, she occurs), and then server-side code returns the date to whatever (ASP.NET) text box you want. (Naturally, the calendar has to be absolutely positioned, and should probably have a z-order that guarantees that it will appear in front of everything else.)
Here's what it looks like -- you can play with it on this page.
Naturally, there were complications. Some were self-imposed, of which the biggest was that I wanted to re-use a single Calendar control. This meant (as I eventually figured out) that I had to store information about the textbox that the Calendar was "bound" to and about the top/left location where the Calendar should appear -- I wanted it to have an offset from the button that had invoked it, rather than a fixed position on the page.
The button that invokes the calendar is all client-side, so I was obliged to use a somewhat clunky mechanism of a) writing a client-side function that would take the ID of the "bound" text box, b) capture the top/left coordinates of the invoking button, and apply them to the calendar, and c) store all that in a hidden field. This last enables me to pass the info up to the server on postback. Because I was doing all this in a hurry, I elected to store the three pieces of information in a string delimited by "+".[2]
When the user selects a date in the calendar, server-side code plucks the ID of the "bound" text box out of the hidden field, finds the actual text box instance, and sets its Text property to the date. Server code then hides the calendar, since we're now done with it.
A tricky thing arose in month navigation -- the calendar does a postback, but we don't want it to disappear until the user actually selects a date. In that case, server code plucks the top and left values out of the hidden field and (re)applies those to the calendar so it will (continue to) show up at the right spot.
You can see the source code for the whole page here. For a change of pace, I wrote the server code in C#; I need the practice.
There's a lot of code required for this -- client code, server code, and fussy function calls for the buttons doing the invoking. This really wants encapsulation in a control. I played briefly with making the whole business a user control, but realized I needed to do actual work to determine the ID of the Calendar control inside a container user control. So I put that off till I could "think about it more."
But anyway, I have a sense of what needs to be done, I guess. I'll work it all into a single control Real Soon Now.
[categories]
aspnet
|
link
|