In my current project on Flex, I came up with a requirement of customizing the current DateChooser control and add following functionalities:
add double clickable functionality for days and know which particular day is double clicked upon double clicked
allow user to drag day from the date chooser and drop over other controls as a date
By default the Flex 3 DateChooser control allows you to select a date, range of dates, or multiple dates. So i had to extend the default datechoose controls and after playing with the codes, i finally achieved what required. Lets have a look at the control first.
You can double click a day which will show you an alert saying which date is double clicked. You can even drag a day and drop over the list control on the right side which will eventually add the dropped date from the date chooser control. Lets have a look at the code now. The code below shows the custom datechooser class that extends the mx.controls.DateChooser which incorporates the behaviors i just discussed above.
package com.iprashant
{
import flash.events.MouseEvent;
import mx.controls.Alert;
import mx.controls.DateChooser;
import mx.controls.Image;
import mx.core.DragSource;
import mx.core.UIComponent;
import mx.core.UITextField;
import mx.core.mx_internal;
import mx.managers.DragManager;
use namespace mx_internal;
public class AdvancedDateChooser extends DateChooser {
private var recentMouseDownEvent:MouseEvent;
public function AdvancedDateChooser() {
super();
addEventListener(MouseEvent.MOUSE_UP, mouseUpHandler);
}
protected override function createChildren() : void {
super.createChildren();
var dateGrid:UIComponent = mx_internal::dateGrid;
dateGrid.doubleClickEnabled = true;
dateGrid.addEventListener(MouseEvent.DOUBLE_CLICK, doubleClickHandler);
dateGrid.addEventListener(MouseEvent.MOUSE_DOWN, mouseDownHandler);
dateGrid.addEventListener(MouseEvent.MOUSE_MOVE, mouseMoveHandler);
}
private function doubleClickHandler(event:MouseEvent) : void {
var dayNum:Number = Number(event.target.text);
if(event.target is UITextField && dayNum != 0) {
var dateDoubleClicked:Date = new Date(displayedYear, displayedMonth, event.target.text);
Alert.show("Double clicked date is: " + dateDoubleClicked.toDateString());
}
}
private function mouseUpHandler(event:MouseEvent) : void {
recentMouseDownEvent = null;
}
private function mouseDownHandler(event:MouseEvent) : void {
var dayNum:Number = Number(event.target.text);
dayNum = dayNum == 0?NaN:dayNum;
if(event.target is UITextField && !isNaN(dayNum)) {
recentMouseDownEvent = event;
}
}
private function mouseMoveHandler(event:MouseEvent) : void {
if(event.buttonDown && recentMouseDownEvent != null && !DragManager.isDragging && (Math.abs(recentMouseDownEvent.stageX - event.stageX) >= 5 || Math.abs(recentMouseDownEvent.stageY - event.stageY) >= 5)) {
var dragSource:DragSource = new DragSource();
var date:Date = new Date(displayedYear, displayedMonth, recentMouseDownEvent.target.text);
dragSource.addData(date, "date");
var imageProxy:Image = new Image();
imageProxy.source = dateImage;
imageProxy.height=16;
imageProxy.width=16;
DragManager.doDrag(UIComponent(event.currentTarget), dragSource, event, imageProxy, (event.currentTarget.x-event.target.x), (event.currentTarget.y-event.target.y) - 25, 1.00);
recentMouseDownEvent = null;
}
}
}
}
If you check the source code of the mx.controls.DateChooser, you will come to know that it arranges the days on the control in the datagrid. So I first fetched the reference of the DataGrid control used in the DateChooser which happens to be the mx_internal variable. mx_internal is a namespace used in Flex SDK for functions, variables likely to change in future releases. To know more about the mx_internal namespace, you can click here.
Have a look at the function createChildren() to find out how i obtained the reference of the dataGrid used in the DateChooser control and added a listner for the double click event on the data grid control of the date chooser. On the double click listener function, i check to see if the target of the event is the UITextField that is used to show the day. I fetch the text property from the target property of the double click event. Using the day on which double click occurs and the displayedYear and displayedMonth properties, i get the double clicked date.
For the draggable functionality of the date from the date chooser, have a look at the functions – mouseUpHandler, mouseDownHandler and mouseMoveHandler. To start the dragging, i used the combination of mouseMoveHandler and mouseDownHandler. The dragging starts only when mouse is down on the box used to show day and few pixels moved. You can check on the “if” condition inside the mouseMoveHandler to figure out how i achieved that.
To download the code click here.