|
Someone was asking on the FlexCoders list today about having a date field, where clicking into the TextInput side allowed the user to type in a date, but still allowing them to click the calendar icon to open the DateChooser. While no component natively supports this, its pretty easy to cobble one together, which I just did. you can see it running here:
<?xml version="1.0" encoding="utf-8"?>
<mx:Canvas xmlns:mx="http://www.macromedia.com/2003/mxml">
<mx:DateField
id="dateField"
selectedDate="{_selectedDate}"
change="setDateFromCal(event)"
open="this.dispatchEvent(event)"
close="this.dispatchEvent(event)"
scroll="this.dispatchEvent(event)" />
<mx:TextInput
id="input"
text="{formatter.format(_selectedDate)}"
width="{dateField.text_mc.width}"
focusOut="setDateFromText(event)" />
<mx:DateFormatter id="formatter" />
<mx:Metadata>
[Event("change")]
[Event("open")]
[Event("close")]
[Event("scroll")]
</mx:Metadata>
<mx:Script>
<![CDATA[
import mx.formatters.DateFormatter;
var _selectedDate:Date;
function set selectedDate(dt:Date){
_selectedDate = dt;
}
function get selectedDate():Date{
return _selectedDate;
}
function setDateFromText(event){
dateField.selectedDate=DateFormatter.parseDateString(event.target.text);
var e:Object = new Object();
e.type = "change";
this.dispatchEvent(e);
}
function setDateFromCal(event){
_selectedDate=event.target.selectedDate;
this.dispatchEvent(event)
}
function parseDate(formattedDate:String):Date{
// for now, assuming mm/dd/yyyy
var aDateParts:Array = formattedDate.split("/");
var date:Date = new Date(aDateParts[2],Number(aDateParts[0])-1,aDateParts[1]);
return date;
}
]]>
</mx:Script>
</mx:Canvas>
When saved as DateTest.mxml, it can be tested like this:
<?xml version="1.0" encoding="utf-8"?>
<mx:Application creationComplete="initApp()" xmlns:mx="http://www.macromedia.com/2003/mxml" xmlns="*">
<DateTest id="dt" selectedDate="{today}" />
<mx:Script>
<![CDATA[
var today:Date;
function initApp(){
today = new Date();
}
]]>
</mx:Script>
</mx:Application>
While this is by no means complete, it does show how in just a few minutes new functionality can be introduced to existing components, which is a topic I'll be discussing at the upcoming Powered By Detroit conference.
A more complete version would mirror the API available from the DateField, but this gives the base functionality in a pretty easy to understand fashion. I've come back and added the four key events from the DateField to this, so it will now broadcast change, open, close and scroll.
A bit more reworking, I found the DateFormatter has a static method to parse a date string, so no need for my parse date method. In fact, the static method is far more effective than mine (mine required date be passed as mm/dd/yyyy), it will properly parse the date from a number of different strings, like:
11/28/06 update - As I was investigating implementing a similar solution for Flex 2, I found that the Flex 2 DateField component already has this built in, all you need to do is set editable="true"
<mx:DateField editable="true"/>
Hello,
pretty userful post...
(I simply had to add a
[ChangeEvent("change")] declaration in order to bind correctly FROM that
component)...
Your point on the parsing is okay, as far as you deal with
US style dates... French style isn't working (DD/MM/YYYY)... Why doesn't
the DateFormatter has a non-static method parse() that works with the
declared formatString property ?
Ciao, r0main
It would be convenient if that parseDateString were instance based and able
to use the formatString. Although, if thats what you need, it shouldnt be
too difficult to subclass DateFormatter...
Would you please translate this to ActionScript 2.0? I'm not using CF, and
this is something that I would like to do. Thanks.
Jeff,
Jeff,