DataCalendar

The DataCalendar is a combination of DateChooser and DataGrid. Like the DateChooser, the DataCalendar displays a standard calendar with controls to navigate to another month and year. And like the DataGrid, the cells of the DataCalendar display data.

Also similar to the DataGrid, the DataCalendar uses itemRenderers – either the default ones I’ve included with the package, or ones you create. The image below shows an example using custom itemRenderers and skins.

A long time ago I helped a friend of mine who owns a nightclub write an application which lets her booking manager create an online calendar of the bands performing at her nightclub. The central part of this application is the calendar which displays the bands playing each night, along with any notes and ticket information. I wrote all of that using PHP and I’ve been meaning to, over the years, write it again in Flex. The only thing holding me back was the calendar.

The DateChooser is fine to pick dates, but you cannot display anything other than the date in the calendar. The DataGrid is also fine but I needed something a bit more flexible. So I finally sat down, planned it out, and came up with the DataCalendar.

See a demo of DataCalendar here

The demonstration is of the nightclub booking tool. The information is stored in XML files and is available for the months of Dec 2007 through Feb 2008; I haven’t modified the program to create new months, but feel free to experiment with the code on your own.

Screen shot of the BookingTool

View Documentation

In hindsight, you can probably do this with the DataGrid. Once I had it planned I wanted to see it through, but if you wanted to do something similar with the DataGrid, I believe you could.

Source Code

These ZIP files are Flex 3 Beta 3 project archives.

DataCalendar Flex Library. This is the source to the DataCalendar control and supporting classes.
Test Application. This is the source to the test applications, including the BookingTool (above).

DataProvider

To use the DataCalendar you need a special data provider. I had toyed around with using the conventional ArrayCollection and XMLListCollection classes, but the more I thought about how someone would use this control, the more I thought I needed something specialized. When you look at a calendar, what do you see? Dates, right? And wouldn’t it make sense to orient the data to the dates of the calendar?

My first thought was to include the day of the month as one of the fields: {day:18, value:"Tim’s Birthday"}, {day:4, value:"Big Meeting"}, and so forth. The problem with this is that you have to repeatedly search through the collection for the information on a particular day. In this example, the information for the 4th comes after the information for the 18th. I could do a one-time pass and create a mapping, but that seemed like too much work and could have issues with data binding events.

Instead, I created the DataCalendarDataProvider class. The class implements ICollectionView, but it allows data to be assigned by day. For instance:

var januaryData:DataCalendarDataProvider = new DataCalendarDataProvider();
januaryData.addItemAt( 18, {value:"Tim's Birthday});
januaryData.addItemAt( 4, {value:"Big Meeting"});

The DataCalendarDataProvider class allocates 32 slots – slot 0 is not used – so each slot corresponds to a day of the month.

Certain properties such as sort and functions such addItem() do not make sense for a calendar, so those will throw exceptions if used.

Layout

The calendar is a grid of 7 columns and 6 rows (to accomodate those months which require 6 weeks, eg. March 2008). Regardless of the width, the DataCalendar makes all of the week day columns the same size. If you specify an explicit height the DataCalendar also makes all of the week rows the same height. However, if you do not specify a height, then the DataCalendar will allow each week row’s height to be different from the others, using the content of the day cells to determine a week row’s maximum height.

Renderers

I wanted this control to be as flexible as possible, so I gave it the ability to use itemRenderers. There are several renderers you can change:

itemRenderer: This is the renderer for the contents of a day cell. The default (DataCalendarItemRenderer) renderer takes the contents and displays it in a Text field. The BookingTool demonstration uses a complex itemRenderer. You can also add video and audio. Imagine showing the most popular YouTube™ video for each day of the month.
todayRenderer: This renderer displays the indicator for the day cell representing the current date. The default renderer simply displays the DataCalendarTodaySkin.
dayNumberRenderer: This renderer displays the date in the day cell. The default (DataCalendarDayNumberRenderer) displays the numerals for the date in the upper right corner of each day cell.
dayNameRenderer: This renderer displays the name of the day of the week across the top of each week day column. The default is DataCalendarDayNameRenderer.

Skins

I also wanted the control to have a great deal of flexability when it came to its look, so there are also a number of skins you can change:

DataCalendarDayNameSkin: the skin used for the background of the week day names.
DataCalendarDayNumberSkin: the skin used for the background of the dates for each day of the month (day cell).
DataCalendarSkin: the skin used for the background and border of the DataCalendar control.
DataCalendarTodaySkin: the skin used to show the indicator for the current day.

Version 2.0

Of course, once you finish a project you think about things you’d like to add or change. I may never get to this, but I can think of some "enhancement requests":

  • Scrolling like the DataGrid. That is, keep the DataCalendar’s title area and day names fixed in place and just scroll the day cells.
  • Selecting by day of the week. This would allow you to select all of the Mondays, for instance.
  • Adding itemEditor capability. This might make the BookingTool even easier to use.
  • Starting the week on some day other than Sunday. A typical business week begins Monday, for example.
  • Items which span rows or columns. For example, a vacation over a long weekend.