Need Flex Migration Help?
- Adobe ends Flash player support in 2020
- Flex apps will no longer function
- We can help migrate your app
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:
- 6/23/2004
- 6-23-2004
- June 23, 2004
- Jun 23, 2004
- etc.
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"/>
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…
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
r0main
John –
there is nothing CF specific here, this is a pure flex 1.5 solution.
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,
This is a nice idea. But I did have some questions about it. Given that the dateField already has a TextInput component does the new one add one on top or override(replace) the previous one?
Another note regarding the use of mx:Canvas as a wrapper. If you try to set properties on the new component, wouldn’t they be ignored. Some of them might conflict with the Canvas wrapper as well. If you wanted to make a new component I think you will need to expose all of the properties of the dateField and set them.
Rodney –
bare in mind, this was a quickly cobbled together solution for flex 1.0. Without a doubt, you could achieve the same (or a better) alternative by subclassing the DateField. This was intended as a quick and dirty, low tech solution for those who were not comfortable creating components in AS2. In Flex2/AS3, i would not use the solution here, but would instead subclass DateField. If i ever get any free time, i may do just that, and post it back to my blog.
Jeff,
I understand. Like I said it is still a nice idea. In addition to helping folks using MXML it also give s you ideas and experience with the code. That can only help when you do have do have the time to tackle in through subclassing.