<code>
<?xml version="1.0" encoding="utf-8"?>
<s:HGroup xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
creationComplete="init()">
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<fx:Script>
<![CDATA[
import com.amdocs.infra.utils.FlexFormatters;
import mx.collections.ArrayCollection;
import mx.controls.DateField;
import mx.events.CalendarLayoutChangeEvent;
import mx.events.FlexEvent;
import mx.formatters.DateFormatter;
import mx.utils.StringUtil;
import spark.events.IndexChangeEvent;
private var arr:ArrayCollection = new ArrayCollection();
private var date:Date;
private var selecteDate:Date = new Date();
public var dateChanged :Boolean;
[Bindable]
private var timezone:String;
[Bindable]
public function get selectedDate():Date
{
if(dateChanged)
return date;
else
return selecteDate;
}
public function set selectedDate(value:Date):void
{
if(value.toString()!= null)
{
selecteDate = value;
var dateformatter:DateFormatter = new DateFormatter();
dateformatter.formatString = "MM/DD/YYYY L:NN:SSA";
var dateStr:String = dateformatter.format(value).substr(0,10);
var dateArray:Array = dateStr.split("/");
dateInput.selectedDate = new Date(dateArray[2],dateArray[0]-1,dateArray[1]);
timeInput.selectedItem = dateformatter.format(value).substr(11,10);
dateStringLabel.text = FlexFormatters.getDateTimeFormatter({ dateTimePattern: "EEEE, MMMM dd, yyyy h:mm:ss a" }).format(value);
dateChanged = false;
timezone = TimeZoneUtil.getTimeZone();
}
}
protected function formatTime():void
{
var rawTimeString:String;
// If the combobox has a custom value, hten use the selectedItem. Otherwise, use the selectedItem.value
if (timeInput.selectedIndex == ComboBox.CUSTOM_SELECTED_ITEM)
rawTimeString = StringUtil.trim(timeInput.selectedItem).toUpperCase();
else if (timeInput.selectedIndex != -1)
rawTimeString = StringUtil.trim(timeInput.selectedItem).toUpperCase();
// look for AM or PM at end of the timestring
var amPm:String = "";
if (rawTimeString.substr(-2) == "AM" )
amPm = "AM";
else if (rawTimeString.substr(-2) == "PM" )
amPm = "PM";
// Split time by colons
var timeArr:Array = StringUtil.trimArrayElements(rawTimeString.replace(amPm, ""),":").split(":");
var hour:int = 0;
var minute:int = 0;
var second:int = 0;
// determine the hour/minute/second from the array
if (timeArr.length >= 2)
{
hour = timeArr[0];
minute = timeArr[1];
second = (timeArr.length == 3 ? timeArr[2] : 0) ;
}
else
{
trace("Error parsing time (" + rawTimeString + "). Defaulting to midnight");
}
// If it is an AM time and hour is 12 (midnight) then set the hour to zero)
if (amPm == "AM" && hour == 12)
hour = 0;
// add 12 hours if the hour is between 1 and 11
else if (amPm == "PM" && hour >=1 && hour <= 11)
hour = hour + 12;
// If hours, minutes, or seconds exceed what they should be, then
// calculate how many days/hours/minutes should be added to the final date
// and determine the final hour/minute/second
if (second >= 60)
{
minute += Math.floor(second/60);
second = second % 60;
}
if (minute >= 60)
{
hour += Math.floor(minute/60);
minute = minute % 60;
}
var addedDays:int = 0;
if (hour >= 24)
{
addedDays += Math.floor(hour/24);
hour = hour % 24;
}
var timeString:String = lpad(hour,2,"0") + ":" + lpad(minute,2,"0") + ":" + lpad(second,2,"0");
var dateString:String = FlexFormatters.getDateTimeFormatter({ "dateTimePattern": "yyyy-MM-dd" }).format(dateInput.selectedDate);
// Create date from final dateString/timeString
date = DateFormatter.parseDateString(dateString + " " + timeString);
// Add days to the final date if needed
if (date != null && addedDays > 0)
date.setDate(date.getDate() + addedDays);
//dateValueLabel.text = (date != null?date.toString():null);
dateStringLabel.text = FlexFormatters.getDateTimeFormatter({ dateTimePattern: "EEEE, MMMM dd, yyyy h:mm:ss a" }).format(date);
dateChanged = true;
}
// helper function to add a leading zero to hour/minute/second
private function lpad(number:int, width:int, padChar:String = " "):String
{
var ret:String = ""+number;
while( ret.length < width )
ret=padChar + ret;
return ret;
}
private function init():void
{
for each (var ampm : String in ["AM","PM"])
{
for(var i :int = 0;i<12;i++)
{
var hours:int = (i == 0?12:i);
for each(var minutes : String in ["00","30"])
{
var item:Object = hours+":"+minutes+" "+ampm;
arr.addItem(item);
//trace(hours+":"+minutes+" "+ampm);
}
}
}
timeInput.dataProvider = arr;
}
protected function timeInput_changeHandler(event:IndexChangeEvent):void
{
if (timeInput.selectedIndex!= ComboBox.CUSTOM_SELECTED_ITEM)
{
timeInput.selectedItem = String(timeInput.selectedItem).replace(" ",":00");
}
// TODO Auto-generated method stub
if(dateInput.selectedDate!= null)
formatTime();
}
protected function dateInput_changeHandler(event:CalendarLayoutChangeEvent):void
{
// TODO Auto-generated method stub
if(timeInput.selectedItem!= null)
formatTime();
}
]]>
</fx:Script>
<fx:Declarations>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:VGroup>
<s:HGroup>
<mx:DateField id="dateInput" change="dateInput_changeHandler(event)"/>
<s:ComboBox id="timeInput" labelField="value" initialize="timeInput_initializeHandler(event)" click="timeInput_clickHandler(event)" change="timeInput_changeHandler(event)"/>
<s:Label text="{timezone}" paddingTop="8"/>
</s:HGroup>
<s:Label id="dateStringLabel"/>
</s:VGroup>
</s:HGroup>
</code>
上面的代码是一个日期时间选择器,用户可以在其中以(hh:mm:ssam/pm)格式选择任何日期和时间。
当用户双击网格时,将调用此日期时间选择器。网格中有一列称为“选定日期”的列。从Beckend获取的值按日期和时间差异进行分解,并分配给DateField和Time to Combox。
客户希望Combox按以下方式工作:
假设所选日期字段是12/12/12 4:20:15 AM,如果用户单击下拉菜单,则下拉菜单不应每次从12:00 AM开始,而应从最近的即将到来的时间开始,如时间4:20:15 AM,它应从4:30:00 AM开始,为7:50:12 AM,它应从8:00 AM开始
请告知
最佳答案
因此,您在timeInput.dataProvider中有一些数据,所以我认为干净的解决方案是在这个数据提供程序中找到想要的项(比如用“4:30”表示的值),然后将其设置为selectedItem(或者index to selectedIndex),这将使下拉列表在打开时滚动到此项。
你可以手动(编程)滚动一个事件的下拉列表,但它的工作多一点,也许还需要创建自定义组合框(我不得不自己说),但我还是会调用这个“不太干净”的解决方案来添加这个功能。。。
关于java - 如何将组合框的光标设置为特定索引?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21162580/