Date pickers and calendar popup are a great way for a user to accurately select the date they require. The main problem with most date pickers is that they take an eternity to popup a new window and initialize, this has a negative effect and the user tends to avoid the popup and enter the date manually which may induce errors. In this article, I’ll make use of one of the best calendars on the web today – Microsoft’s calendar.htc and expose it in a more efficient manner.
In my last article, I had demonstrated how to use DHTML behaviours to expose common functionality as a CSS style and briefly talked about element behaviours. The Microsoft calendar.htc is an element behaviour that exposes a fully functional DHTML calendar. Microsoft’s calendar is great, and apart from adding a double click event and a bit of styling, I’ve left it intact. Instead of changing the calendar, I decided to create an element behaviour and embed the calendar.htc into it, this way we leave the calendar relatively untouched. The wrapper will expose the calendar in the form of a popup; the popup object is a special type of overlapped window that is very much like a
layer, but unlike the
layer it hides itself when losing the focus and can go over select elements. Here are the main benefits of the control:
- Totally encapsulated date picker / calendar.
- Quick loading.
- Immune to popup blockers (when opening from script).
- Targets HTML controls or ASP.NET web controls.
First of all, we need to declare our namespace, this is to ensure that the calendar element has a unique qualifier. The HTML element has a
xmlns attribute that declares the namespace
astutemedia. Setting this attribute allows us to use the prefix
astutemedia in the document. The next step is to import the calendar element into the namespace with the
<?import namespace="astutemedia" implementation="CalendarPopup.htc">
The import directive is really the key to implementing an element behaviour in the primary document. When the browser begins processing the “
import” directive, it waits until the contents of the HTC file have been downloaded completely before continuing. The way this instruction is processed is the reason why the behaviour is bound synchronously to the custom element.
Using the CalendarPopup.htc
Element behaviours are implemented the same as ASP.NET server controls, but all of the processing is done on the client. As you can see from the code snippet below, "
Calendar1" has a
target attribute that references a textbox, which gets populated by the selected date. The second element doesn’t provide a
target but gets the selected date from the
onDateSelected event via the
selectedDate event attribute.
<input class="FormTextBox" id="Date1" type="text"
<astutemedia:calendar id="Calendar1" target="Date1"></astutemedia:calendar>
Creating the Behaviour
The solution has four files:
- Calendar.gif – This is the calendar icon that gets rendered by the behaviour.
- Calendar.htc – This is Microsoft’s Calendar behaviour.
- Calendar.htm – This is the popup’s body, encapsulated into a HTML file.
- CalendarPopup.htc – This is the main behaviour.
The Calendar.htc behaviour has one minor change that allows us to double click on a date to select it. This is achieved by adding a custom event called
<public:event id="onCalendarDblClick" name="oncalendardblclick">
This gets called when the inner table of the calendar gets double clicked. We reference the
innerTableElem and attach the
DblClick function to the
var oEvent = createEventObject();
We make use of this event in the Calendar.htm file. On the
OnCalendarDblClick event, we call a function called
CloseCalendar which exposes the value of the selected date.
This function is strictly necessary, as we could have called
Unload function from the CalendarPopup.htc directly. But adding this function allows readability.
var val = Calendar.value;
var id = parent.document.body.children.ParentId;
The CalendarPopup.htc holds the main functionality. It exposes the calendar as a custom element and produces the date picker as a popup. We first start off by declaring the component.
<public:defaults viewLinkContent="true" />
<public:property name="Version" value="Calendar 1.0" />
<public:property name="Target" value="" />
<public:event id="onDateSelected" name="ondateselected">
<public:method name="Unload" />
<public:attach event="oncontentready" onevent="Init()" />
As you can see from the above code sample, we expose a
Target property and give it a default property of an empty string. We also expose an event called
onDateSelected, which gets called when the popup unloads. The
Unload method gets called by the
CloseCalendar function in the Calendar.htm file. We then attach the “
Init” function to an event on the holding page (the page where we want to use the behaviour), the event is
onContentReady, this event gets fired when the content on the holding page is fully loaded.
Init function first checks to see if the
Target property is set, and if so attaches the
onDblClick event to the element. This will allow the double click of the element to show the calendar. We then create the popup itself and populate it with the Calendar.htm file.
if(Target != null && Target != "")
popup = win.createPopup();
popupBody = popup.document.body;
popupBody.innerHTML = "<object id='cal' width='100%'
ParentId='" + id + "' height='100%' type='text/x-scriptlet'
Unload function fires the
onDateSelected event and if a target exists, populate it with the selected date value. It then hides the popup.
var e = createEventObject();
e.selectedDate = val;
if(Target != null && Target != "")
winDoc.getElementById(Target).value = val;
The last function is the
ShowPopup function; this function shows the popup when the the calendar icon is clicked or the target element is double clicked. It positions the popup 22 pixels from where the click/double-click occurred. It also makes sure that it doesn’t conflict with the boundaries of the browser window.
var wEvent = win.event;
var winDocBody = winDoc.body;
var popupWidth = 320;
var popupHeight = 250;
x = wEvent.x + 22;
y = wEvent.y - 22;
if (x + popupWidth > winDocBody.clientWidth)
x = wEvent.x - (popupWidth + winDocBody.scrollLeft + 22);
x += winDocBody.scrollLeft;
if (y + popupHeight > winDocBody.offsetHeight)
y = wEvent.y - (popupHeight + winDocBody.scrollTop + 22);
y += winDocBody.scrollTop;
popupBody.style.border = "1px solid #333333";
popup.show(40, -80, popupWidth, popupHeight, document.body);
Finally, we output our calendar icon and add an
onClick event to show the popup.
<img src="Calendar.gif" width="16" height="15" style="cursor:hand"
onclick="ShowPopup()" title="Click to show calendar" align="absMiddle">
This behaviour makes calendars and date pickers a quick and easy solution to a very common problem. Element behaviours are a great way to implement and encapsulate common functionality and are very quick to use. If you are using ASP.NET, you can wrap the element behaviour in a server control to expose the selected date on the server side.
Links and Resources
Downloads and Demos