Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / web / HTML

Calendar UI Extender Control

4.00/5 (3 votes)
10 Oct 20075 min read 1   1.2K  
An AJAX calendar extender control that implements a highly customizable UI and a WYSIWYG designer preview

Summary

The standard ASP.NET calendar control while useful, does not have the hooks to customize title date displays. Furthermore, the control model is not flexible enough to allow extension through sub-classing. I have implemented an AJAX control extender (CalendarUIExtender) that exposes a rich API for fine-grained control over title date and day header displays. Unlike extenders in AjaxControlToolkit, this extender's target control is the standard ASP.NET Calendar control and it is intended to enhance the UI capabilities of the Calendar control. It features bit flag enumerations with the ability to turn specific date components on or off, customization of the order of rendering of date components, custom prefix and suffix, auto-generation of date suffix (such as 1st, 2nd, 12th), auto-formatting, date display behavior (today's date in current month view, today's date always, selected date, etc.), custom day headers and so on.

The final date output is computed from bitwise specifications using the DateExpressionBuilder utility class. DateExpressionBuilder is the heart of the formatting engine which uses an algorithm that I came up with along with a series of utility functions, to compute a custom date format pattern that is used as an argument to DateTime.ToString. The CalendarUIExtender control implements a JavaScript prototype that handles client-server property synchronization and also client side rendering using DHTML and JavaScript. The output generated by the extender is delivered to the JavaScript prototype which parses the HTML output generated by ASP.NET Calendar and substitutes specific regions of the output to render customized date title and day header specifications. Please refer to the section on rendering for details.

The extender control features a rich UI designer that enables control configuration through region-specific action lists. It also features smart tag functionality, so that the user can preview the rendered output in the Visual Studio design view.

Usage

The snippet below shows one of the ways to customize day headers and title date rendering. However, it is preferable to use the rich design time rendering capabilities of the CalendarUIExtender's designer to visually generate these settings.

XML
<cc1:CalendarUIExtender ID="CalendarUIExtender1" 
    runat="server" EnableViewState="true"
    TargetControlID="calTest"
    TitleDateDisplayBehaviour="UserDefinedPrefixSuffixBehaviour"
    TitleDateDisplayOrder="DayOfWeek_Date_Month_Year"
    TitleDateValueBehaviour="TodayAlways"
    TitleDateDayOfWeekSuffix=", "
    TitleDateYearPrefix=", "
    DayHeaderFormat ="Custom"
    CustomDayHeaders="Sun,M,Tu,W,Th,F,Sat" >
</cc1:CalendarUIExtender>

Title Date and Day Header Rendering Customization

CalendarUIExtender implements a WYSIWYG designer that supports smart tags, regions and region-specific action lists. The following is a set of screenshots that show the extender control in action.

Control Rendering in the Visual Studio Designer

Visual Studio Designer Support

Control Rendering in the Browser

Example 1

Custom User Phrases can be Combined with Auto-Generated Date Suffixes
(e.g. 12th, 22nd)

Example 2

Structure of the Calendar Extender Control

The code and logic of this control and its utilities is complex and extensive. I don't intend to write an elaborate article on this. Please refer to the source code if you are curious about the working of components under the hood.

CalendarUIExtender Classes

DateDisplaySpec is a bitwise enumeration (Flags enum) that can be XORed to turn specific bits on or off, along with other typical bitwise operations such as OR.

Enum Operations

The following classes implement rich Visual Studio designer preview features (context menu with smart tags and region specific action lists).

CalendarUIExtender Designer Classes

Behavior Modes

Title Date behavior modes:

C#
public enum DateDisplayBehaviour
{
    ASPNetCalendarSetting,
    DefaultPrefixSuffixBehaviour,
    UserDefinedPrefixSuffixBehaviour
}

public enum DateValue
{
    ASPNetCalendarSetting,
    TodayAlways,
    TodayOnlyInCurrentMonth,
    SelectedDate,
    VisibleDate
}

public enum DateDisplayOrder
{
    DayOfWeek_Month_Date_Year,  // Sunday Jan 23 2007
    DayOfWeek_Date_Month_Year,  // Sunday 23rd Jan 2007
    Year_Month_Date_DayOfWeek   // 2007 Jan 23 Sunday
}

Day Header behavior modes: format of day header names. When the format value is Custom, the TitleDayHeader property is set to a comma-separated list of header names.

C#
public enum DayHeaderFormat
{
    ASPNetCalendarSetting,
    OneLetterDay,
    TwoLetterDay,
    ThreeLetterDay,
    FullName,
    Custom    // allows custom names for day headers
}

Bitwise flags allow fine-grained control over individual attributes of the title date and day header display.

C#
[Flags]
public enum DateDisplaySpec : int
{
    None                            =   0,
    YearPrefix                      =   0x01,
    YearSuffix                      =   YearPrefix<<1,
    Year4Digits                     =   YearSuffix<<1,
    Year2Digits                     =   Year4Digits<<1,
    MonthPrefix                     =   Year2Digits<<1,
    MonthSuffix                     =   MonthPrefix<<1,
    MonthNumericAnyDigits           =   MonthSuffix<<1,
    MonthNumeric2Digits             =   MonthNumericAnyDigits<<1,
    MonthFullWord                   =   MonthNumeric2Digits<<1,
    Month3LetterAbbreviation        =   MonthFullWord<<1,
    DatePrefix                      =   Month3LetterAbbreviation<<1,
    DateSuffix                      =   DatePrefix<<1,
    DateSuffix2Letter               =   DateSuffix<<1,
    DateAnyDigits                   =   DateSuffix2Letter<<1,
    Date2Digit                      =   DateAnyDigits<<1,
    DayOfWeekPrefix                 =   Date2Digit<<1,
    DayOfWeekSuffix                 =   DayOfWeekPrefix<<1,
    DayOfWeekNumeric                =   DayOfWeekSuffix<<1,
    DayOfWeekFullWord               =   DayOfWeekNumeric<<1,
    DayOfWeek3LetterAbbreviation    =   DayOfWeekFullWord<<1
}

Layered Rendering

  1. The ASP.NET calendar control renders table markup.
  2. The extender's JavaScript prototype parses the target ASP.NET calendar control's HTML output and replaces the content of the title date cell and the 7 day header cells. If the extender is configured to mimic ASP.NET calendar behavior, then the prototype rendering is by-passed. This allows the standard calendar output to be rendered as-is.

Differences w.r.t. AjaxControlToolkit CalendarExtender

Header CalendarExtender My control

Use case

Meant to be a pop-up calendar with an event-driven trigger to show or hide the calendar.

Meant to be an always-on calendar on a webpage.

Functionality

Implements a date picker functionality.

Does not implement a behavior that's different from the ASP.NET calendar control. It's meant to be a UI enhancer. However, it adds some additional behavior to the calendar control that is UI-specific.

Target

Targets another control (textbox, drop-down, etc).

Targets the ASP.NET calendar in the same naming container (by default).

Model

A JavaScript rewrite of the ASP.NET calendar functionality, including model (SelectedDate, VisibleDate, style, etc). The prototype implements all the calendar logic.

Not meant to be a JavaScript calendar (it can always be AJAX-ified by wrapping the ASP.NET calendar in an update panel).

Reuses the ASP.NET calendar model as well as implementation and injects its model and implementation transparently at runtime.

Styles

Calendar styles are set in style sheet classes. Not trivial unless the developer is aware of advanced HTML style concepts.

Reuses the ASP.NET calendar style properties. Developer can easily define styles through the ASP.NET calendar control designer.

Designer preview

Designer does not render design time preview in Visual Studio.

The extender has a designer that renders a preview of title date and calendar day headers by applying styles defined for the ASP.NET calendar control.

The designer implements regions and region-specific smart tags.

When the extender is in mode, the designer renders ASP.NET calendar day headers using reflection.

Title Date Format

The Format property is defined using DateTime format grammar. There is no preview available at design time. It is not simple to the average developer.

Defines bit flag enumeration and properties for each date component.

Enables out-of-the-box coarse-grained, as well as fine-grained, configuration.

The designer preview in Visual Studio makes it easy to configure.

The DateExpressionBuilder class is the engine that computes the final result by translating user-defined and automated behavior into DateTime format specs.

Adding custom phrases is not simple for the average developer.

Can be done in the designer without requiring knowledge of DateTime format specs for custom phrases.

Auto-generates date suffixes (if enabled). For ex. 21st, 11th, 22nd, 3rd, 13th

Dynamic title date

Title date is static based on the Format property

Allows dynamic title date behavior:

  • ASPNetCalendarSetting
  • TodayAlways
  • TodayOnlyInCurrentMonth (when user shifts to a different month, it displays visible date in the format specified; otherwise, today's date)
  • SelectedDate
  • VisibleDate

Day Headers

Does not allow day header customization

Allows single letter, 2-letter, 3-letter, full name, as well as custom names for day of week headers in the day header row.

History

  • September 26, 2007 -- Original version posted

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here