package as_components
{
import mx.containers.HBox;
import mx.controls.ComboBox;
import mx.events.FlexEvent;
import mx.events.ListEvent;
import mx.formatters.DateFormatter;
[Bindable]
public class ComboBoxCodeBehind extends HBox
{
public var months:Array = new Array();
public var dateformatter:DateFormatter = new DateFormatter();
public var selectedIndex:int;
public var days:Array;
public var years:Array = new Array();
public var monthsCB:ComboBox;
public var daysCB:ComboBox;
public var yearsCB:ComboBox;
public var selectedIndexYear:int;
public var selectedIndexMonth:int;
public var selectedIndexDay:int;
public var thisYear:int;
public function ComboBoxCodeBehind()
{
super();
init();
this.addEventListener(FlexEvent.CREATION_COMPLETE, creationCompleteHandler);
}
private function init():void{
var i:int;
var now:Date = new Date();
var currentMonth:int = now.getMonth();
var currentYear:int = now.getFullYear();
var currentDay:int = now.getDate();
thisYear = currentYear;
dateformatter.formatString = "MMMM";
for (i=0; i<12; i++){
now.setMonth(i);
months[i] = dateformatter.format(now);
}
setYears(currentYear);
setDays(currentMonth);
selectedIndexMonth = currentMonth;
selectedIndexYear = years.indexOf(currentYear);
selectedIndexDay = days.indexOf(currentDay);
}
private function creationCompleteHandler(event:FlexEvent):void{
monthsCB.addEventListener(ListEvent.CHANGE,monthsHandler);
yearsCB.addEventListener(ListEvent.CHANGE, yearsHandler);
}
private function setDays(month:int):void{
days = new Array();
var i:int;
if (month == 0 || month == 2 || month == 4 || month == 6 || month == 7 || month == 9 || month == 11){
for(i=1; i<=31; i++)
days.push(i);
}else if (month == 3 || month == 5 || month == 8 || month == 10){
for(i=1; i<=30; i++)
days.push(i);
}else if (month == 1){
if (thisYear % 4 == 0){
for(i=1; i<=29; i++)
days.push(i);
}else{
for(i=1; i<=28; i++)
days.push(i);
}
}
}
private function setYears(year:int):void{
var j:int;
for(j=1950; j<=year; j++){
years.push(j);
}
}
private function monthsHandler(event:ListEvent):void{
setDays(event.currentTarget.selectedIndex);
selectedIndexDay = 0;
}
private function yearsHandler(event:ListEvent):void{
if (monthsCB.selectedIndex == 1){
var selectedDay:int = daysCB.selectedIndex;
thisYear = event.currentTarget.selectedItem as int;
setDays(monthsCB.selectedIndex);
selectedIndexDay = selectedDay;
}
}
}
}
A few corrections to this example:
1. In CodeExample.mxml, <local:CodeBehindForm /> should say <local:CodeBehindDisplay />
2. In Quan Li's solution above, if a user selects day '31' from a month with 31 days and then changes the month dropdown to a month with only 30 days, '31' will still be incorrectly shown in the day dropdown. An easier fix is to briefly change the day index to force a refresh on the displayed value:
private function monthsHandler(event:ListEvent):void{
setDays(event.currentTarget.selectedIndex);
selectedIndexDay = 1;
selectedIndexDay = 0;
}
3. A more subtle logic error in this example involves the month dropdown. Change your computer date to 31 July 2008. Then refresh this page and notice the month dropdown has no February month and two March months. This is because 'now' is a date with 31 days but when now.setMonth(i) is called in the init() function, setMonth tries to set the date to February 31st (which doesn't exist) so 'now' is converted to February 29th + 2 days which equals March 2nd so 'March' appears in the dropdown for February. To fix this, in the init() function, set 'now' to be the first day of the month:
for (i=0; i<12; i++){
now.setDate(1);
now.setMonth(i);
months[i] = dateformatter.format(now);
}
Subtle bug, eh?