Posted by: rouse in MyBlog on Oct 28, 2009
A couple weeks ago another developer, Corey Losenegger, and I were faced with a Flex project that required the user to select a week. A combination of drop downs for year and week seemed awkward, so we ended up trying to augment Flex's DateChooser. There were two main parts to this task, getting a single day selection to transform into a week automatically, and secondly to get the calendar to show that it was going to select a week instead of a day. You can view our source, but there are no guarantees on code quality. Use at your own risk.
1. Transform single day selection into a week selection
For the week transformation, we found a post on Fusioncube and built our solution around it.
Corey and I ended up extending the DateChooser because we wanted to be able to tinker with some deeper elements (a.k.a. hack with possibly protected properties). This could have been a little more compositional, but I don't want to imply that what we were doing was all that flexible, or not as deeply bound to the DateChooser as it actually is. Corey took the core of the Fusioncube code and added an event to dispatch from the component as well as updating the actual selected elements of the DateChooser to reflect the selection. Incidentally, the use of constants in the Fusioncube code is cool:
private static const millisecondsPerMinute:int = 1000 * 60;
private static const millisecondsPerHour:int = 1000 * 60 * 60;
private static const millisecondsPerDay:int = 1000 * 60 * 60 * 24;
2. Show the week selection in the calendar component
The second part of the task is to update the display so that it is apparent to the user that a week is going to be selected. To start, I had to figure out where I could draw the week highlight bars. I decided on the dateGrid (just the area that has the numbers and the week headers "M","T", etc). The x,y coordinates would be relative to the grid itself. More importantly, when I tried drawing onto the DateChooser itself, nothing showed up. The background of the component is rendered on top of the root component's graphics object. I found the dateGrid by hacking into the list of children since it is a private variable within the DateChooser itself. Not pretty, but everything is bound so tightly I didn't see another way around it. From there, I hooked into the start and end date provided by Corey's work and figured out where my week highlight block andthe selected week box should be rendered.
Caveats
It's always interesting to customize the Flex components because it usually leads to ugly hacks much too quickly. It reveals how tightly packaged they are and what little changes could have been made to make the process considerably easier. For starters, composing elements would be extremely useful. The DateChooser, in particular, is a perfect candidate for using MXML with encapsulated elements such as title, back/forward buttons, and the calendar with bindings between them. An only AS-based version could be created for the purists without too much hassle. For this project, it would have sped up the process of understanding the component considerably to use MXML because it would have given a better visual expression of where elements were and forced better encapsulation of the sub-elements.