|
||||||||||||||||||||||||||||||||||||
|
||||||||||||||||||||||||||||||||||||
|
Announcements
Want a new Job?
Chapters
Services
Feature Zones
|
The ProblemDate 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. The SolutionIn 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
RequirementsFirst 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 <html xmlns:astutemedia>
<head>
<?import namespace="astutemedia" implementation="CalendarPopup.htc">
</head>
The import directive is really the key to implementing an element behaviour in the primary document. When the browser begins processing the “ Using the CalendarPopup.htcElement 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, " <input class="FormTextBox" id="Date1" type="text"
maxlength="10" name="Date1">
<astutemedia:calendar id="Calendar1" target="Date1"></astutemedia:calendar>
<astutemedia:calendar id="Calendar2"
onDateSelected="alert(window.event.selectedDate)">
</astutemedia:calendar>
Creating the BehaviourThe solution has four files:
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 window.document.all.innerTableElem.attachEvent("ondblclick", DblClick);
The function… function DblClick()
{
var oEvent = createEventObject();
onCalendarDblClick.fire(oEvent);
}
We make use of this event in the Calendar.htm file. On the oncalendardblclick="CloseCalendar()"
This function is strictly necessary, as we could have called function CloseCalendar()
{
var val = Calendar.value;
var id = parent.document.body.children[0].ParentId;
parent.parent.document.getElementById(id).Unload(val);
}
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:component tagname="Calendar">
<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()" />
</public:component>
As you can see from the above code sample, we expose a The function Init()
{
// Check to see if there is a target element.
if(Target != null && Target != "")
{
// Add a double click to the target elem, to show the calendar
winDoc.getElementById(Target).attachEvent("ondblclick", ShowPopup);
}
// Create a popup object
popup = win.createPopup();
popupBody = popup.document.body;
// Add the scriptlet to the popups body.
popupBody.innerHTML = "<object id='cal' width='100%'
ParentId='" + id + "' height='100%' type='text/x-scriptlet'
data='Calendar.htm'></object>";
}
The function Unload(val)
{
// Create a new event.
var e = createEventObject();
// Expose the selected value with the event.
e.selectedDate = val;
// Fire the event.
onDateSelected.fire(e);
if(Target != null && Target != "")
{
// Find the target in the parent document and set the value.
winDoc.getElementById(Target).value = val;
}
// Hide the popup.
popup.hide();
}
The last function is the function ShowPopup()
{
var wEvent = win.event;
var winDocBody = winDoc.body;
var popupWidth = 320;
var popupHeight = 250;
// Set the x and y from where the mouse clicks.
x = wEvent.x + 22;
y = wEvent.y - 22;
// Check to see if the popup goes out of bounds.
if (x + popupWidth > winDocBody.clientWidth)
x = wEvent.x - (popupWidth + winDocBody.scrollLeft + 22);
else
x += winDocBody.scrollLeft;
if (y + popupHeight > winDocBody.offsetHeight)
y = wEvent.y - (popupHeight + winDocBody.scrollTop + 22);
else
y += winDocBody.scrollTop;
popupBody.style.border = "1px solid #333333";
// Show the popup.
popup.show(40, -80, popupWidth, popupHeight, document.body);
}
Finally, we output our calendar icon and add an <body id="TheBody">
<img src="Calendar.gif" width="16" height="15" style="cursor:hand"
onclick="ShowPopup()" title="Click to show calendar" align="absMiddle">
</body>
ConclusionThis 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 ResourcesDownloads and Demos
|
|||||||||||||||||||||||||||||||||||