Introduction
This article will explain how to utilize and implement the AsyncCalendar (from the highly anticipated AsyncControls Suite).
As with the other AsyncControls, the AsyncCalendar is AJAX enabled and comes with many enhancements not found in asp:Calendar or any other calendar control.
The AsyncCalendar boast the ability to render and receive events from any of the AsyncControls. Any AsyncDay can render any of the over 30 AsyncControls. This means that
you can literally have an AsyncPageRepeater, an AsyncSuggestBox, or an AsyncUserControl nested inside the AsyncDay. With the addition of having the most properties of all the other AsyncControls, it also has the most flexibility. It mimics the behavior of an AsyncPageRepeater and an AsyncUserControl. Adding to the many features of the AsyncCalendar, just by setting three properties, it can now be used to provide a �popup� calendar control.
The AsyncCalendar provides you with not only date entry abilities, but unlimited rendering capabilities as well. And I will try to touch on the most common ways of taking advantage of these features.
Implementing the AsyncCalendar (Standard Mode):
The AsyncCalendar by default is rendered using standard mode. This mode allows the calendar to be placed on the page just as any other control. It provides a more �open� layout. Using the calendar in standard mode allows you to lift the constraints of possible size.
Implementing the AsyncCalendar (Standard Mode):
1.) If you already have an asp:Calendar on the page:
- Just rename it to AsyncCalendar and you�re done. Luckily the AsyncCalendar supports most of the commonly used properties.
2.) If you are creating a calendar from scratch:
ASPX
<dw:AsyncCalendar runat="server" ID="asyncCal" Width="600"
AbbreviateDays="false" DefaultStyle="false"
YearListCssClass="calYearList" MonthListCssClass="calMonthList"
YearSelectorCssClass="calYearSel" MonthSelectorCssClass="calMonthSel"
CssClass="asynccal" DayCssClass="calday" WeekendDayCssClass="weekendcal"
OtherMonthCssClass="othermonthcal"
ShowGridLines="false" ShowTodayFooter="true"
PreviousMonthText="<<" NextMonthText=">>"
OnDayRender="cal_DayRender" OnDaySelected="cal_DaySelected"
SelectedDayCssClass="selDay" ShowOnTextClick="true"
IsIconic="false" AssociatedTextBox="calTxt" IconImageUrl="images/calicon.jpg">
<dw:AsyncDay runat="server" ID="day1">
<div align="right"><dw:AsyncLiteral runat="server" ID="calLtlDate" /></div>
<span style="font-size: 9px;">
Users scheduled for today.
</span>
<dw:AsyncPageRepeater runat="server" ID="calRpt" CssClass="calRpt"
PagingComponentCssClass="calRptPaging" RangeOfTextFormat="" RangeCurrentPageTextFormat="<b><{0}></b>"
PageSize="3" MaxItemCount="10" OnItemDataBound="calRpt_ItemDataBound"
NextPageComponentText="" PreviousPageComponentText="">
<HeaderTemplate>
<table>
</HeaderTemplate>
<ItemTemplate>
<tr>
<td><span style="font-size: 10px;"><img src="images/misc/ac_user.jpg" /><dw:AsyncLiteral runat="server" ID="calRptLtl" /></span></td>
</tr>
</ItemTemplate>
<FooterTemplate>
</table>
</FooterTemplate>
</dw:AsyncPageRepeater>
</dw:AsyncDay>
</dw:AsyncCalendar>
Code Behind (CS)
protected void cal_DayRender( object sender, AsyncDayRenderEventArgs ae )
{
if ( ae.IsToday )
{
calLtlDate.Text = ae.DayNumberText;
calRpt.DataBind(GetUsers());
ae.Day = day1;
}
if ( ae.Date.DayOfWeek == DayOfWeek.Wednesday && !ae.IsOtherMonth )
{
Control c = this.LoadControl("~/Controls/CalendarUserControl.ascx");
AsyncDay day = new AsyncDay();
day.ID = "tempDay";
c.ID = "tempID";
day.Controls.Add(c);
ae.Day = day;
}
if ( ae.IsOtherMonth )
{
ae.Html = " ";
}
}
Implementing the AsyncCalendar (Iconic Mode):
<dw:AsyncTextBox runat="server" ID="calTxt" />
<dw:AsyncCalendar runat="server" ID="tinyAsyncCal"
AbbreviateDays="true" AbbreviateMonths="true"
ShowGridLines="false" ShowTodayFooter="true"
PreviousMonthText="<<" NextMonthText=">>"
TodayCssClass="selDay" ShowOnTextClick="true" VisibleDateFromTextBox="true"
IsIconic="true" AssociatedTextBox="calTxt" IconImageUrl="images/calicon.jpg"
YearListCssClass="calYearList" MonthListCssClass="calMonthList"
YearSelectorCssClass="calYearSel" MonthSelectorCssClass="calMonthSel"
TodayFooterCssClass="calTodayFooter" CssClass="iconCal"
DayCssClass="iconCalDay" OtherMonthCssClass="iconCalOtherMonth"
WeekendDayCssClass="iconCalWeekend" DefaultStyle="false" />
The AsyncCalendar also allows you to quickly and easily implement date entry for the a text box in an AsyncRepeater or just on the page.
To implement the AsyncCalendar in Iconic Mode set
AsynCalendar.IsIconic to true, set
AsyncCalendar.IconImageUrl to a target image, or set
AsyncCalendar.IconText to the desired display text. And last set
AsyncCalendar.AssociatedTextBox to the ID of the AsyncTextBox you wish to display the date selected.
This mode will force the AsyncCalendar to hide initially, the upon activation it will visibly float itself near either the IconText or the image shown by IconImageUrl. The AsyncCalendar can be activated by the user if they click on the AssociatedTextBox, the IconText or the icon image. The AsyncCalendar can also display the date input by the user. So if the user types in a date and activates the calendar it will �jump� to the specified date. No validation is required.
The AsyncCalendar is still fully customizable in this mode. So you can literally swap between Standard and Iconic mode without any code changes.
AsyncCalendar Notes:
Depending on the purpose or objective of the calendar you may need to utilize some of the other properties or methods provided by the AsyncCalendar. Unfortunately I don�t know your intentions so I can�t target this section at a certain scenario, but I can however describe the properties and methods that you may find most useful.
1.) �Weekday Text� properties are very useful if you really want to customize the days display text for the calendar. If
AsyncCalendar.AbbreviateDays is not what you need, you have the ability to set the text for each day of the week. You can set FridayText = �HappyDay� and MondayText = �StartDay� or anything you want. Each day can have its own text. A common use may be to minimize the day text real estate by showing only the first letter of each day.
2.) �Month Text� properties will allow you to customize the month text displayed for every month (of the Gregorian calendar). If
AsyncCalendar.AbbreviateMonths is not what you need, you can set AugustText = �GreatMonth� and SeptemberText = �Sept.� Each month can have its own text display.
3.) SelectionMode, if set to �Multiple�; it will allow the user to select multiple dates on the calendar. It will also change the CSS class of the corresponding day, if SelectedDayCssClass is set. Use
AsyncCalendar.SelectedDates to get the dates selected by the user.
4.) The �Month and Year Selectors� which are available in both standard and iconic mode, can be fully customized or removed. Set Show*Selector to hide/show the month or year selector. And use *SelectorCssClass to assign a CSS class to either the month or year selector.
5.) Using the Show* methods will allow you to programmatically �jump� to different dates. You can use
ShowNextMonth(),
ShowPreviousMonth(),
ShowToday(), and the favorite
ShowDate(DateTime). These of course are Async-Enabled, and can be used during an AsyncCallback.
6.) The use of
UpdateCalendar() is a little advanced. Since not all changes to the calendar are Async-Enabled, you may have to �force� the calendar to render the changes to the client. For example, you should invoke this method if you alter the SelectedDates collection (during an AsyncCallback); or if you set
AsyncCalendar.VisibleDate (because you chose not to use ShowDate(DateTime)).
Keep in mind that the AsyncCalendar (and some AsyncControls) render their default styles unless DefaultStyle is set to false.
Using AsyncCalendar Events:
1.)
CalendarChanged, occurs when the user either selects a month or year from the selector, or if they navigate using next and previous month.
2.)
DayMouseOver, occurs when the user�s mouse enter the bounds of an AsyncDay.
3.)
DayMouseOut, occurs when the user�s mouse exits the bounds of an AsyncDay.
4.)
DaySelected, occurs when a user clicks or selects an AsyncDay.
5.)
DayRender, occurs when an AsyncDay is being rendered.
DayMouseOver, DayMouseOut, and DaySelected events will not occur if you change the AsyncDay either by assigning an AsyncDay or by setting the HTML.
AsyncCalendar.DayRender event:
This event requires it�s own section simply because it is one of the most complex and advanced events to respond to.
DayRender is very, very powerful; in terms of calendar appearance. Based on what you render to an AsyncDay you may effect the performance of the AsyncCalendar. With the default render, the bottom level server will still render the calendar to the user almost instantly. Each month/year change will be reflected back to the user as soon a they click it. This is a definite advantage for you, because you�re not starting with a slow engine. In respects to AsyncUserControls and their ability to ease the creation of AsyncDays, I recommend using them. But you can just as easily use any other AsyncControl you want.
The AsyncDay is its own tag/class. You can use it on the front end or create an instance of it (in the code behind), and add controls to it dynamically.
Implementing an AsyncDay:
If you choose to dynamically create the AsyncDay (the code behind):
You must also explicitly add it to the corresponding AsyncCalendar (and don�t forget the add the child controls). You can do this by setting
AsyncDayRenderEventArgs.Day to the instance you created.
Example (during DayRender event):
Control userCtrl = this.LoadControl("~/Controls/CalendarUserControl.ascx");
AsyncDay newDay = new AsyncDay();
newDay.ID = "tempDay";
userCtrl.ID = "tempID";
newDay.Controls.Add(userCrtl);
asyncDayRenderEventArgs.Day = newDay;
If you choose to create a static AsyncDay (the front end):
<dw:AsyncDay runat="server" ID="staticDay1" Date="8/13/2007">
<!-- AsyncControls I want to be rendered on this day -->
<dw:AsyncDay>
You simply use the AsyncDay as you would any other AsyncPanel, placing all child controls within the AsyncDay inner area. You may wish to set
AsyncDay.Date to the related date, and during the DayRender the AsyncDay will be rendered for you. The day set on the front end will remain, so if you assign the AsyncDay to another date, it will still render on both days.
Keep in mind placing other AsyncCalendars or even entire web pages within an AsyncDay may not be the best idea, don�t forget the user has to download all that content.
Conclusion
The AsyncCalendar is a "new breed" of calendar, one without restrictions. With this calendar control you actually have control. Build a calendar based application with the speed of AsyncControls and unlimited abilities. What you can put on an ASPX page you can now render into a calendar day with ease.
Additional Links/References
AJAXForASP.Net has a demo of the AsyncCalendar discussed in this article along with a list of the other 30+ AsyncControls. Also you can check out the
AsyncPageRepeater Tutorial.