• Flex自定义组件开发之日周月日期选择日历控件


            使用过DateField的我们都知道,DateField 控件是用于显示日期的文本字段,字段右侧带有日历图标。当用户在控件边框内的任一位置单击时,将弹出一个 DateChooser 控件,显示当月的所有日期。如果未选择日期,则该文本字段为空白,并且 DateChooser 控件中将显示当前日期的月份。当 DateChooser 控件处于打开状态时,用户可以在各个月份和年份之间滚动,并选择某个日期。选择日期后,DateChooser 控件关闭,文本字段将显示所选的日期。而在我们的业务过程中,很多时候我们需要选择的日期不仅仅是某天,可能还需要的是某些时间段,比如说一周,一个月,这是DateField就满足不了我们的需求,它提供的只是对某个日期的选择。这时候就需要我们进行自定义组件的开发了。而这个突破口就在DateChooser ,DateChooser控件显示月份名称、年份名称,并显示包含当月的所有日期的网格(每列标有对应的星期日期)。用户可以选择一个日期、某个日期范围或者多个日期。此控件包含前进和后退箭头按钮,用于改变年份和月份。您可以允许用户选择多个日期,禁止选择特定日期和只限于显示某个日期范围。DateChooser的这些特性满足了我们的需求,因此我们可以利用它进行我们所需要组件的开发。下面先看一小效果实现图(鼠标点击):
     
     我们可以看下包结构:
    首先是对控件的主体DateWeekMouthDateField.mxml进行分析,代码如下
    <?xml version="1.0" encoding="utf-8"?>
    <s:BorderContainer xmlns:fx="http://ns.adobe.com/mxml/2009" 
                       xmlns:s="library://ns.adobe.com/flex/spark" 
                       xmlns:mx="library://ns.adobe.com/flex/mx" 
                       width="100%" height="100%" backgroundAlpha="0"
                       borderVisible="false"
                       buttonMode="true" useHandCursor="true"
                       creationComplete="init();"
                       click="popUpButton.open();">
        
        <fx:Style source="css/tabNavigator.css"/> 
        <fx:Script>
            <![CDATA[
                import DateField.component.DateChoosers;
                import DateField.event.DateFieldChooseEvent;
                
                [Embed(source="DateField/images/leftIcon.png")]
                private var leftIcon:Class;
                [Embed(source="DateField/images/rightIcon.png")]
                private var rightIcon:Class;
                public var dateChoosers:DateChoosers = new DateChoosers();;
                /**
                 * 初始化导航菜单组
                 * */
                private function init():void
                {    
                    
                    var date:Date = new Date();
                    var dateString:String = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                        + date.getDate();
                    dateSlectLabel.text = dateString;
    //                dateChoosers.dateLabel = ["日","周","月","年"];
    //                dateChoosers.dateLabel = ["日","周"];
                    popUpButton.popUp = dateChoosers;
                    
                    /* open it just for initialize. */
                    popUpButton.open();
                    popUpButton.close();
                    dateChoosers.addEventListener(DateFieldChooseEvent.DATE_SELECTED,dateSelectedHandler);
                }
                
                protected function dateSelectedHandler(event:DateFieldChooseEvent):void
                {
                    // TODO Auto-generated method stub
                    dateSlectLabel.text = event.vEventResult;
                    popUpButton.label = event.vEventResult;
                    popUpButton.close();
                }
                
            ]]>
        </fx:Script>
        
        <fx:Declarations>
            <!-- 将非可视元素(例如服务、值对象)放在此处 -->
        </fx:Declarations>
        <s:layout>
            <s:VerticalLayout />
        </s:layout>
        <s:BorderContainer id="imgLabel" width="100%" height="100%" borderVisible="false" backgroundAlpha="0">
            <s:Image id="leftImg" x="0" source="{leftIcon}" />
            <s:Label id="dateSlectLabel" x="15" y="3"
                     text="2013-7-6"
                     paddingLeft="5" paddingRight="5"
                     verticalAlign="middle" maxDisplayedLines="1" textAlign="center" fontFamily="微软雅黑" />
            <s:Image id="rightImg" x="{dateSlectLabel.width + 15}" source="{rightIcon}" />
        </s:BorderContainer>
        <mx:PopUpButton id="popUpButton"
                        label="日期选择" visible="false" chromeColor="0xE8FFE2"
                        alpha="0.8" buttonMode="true"  width="0" height="0" open="dateChoosers.x -= 25;"
                        openAlways="true" useHandCursor="true">
        </mx:PopUpButton>
    </s:BorderContainer>
    DateWeekMouthDateField 的主体是一个BorderContainer,它包含了一个显示标签Label和2个用来外观显示Image以及一个PopUpButton,看下Script里面的代码我们就可以发现它弹出的是dateChoosers。下面我们来看下dateChoosers,源码如下:
    package DateField.component
    {
        import DateField.event.DateFieldChooseEvent;
        
        import mx.containers.TabNavigator;
        import mx.containers.VBox;
        import mx.controls.DateChooser;
        import mx.controls.List;
        import mx.core.ScrollPolicy;
        import mx.events.CalendarLayoutChangeEvent;
        import mx.events.ListEvent;
        
        import spark.components.BorderContainer;
        
        /**
         * 日周月年日期选择控件,包含了日日期选择器,周日期选择器,月份选择器和年份选择器 
         * @author jackyWHJ
         * @date 2013-7-30
         * @version 1.0
         * 
         */
        public class DateChoosers extends BorderContainer
        {
            //-----------------------------------------------------
            //    控件需要从外部接收参数的属性定义 start
            //-----------------------------------------------------
            /**
             * 启用年份导航。如果为 true,则显示的年份右侧会出现向上和向下按钮。
             * 您可以使用这些按钮更改当前年份。
             * 在采用年份显示在月份之前的日期格式的区域设置中,这些按钮将显示在年份的左侧。 
             * @default true 
             */
            private var _yearNavigationEnabled:Boolean = true;
            
            /**
             * DateChooser 控件的工作日名称。
             * 更改此属性可更改 DateChooser 控件的日期标签。
             * 星期日为第一天(在索引为 0 处)。
             * 一周中其余的天按照正常的顺序命名。
             * @default ["日", "一", "二", "三", "四", "五", "六"]
             */
            private var _dayNames:Array = ["日", "一", "二", "三", "四", "五", "六"];
            
            /**
             * 显示在 DateChooser 控件顶部的月份名称。
             * 将 monthSymbol 属性追加到由 monthNames 属性指定的值末尾,该属性这在语言(如日语)中很有用。
             * @default ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月","十二月"]
             */
            private var _monthNames:Array = ["一月", "二月", "三月", "四月", "五月",
                "六月", "七月", "八月", "九月", "十月", "十一月","十二月"];
            
            /**
             * 控件中可选的最后一个年份。
             * @default 2020 
             */
            private var _maxYear:uint = 2020; 
            
            /**
             * 控件中可选的第一个年份。
             * @default 2009
             */
            private var _minYear:uint = 2009; 
            
            /**
             * 日期控件的宽度 
             * @default 210
             */
            private var _chooserWidth:Number = 210;
            
            /**
             * 日期控件的高度
             * @default 200
             */
            private var _chooserHeight:Number = 200;
            
            /**
             * 如果为 true,则指定在 DateChooser 控件中允许选择不连续的日期。
             * 仅当 allowMultipleSelection 属性设置为 true 时,此属性才起作用。
             * 设置此属性可更改 DateChooser 控件的外观。 默认值为 false。
             */
            private var _allowDisjointSelection:Boolean = false;
            
            /**
             * 如果为 true,则指定在 DateChooser 控件中允许选择多个日期。
             * 设置此属性可更改 DateChooser 控件的外观。 默认值true。
             */
            private var _allowMultipleSelection:Boolean = true;
            
            /**
             * 每周中要禁用的日期。每月中除指定日期外,所有日期都被禁用。
             * 此属性可更改 DateChooser 控件的外观。
             * 此数组中的元素可使用介于 0(星期日)到 6(星期六)之间的值。例如,如果设置值 [ 0, 6 ],将禁用星期日和星期六。 
             * 默认值为 []。
             * */
            private var _disabledDays:Array = [];
            
            /**
             * 禁用一天或多天。 此属性接受对象 Array 作为参数。
             * 此数组中的所有对象都是 Date 对象,用于指定要禁用的各个日期;也可以是一个包含 rangeStart 和(或)rangeEnd 属性的对象。
             * 这些属性的值描述了日期范围的边界。如果忽略其中任一属性,则认为在该方向上无范围限制。
             * 如果仅指定 rangeStart,则将禁用指定日期之后的所有日期(包括 rangeStart 日期)。
             * 如果仅指定 rangeEnd,则将禁用指定日期之前的所有日期(包括 rangeEnd 日期)。
             * 要禁用单个日期,请使用一个 Date 对象指定 Array 中的某个日期。时间值(如果存在)将以 Date 对象为零值,依次递增。
             * 以下示例将禁用下列日期:2006 年 1 月 11 日,从 2006 年 1 月 23 至同年 2 月 10 日,以及 2006 年 3 月 1 日及后续所有日期。
             * disabledRanges="{[ new Date(2006,0,11), {rangeStart: new Date(2006,0,23), 
             * rangeEnd: new Date(2006,1,10)}, {rangeStart: new Date(2006,2,1)} ]}"
             * 默认值为 []。
             */
            private var _disabledRanges:Array = [];
            
            /**
             * 一个数字,该数字代表显示在 DateChooser 控件第一列中的一周中的日期。
             * 该值必须介于 0 到 6 之间,其中 0 对应星期日,这是 dayNames Array 中的第一个元素。 
             * 设置此属性将更改日期列的顺序。例如,将其设置为 1 可将星期一设置为该控件中的第一列。
             * 默认值为 0 (Sunday)。
             */
            private var _firstDayOfWeek:Object = 0;
            
            /**
             * 此属性将追加到由 monthNames 属性指定的值的末尾,用于定义显示在 DateChooser 控件顶部的月份名称。
             * 有些语言(如日语)会在月份名称后使用额外的符号。 默认值为 ""。
             */
            private var _monthSymbol:String = "";
            
            /**
             * 日期范围,可从中选择日期。例如,可以选择 04-12-2006 和 04-12-2007 之间的日期,而超出此范围的日期将被禁用。 
             * 此属性接受 Object 作为参数。该 Object 包含 Date 类型的两个属性:rangeStart 和 rangeEnd。
             * 如果仅指定了 rangeStart,则在此指定日期之后的所有日期都可用。如果仅指定了 rangeEnd,则在此指定日期之前的所有日期都可用。
             * 要仅在 DateChooser 控件中使用一个日期,可以直接传递一个 Date 对象。时间值(如果存在)将以 Date 对象为零值,依次递增。
             * 以下示例仅启用 2006 年 1 月 1 日到 2006 年 6 月 30 日的范围。1 月之前和 6 月之后的月份不会出现在 DateChooser 中。
             * selectableRange="{{rangeStart : new Date(2006,0,1), rangeEnd : new Date(2006,5,30)}}"
             * 默认值为 null
             */
            private var _selectableRange:Object;
            
            /**
             * 在 DateChooser 控件中选择的日期。如果传入的 Date 对象包含任何时间值,则它们将被清零。 
             * 在控件中选择当前所选日期时按住 Ctrl 键可取消对该日期的选择,将 selectedDate 属性设置为 null,然后分派 change 事件。
             * 默认值为 null。
             */
            private var _selectedDate:Date = null;
            
            /**
             * 如果为 true,则指定在 DateChooser 控件中加亮显示今天。设置此属性可更改 DateChooser 控件的外观。 
             * 默认值为 true。
             */
            private var _showToday:Boolean = true;
            
            /**
             * 此属性附加在 DateChooser 控件顶部显示的年份末尾。有些语言(如日语)会在年份后添加符号。 
             * 默认值为 ""。
             */
            private var _yearSymbol:String = "";
            
            /**
             * 日期选择器标签 ,日期选择器就是由这个标签来生成的。
             * 总共有["日","周","月","年"]4个日期标签,如果该值设置为["日","周"]的话,那就只有日周2个日期选择器。
             */
            private var _dateLabel:Array = ["日","周","月"];
            
            /**
             * 月份日期选择器日期范围需要在当前月份推前的月份数,比如现在是2013年7月,
             * 那么默认值48则表示从该日期往前推48个月,也就是说,目前的日期选择最前可以是2009年7月 
             */
            private var _beforeMonthCount:uint = 48;
            
            /**
             * 月份日期选择器日期范围需要在当前月份推后的月份数,比如现在是2013年7月,
             * 值为2则表示从该日期往后推2个月,也就是说,日期选择最后可以是2013年9月 
             */
            private var _afterMonthCount:uint = 0;
            
            /**
             * 年份日期选择器日期范围需要在当前月份推前的月份数,比如现在是2013年
             * 那么默认值4则表示从该日期往前推4年,也就是说,目前的日期选择最前可以是2009年 
             */
            private var _beforeYearCount:uint = 4;
            
            /**
             * 年份日期选择器日期范围需要在当前年份推后的月份数,比如现在是2013年,
             * 值为2则表示从该日期往后推2年,也就是说,日期选择最后可以是2015年。 
             */
            private var _afterYearCount:uint = 0;
            
            /**
             * 当前默认是选择哪个日期选择器,默认是0,日日期选择器
             */
            private var _selectedIndex:int = 0;
            
            //-----------------------------------------------------
            //    控件需要从外部接收参数的属性定义 end
            //-----------------------------------------------------
            
            //-----------------------------------------------------
            //    控件内部属性定义 start
            //-----------------------------------------------------
            /**
             * 月份选择下拉列表 
             */
            private var monthList:List;
            
            /**
             * 年份选择下拉列表 
             */
            private var yearList:List;
            
            /**
             * 月份选择控件数据源数据
             */
            private var dateArray:Array;
            
            /**
             * 日日期选择器
             */
            private var dateChooser1:DateChooser;
            
            /**
             * 周日期选择器
             */
            private var dateChooser2:DateChooser;
            
            /**
             * MX TabNavigator 容器通过包括一个用于在其子容器间导航的 TabBar 容器来扩展 MX ViewStack 容器。  
             */
            private var tabNavigator:TabNavigator;
            
            /**
             * TabNavigator的日日期选择器子容器
             */
            private var dateField:VBox;
            
            /**
             * TabNavigator的周日期选择器子容器
             */
            private var weekField:VBox;
            
            /**
             * TabNavigator的月日期选择器子容器
             */
            private var monthField:VBox;
            
            /**
             * TabNavigator的年日期选择器子容器
             */
            private var yearField:VBox;
            //-----------------------------------------------------
            //    控件内部属性定义 end
            //-----------------------------------------------------
            /**
             * 构造函数,初始化并添加子容器
             * 
             */
            public function DateChoosers()
            {
                //TODO: implement function
                super();
                this.width = chooserWidth;
                this.height = chooserHeight;
                
            }
     
            override protected function createChildren():void
            {
                //初始化tabNavigator
                if(tabNavigator == null)
                {
                    tabNavigator = new TabNavigator();
                    tabNavigator.styleName = "TabNavigator";
    //                tabNavigator.percentWidth = 100;
                    tabNavigator.width = chooserWidth + 1;
                    tabNavigator.percentHeight = 100;
                    tabNavigator.x = -1;
                    this.addElement(tabNavigator);
                }
                
                
                //设置 tabNavigator 的tabWidth 长度
                if (dateLabel != null && dateLabel.length >0)
                {
                    tabNavigator.setStyle("tabWidth",chooserWidth/dateLabel.length + 1);
                }
                
                //dateLabel 的长度大于0,也是就是dateLabel至少有1个元素,则添加日日期选择器容器
                if(dateLabel.length > 0 && dateField == null)
                {
                    //初始化dateField
                    dateField = new VBox();
                    dateField.label = dateLabel[0];
                    dateField.percentWidth = 100; 
                    dateField.percentHeight = 100;
                    tabNavigator.addElement(dateField);
                }
                
                //dateLabel 的长度大于1,也是就是dateLabel至少有2个元素,则添加周日期选择器容器
                if(dateLabel.length > 1 && weekField == null)
                {
                    //初始化weekField
                    weekField = new VBox();
                    weekField.label = dateLabel[1];
                    weekField.percentWidth = 100; 
                    weekField.percentHeight = 100;
                    tabNavigator.addElement(weekField);
                }
                
                //dateLabel 的长度大于2,也是就是dateLabel至少有3个元素,则添加月日期选择器容器
                if(dateLabel.length > 2 && monthField == null)
                {
                    //初始化monthField
                    monthField = new VBox();
                    monthField.label = dateLabel[2];
                    monthField.percentWidth = 100; 
                    monthField.percentHeight = 100;
                    monthField.verticalScrollPolicy = ScrollPolicy.OFF ;
                    monthField.horizontalScrollPolicy = ScrollPolicy.OFF;
                    tabNavigator.addElement(monthField);
                }
                
                //dateLabel 的长度大于3,也是就是dateLabel至少有4个元素,则添加年日期选择器容器
                if(dateLabel.length > 3 && yearField == null)
                {
                    //初始化yearField
                    yearField = new VBox();
                    yearField.label = dateLabel[3];
                    yearField.percentWidth = 100; 
                    yearField.percentHeight = 100;
                    yearField.verticalScrollPolicy = ScrollPolicy.OFF ;
                    yearField.horizontalScrollPolicy = ScrollPolicy.OFF;
                    tabNavigator.addElement(yearField);
                }
                
                tabNavigator.selectedIndex = selectedIndex;
                
                this.init();
            }
            
            /**
             * 初始化日周月各日期选择器,并绑定数据源,添加监听事件 
             * 
             */
            private function init():void 
            {
                if(dateField != null)
                {
                    //初始化day日期选择器的
                    dateChooser1 = new DateChooser();
                    dateChooser1.percentWidth = 100; 
                    dateChooser1.percentHeight = 100; 
                    dateChooser1.yearNavigationEnabled = this.yearNavigationEnabled;
                    dateChooser1.dayNames = this.dayNames;
                    dateChooser1.monthNames = this.monthNames;
                    dateChooser1.maxYear = this.maxYear; 
                    dateChooser1.minYear = this.minYear; 
                    dateChooser1.allowDisjointSelection = allowDisjointSelection;
                    dateChooser1.allowMultipleSelection = allowMultipleSelection;
                    dateChooser1.disabledDays = disabledDays;
                    dateChooser1.disabledRanges = disabledRanges;
                    dateChooser1.firstDayOfWeek = firstDayOfWeek;
                    dateChooser1.selectedDate = selectedDate;
                    dateChooser1.monthSymbol = monthSymbol;
                    dateChooser1.selectableRange = selectableRange;
                    dateChooser1.showToday = showToday;
                    dateChooser1.yearSymbol = yearSymbol;
                    dateChooser1.x = -1;
                    dateChooser1.styleName = "DateChooser";
                    dateChooser1.addEventListener(CalendarLayoutChangeEvent.CHANGE,dateChooser1_changeHandler);
                    dateField.addElement(dateChooser1);
                }
                
                if(weekField != null)
                {
                    //初始化week日期选择器
                    dateChooser2 = new DateChooser();
                    dateChooser2.percentWidth = 100; 
                    dateChooser2.percentHeight = 100; 
                    dateChooser2.yearNavigationEnabled = this.yearNavigationEnabled;
                    dateChooser2.dayNames = this.dayNames;
                    dateChooser2.monthNames = this.monthNames;
                    dateChooser2.maxYear = this.maxYear; 
                    dateChooser2.minYear = this.minYear; 
                    dateChooser2.allowDisjointSelection = this.allowDisjointSelection;
                    dateChooser2.allowMultipleSelection = this.allowMultipleSelection;
                    dateChooser2.disabledDays = disabledDays;
                    dateChooser2.disabledRanges = disabledRanges;
                    dateChooser2.firstDayOfWeek = firstDayOfWeek;
                    dateChooser2.monthSymbol = monthSymbol;
                    dateChooser2.yearSymbol = yearSymbol;
                    dateChooser2.x = -1;
                    dateChooser2.styleName = "DateChooser";
                    dateChooser2.addEventListener(CalendarLayoutChangeEvent.CHANGE,dateChooser2_changeHandler);
                    weekField.addElement(dateChooser2);
                    
                    //初始化week日期选择器的选择数据
                    var currentDate:Date;
                    //如果已经设置了选择的日期,则当前日期安装选择日期来
                    if(selectedDate)
                    {
                        currentDate = selectedDate;
                    }
                    else
                    {
                        currentDate = new Date();
                    }
                    var date1:Date = new Date(currentDate.getTime());
                    var date2:Date = new Date(currentDate.getTime());
                    var distinceDay:Number = currentDate.getDay();
                    if(distinceDay > 0)
                    {
                        date1.date -= distinceDay - 1;
                        date2.date = currentDate.date + (7 - distinceDay);
                    }
                    else
                    {
                        date1.date -= distinceDay - 6;
                    }
                    //                trace(DateChooser(event.target).selectedDate.getUTCDay ());
                    dateChooser2.selectedRanges = [{rangeStart: date1, rangeEnd: date2}];
                    
                }
                
                var currentYear:uint;
                var beforeYear:uint;
                var afterYear:uint;
                
                //初始化月日期选择器
                var rowCount:int = 0;
                if(monthField != null)
                {
                    monthList = new List();
                    rowCount = 0;
                    dateArray = new Array();
                    //根据当前日期和要推前的月份数计算最前日期应该是那一年那一月
                    currentYear = currentDate.getFullYear();
                    var currentMonth:uint = currentDate.getMonth() + 1;
                    beforeYear = currentYear - uint(this.beforeMonthCount / 12);
                    var beforeMonth:int = currentMonth - uint(this.beforeMonthCount % 12);
                    //如果减下来的日期已经超过这一年的日期,则月份从前一年开始算
                    if(beforeMonth <= 0)
                    {
                        -- beforeYear;
                        beforeMonth = 12 + beforeMonth;
                    }
                    afterYear = currentYear + uint(this.afterMonthCount / 12);
                    var afterMonth:int = currentMonth + uint(this.afterMonthCount % 12);
                    //如果加下来的日期已经超过这一年的日期,则月份从后一年开始算
                    if(afterMonth > 12)
                    {
                        ++ afterYear;
                        afterMonth = afterMonth - 12;
                    }
                    //初始化月日期选择器的数据源
                    for (var i:int = afterYear; i >= beforeYear; i--)
                    {
                        for (var j:int = 12 ;j >0 ; j--)
                        {
                            //最后日期后的略过
                            if (i == afterYear && j > afterMonth)
                            {
                                continue;
                            }
                            //最前日期前的直接终止
                            if (i == beforeYear && j < beforeMonth)
                            {
                                break;
                            }
                            var dateString:String = "" + i + "年" + j + "月";
                            rowCount = dateArray.push(dateString);
                            //如果设置了选中日期,则默认选择日期按照选中日期来,否则,默认选中日期为当前日期
                            if(this.selectedDate)
                            {
                                if (i == this.selectedDate.getFullYear() && j == (this.selectedDate.getMonth() + 1))
                                {
                                    monthList.selectedIndex = rowCount - 1;
                                }
                            }
                            else
                            {
                                if (i == currentYear && j == currentMonth)
                                {
                                    monthList.selectedIndex = rowCount - 1;
                                }
                            }
                            
                        }
                    }
                    
                    monthList.dataProvider = dateArray;
                    monthField.addElement(monthList);
                    monthList.percentWidth = 100;
                    monthList.addEventListener(ListEvent.ITEM_CLICK, itemClickHandler);
                }
                //初始化年日期选择器
                if(yearField != null)
                {
                    yearList = new List();
                    rowCount = 0;
                    dateArray = new Array();
                    currentYear = currentDate.getFullYear();
                    beforeYear = currentYear - this.beforeYearCount;
                    afterYear = currentYear + this.afterYearCount;
                    //初始化年日期选择器的数据源
                    for (var k:int = afterYear; k >= beforeYear; k--)
                    {
                        var yearString:String = "" + k + "年";
                        rowCount = dateArray.push(yearString);
                        //如果设置了选中日期,则默认选择日期按照选中日期来,否则,默认选中日期为当前日期
                        if(this.selectedDate)
                        {
                            if (k == this.selectedDate.getFullYear())
                            {
                                yearList.selectedIndex = rowCount - 1;
                            }
                        }
                        else
                        {
                            if (k == currentYear)
                            {
                                yearList.selectedIndex = rowCount - 1;
                            }
                        }
                    }
                    
                    yearList.dataProvider = dateArray;
                    yearField.addElement(yearList);
                    yearList.percentWidth = 100;
                    yearList.addEventListener(ListEvent.ITEM_CLICK, yearItemClickHandler);
                }
                
            }
            
            /**
             * 年日期选择器的选择点击监听事件 
             * @param evt
             * 
             */
            protected function yearItemClickHandler(event:ListEvent):void
            {
                // TODO Auto-generated method stub
                yearList.selectedIndex = event.rowIndex;
                this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                    yearList.selectedItem));
            }
            
            /**
             * 月日期选择器的选择点击监听事件 
             * @param evt
             * 
             */
            protected function itemClickHandler(evt:ListEvent):void {
                trace("evt.index:" + monthList.selectedItem);
                monthList.selectedIndex = evt.rowIndex;
                this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                    monthList.selectedItem));
            }
            
            /**
             * 周 日期选择器的选择点击监听事件 
             * @param event
             * 
             */
            protected function dateChooser2_changeHandler(event:CalendarLayoutChangeEvent):void
            {
                // 获取当前选中的日期,再根据当前日期是周几取得这星期的第一天和最后一天
                var currentDate:Date = DateChooser(event.target).selectedDate;
    //            trace(DateChooser(event.target).selectedDate);
                var date1:Date = new Date(currentDate.getTime());
                var date2:Date = new Date(currentDate.getTime());
                var distinceDay:Number = currentDate.getDay();
                if(distinceDay > 0)
                {
                    date1.date -= distinceDay - 1;
                    date2.date = currentDate.date + (7 - distinceDay);
                }
                else
                {
                    date1.date -= distinceDay - 6;
                }
                dateChooser2.selectedRanges = [{rangeStart: date1, rangeEnd: date2}];
                var dateString:String = "" + date1.getFullYear() + "-" + (date1.getMonth()+1) + "-"
                    + date1.getDate() + "~" + date2.getFullYear() + "-" + (date2.getMonth()+1) + "-"
                    + date2.getDate();
                trace(dateString);
                this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                    dateString));
            }
            
            /**
             * 日日期选择器的选择点击监听事件  
             * @param event
             * 
             */
            protected function dateChooser1_changeHandler(event:CalendarLayoutChangeEvent):void
            {
                var date:Date = DateChooser(event.target).selectedDate;
                var ob:Object = DateChooser(event.target).selectedRanges;
                var dateString:String;
    //            trace(ob);
                if(ob !=  null)
                {
                    var date1:Date = ob[0].rangeStart;
                    var date2:Date = ob[0].rangeEnd;
                    if(date1.getFullYear() == date2.getFullYear() && date1.getMonth() == date2.getMonth() 
                        && date1.getDate() == date2.getDate())
                    {
                        dateString = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                            + date.getDate();
                    }
                    else
                    {
                        dateString = "" + date1.getFullYear() + "-" + (date1.getMonth()+1) + "-"
                            + date1.getDate() + "~" + date2.getFullYear() + "-" + (date2.getMonth()+1) + "-"
                            + date2.getDate();
                    }
                }
                else
                {
                    dateString = "" + date.getFullYear() + "-" + (date.getMonth()+1) + "-"
                        + date.getDate();
                }
                
                trace(dateString);
                this.dispatchEvent(new DateFieldChooseEvent(DateFieldChooseEvent.DATE_SELECTED, 
                    dateString));
            }
            
            /**
             * 启用年份导航。如果为 true,则显示的年份右侧会出现向上和向下按钮。
             * 您可以使用这些按钮更改当前年份。
             * 在采用年份显示在月份之前的日期格式的区域设置中,这些按钮将显示在年份的左侧。 
             */
            public function get yearNavigationEnabled():Boolean
            {
                return _yearNavigationEnabled;
            }
     
            /**
             * @private
             */
            public function set yearNavigationEnabled(value:Boolean):void
            {
                _yearNavigationEnabled = value;
            }
     
            /**
             * DateChooser 控件的工作日名称。
             * 更改此属性可更改 DateChooser 控件的日期标签。
             * 星期日为第一天(在索引为 0 处)。
             * 一周中其余的天按照正常的顺序命名。
             * @default ["日", "一", "二", "三", "四", "五", "六"]
             */
            public function get dayNames():Array
            {
                return _dayNames;
            }
     
            /**
             * @private
             */
            public function set dayNames(value:Array):void
            {
                _dayNames = value;
            }
     
            /**
             * 显示在 DateChooser 控件顶部的月份名称。
             * 将 monthSymbol 属性追加到由 monthNames 属性指定的值末尾,该属性这在语言(如日语)中很有用。
             * @default ["一月", "二月", "三月", "四月", "五月", "六月", "七月", "八月", "九月", "十月", "十一月","十二月"]
             */
            public function get monthNames():Array
            {
                return _monthNames;
            }
     
            /**
             * @private
             */
            public function set monthNames(value:Array):void
            {
                _monthNames = value;
            }
     
            /**
             * 控件中可选的最后一个年份。
             * @default 2020 
             */
            public function get maxYear():uint
            {
                return _maxYear;
            }
     
            /**
             * @private
             */
            public function set maxYear(value:uint):void
            {
                _maxYear = value;
            }
     
            /**
             * 控件中可选的第一个年份。
             * @default 2009
             */
            public function get minYear():uint
            {
                return _minYear;
            }
     
            /**
             * @private
             */
            public function set minYear(value:uint):void
            {
                _minYear = value;
            }
     
            /**
             * 日期控件的宽度 
             * @default 210
             */
            public function get chooserWidth():Number
            {
                return _chooserWidth;
            }
     
            /**
             * @private
             */
            public function set chooserWidth(value:Number):void
            {
                _chooserWidth = value;
            }
     
            /**
             * 日期控件的高度
             * @default 200
             */
            public function get chooserHeight():Number
            {
                return _chooserHeight;
            }
     
            /**
             * @private
             */
            public function set chooserHeight(value:Number):void
            {
                _chooserHeight = value;
            }
            
            /**
             * 日期选择器标签 ,日期选择器就是由这个标签来生成的。
             * 总共有["日","周","月","年"]4个日期标签,如果该值设置为["日","周"]的话,那就只有日周2个日期选择器。
             */
            public function get dateLabel():Array 
            {
                return _dateLabel;
            }
     
            /**
             * @private
             */
            public function set dateLabel(value:Array):void
            {
                _dateLabel = value;
            }
     
            /**
             * 如果为 true,则指定在 DateChooser 控件中允许选择不连续的日期。
             * 仅当 allowMultipleSelection 属性设置为 true 时,此属性才起作用。
             * 设置此属性可更改 DateChooser 控件的外观。 默认值为 false。
             */
            public function get allowDisjointSelection():Boolean
            {
                return _allowDisjointSelection;
            }
     
            /**
             * @private
             */
            public function set allowDisjointSelection(value:Boolean):void
            {
                _allowDisjointSelection = value;
            }
     
            /**
             * 如果为 true,则指定在 DateChooser 控件中允许选择多个日期。
             * 设置此属性可更改 DateChooser 控件的外观。 默认值true。
             */
            public function get allowMultipleSelection():Boolean
            {
                return _allowMultipleSelection;
            }
     
            /**
             * @private
             */
            public function set allowMultipleSelection(value:Boolean):void
            {
                _allowMultipleSelection = value;
            }
     
            /**
             * 每周中要禁用的日期。每月中除指定日期外,所有日期都被禁用。
             * 此属性可更改 DateChooser 控件的外观。
             * 此数组中的元素可使用介于 0(星期日)到 6(星期六)之间的值。例如,如果设置值 [ 0, 6 ],将禁用星期日和星期六。 
             * 默认值为 []。
             * */
            public function get disabledDays():Array
            {
                return _disabledDays;
            }
     
            /**
             * @private
             */
            public function set disabledDays(value:Array):void
            {
                _disabledDays = value;
            }
     
            /**
             * 禁用一天或多天。 此属性接受对象 Array 作为参数。
             * 此数组中的所有对象都是 Date 对象,用于指定要禁用的各个日期;也可以是一个包含 rangeStart 和(或)rangeEnd 属性的对象。
             * 这些属性的值描述了日期范围的边界。如果忽略其中任一属性,则认为在该方向上无范围限制。
             * 如果仅指定 rangeStart,则将禁用指定日期之后的所有日期(包括 rangeStart 日期)。
             * 如果仅指定 rangeEnd,则将禁用指定日期之前的所有日期(包括 rangeEnd 日期)。
             * 要禁用单个日期,请使用一个 Date 对象指定 Array 中的某个日期。时间值(如果存在)将以 Date 对象为零值,依次递增。
             * 以下示例将禁用下列日期:2006 年 1 月 11 日,从 2006 年 1 月 23 至同年 2 月 10 日,以及 2006 年 3 月 1 日及后续所有日期。
             * disabledRanges="{[ new Date(2006,0,11), {rangeStart: new Date(2006,0,23), 
                    * rangeEnd: new Date(2006,1,10)}, {rangeStart: new Date(2006,2,1)} ]}"
                * 默认值为 []。
                */
                public function get disabledRanges():Array
                {
                return _disabledRanges;
            }
     
            /**
             * @private
             */
            public function set disabledRanges(value:Array):void
            {
                _disabledRanges = value;
            }
     
            /**
             * 一个数字,该数字代表显示在 DateChooser 控件第一列中的一周中的日期。
             * 该值必须介于 0 到 6 之间,其中 0 对应星期日,这是 dayNames Array 中的第一个元素。 
             * 设置此属性将更改日期列的顺序。例如,将其设置为 1 可将星期一设置为该控件中的第一列。
             * 默认值为 0 (Sunday)。
             */
            public function get firstDayOfWeek():Object
            {
                return _firstDayOfWeek;
            }
     
            /**
             * @private
             */
            public function set firstDayOfWeek(value:Object):void
            {
                _firstDayOfWeek = value;
            }
     
            /**
             * 此属性将追加到由 monthNames 属性指定的值的末尾,用于定义显示在 DateChooser 控件顶部的月份名称。
             * 有些语言(如日语)会在月份名称后使用额外的符号。 默认值为 ""。
             */
            public function get monthSymbol():String
            {
                return _monthSymbol;
            }
     
            /**
             * @private
             */
            public function set monthSymbol(value:String):void
            {
                _monthSymbol = value;
            }
     
            /**
             * 日期范围,可从中选择日期。例如,可以选择 04-12-2006 和 04-12-2007 之间的日期,而超出此范围的日期将被禁用。 
             * 此属性接受 Object 作为参数。该 Object 包含 Date 类型的两个属性:rangeStart 和 rangeEnd。
             * 如果仅指定了 rangeStart,则在此指定日期之后的所有日期都可用。如果仅指定了 rangeEnd,则在此指定日期之前的所有日期都可用。
             * 要仅在 DateChooser 控件中使用一个日期,可以直接传递一个 Date 对象。时间值(如果存在)将以 Date 对象为零值,依次递增。
             * 以下示例仅启用 2006 年 1 月 1 日到 2006 年 6 月 30 日的范围。1 月之前和 6 月之后的月份不会出现在 DateChooser 中。
             * selectableRange="{{rangeStart : new Date(2006,0,1), rangeEnd : new Date(2006,5,30)}}"
                * 默认值为 null
                */
                public function get selectableRange():Object
                {
                return _selectableRange;
            }
     
            /**
             * @private
             */
            public function set selectableRange(value:Object):void
            {
                _selectableRange = value;
            }
     
            /**
             * 在 DateChooser 控件中选择的日期。如果传入的 Date 对象包含任何时间值,则它们将被清零。 
             * 在控件中选择当前所选日期时按住 Ctrl 键可取消对该日期的选择,将 selectedDate 属性设置为 null,然后分派 change 事件。
             * 默认值为 null。
             */
            public function get selectedDate():Date
            {
                return _selectedDate;
            }
     
            /**
             * @private
             */
            public function set selectedDate(value:Date):void
            {
                _selectedDate = value;
            }
     
            /**
             * 如果为 true,则指定在 DateChooser 控件中加亮显示今天。设置此属性可更改 DateChooser 控件的外观。 
             * 默认值为 true。
             */
            public function get showToday():Boolean
            {
                return _showToday;
            }
     
            /**
             * @private
             */
            public function set showToday(value:Boolean):void
            {
                _showToday = value;
            }
     
            /**
             * 此属性附加在 DateChooser 控件顶部显示的年份末尾。有些语言(如日语)会在年份后添加符号。 
             * 默认值为 ""。
             */
            public function get yearSymbol():String
            {
                return _yearSymbol;
            }
     
            /**
             * @private
             */
            public function set yearSymbol(value:String):void
            {
                _yearSymbol = value;
            }
     
            /**
             * 月份日期选择器日期范围需要在当前月份推前的月份数,比如现在是2013年7月,
             * 那么默认值48则表示从该日期往前推48个月,也就是说,目前的日期选择最前可以是2009年7月 
             */
            public function get beforeMonthCount():uint
            {
                return _beforeMonthCount;
            }
     
            /**
             * @private
             */
            public function set beforeMonthCount(value:uint):void
            {
                _beforeMonthCount = value;
            }
     
            /**
             * 月份日期选择器日期范围需要在当前月份推后的月份数,比如现在是2013年7月,
             * 值为2则表示从该日期往后推2个月,也就是说,日期选择最后可以是2013年9月 
             */
            public function get afterMonthCount():uint
            {
                return _afterMonthCount;
            }
     
            /**
             * @private
             */
            public function set afterMonthCount(value:uint):void
            {
                _afterMonthCount = value;
            }
     
            /**
             * 年份日期选择器日期范围需要在当前月份推前的月份数,比如现在是2013年
             * 那么默认值4则表示从该日期往前推4年,也就是说,目前的日期选择最前可以是2009年 
             */
            public function get beforeYearCount():uint
            {
                return _beforeYearCount;
            }
     
            /**
             * @private
             */
            public function set beforeYearCount(value:uint):void
            {
                _beforeYearCount = value;
            }
     
            /**
             * 年份日期选择器日期范围需要在当前年份推后的月份数,比如现在是2013年,
             * 值为2则表示从该日期往后推2年,也就是说,日期选择最后可以是2015年。 
             */
            public function get afterYearCount():uint
            {
                return _afterYearCount;
            }
     
            /**
             * @private
             */
            public function set afterYearCount(value:uint):void
            {
                _afterYearCount = value;
            }
     
            /**
             * 当前默认是选择哪个日期选择器,默认是0,日日期选择器
             */
            public function get selectedIndex():int
            {
                return _selectedIndex;
            }
     
            /**
             * @private
             */
            public function set selectedIndex(value:int):void
            {
                _selectedIndex = value;
            }
     
     
        }
    }
    DateChoosers 继承了 BorderContainer,在init方法里我们可以看到,它根据自身的属性日周月年的控制添加了2个DateChooser和2个List,也就是说日和周日期选择主要是2个DateChooser,而月和年的日期选择则是2个List。而在DateChooser和List都添加了点击事件的监听,在点击事件之后根据自身特点派发出相应的事件。从而达到日期选择的目的。
    下面来看看使用例子:
    <?xml version="1.0" encoding="utf-8"?>
    <!-- Simple example to demonstrate the Halo List Control -->
    <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                   xmlns:s="library://ns.adobe.com/flex/spark"
                   xmlns:mx="library://ns.adobe.com/flex/mx"
                   xmlns:DateField="DateField.*"
                   initialize="application1_initializeHandler(event)">
        <fx:Script>
            <![CDATA[
                import mx.events.FlexEvent;
                
                protected function application1_initializeHandler(event:FlexEvent):void
                {
                    // TODO Auto-generated method stub
                    dwmDF.dateChoosers.dateLabel = ["日","周","月","年"];
                    dwmDF.dateChoosers.afterMonthCount = 4;
                    dwmDF.dateChoosers.afterYearCount = 3;
                    dwmDF.dateChoosers.disabledRanges = [ {rangeStart: new Date(2013,7,3), rangeEnd: new Date(2013,7,10)}];
                }
                
            ]]>
        </fx:Script>
        
        <fx:Declarations>
            
        </fx:Declarations>
        
        <s:Panel title="DateWeekMouthDateField Example"
                 width="75%" height="75%" 
                 horizontalCenter="0" verticalCenter="0">
            <s:VGroup left="10" right="10" top="10" bottom="10">
                <DateField:DateWeekMouthDateField id="dwmDF" x="150" y="100">
                    
                </DateField:DateWeekMouthDateField>
            </s:VGroup>
        </s:Panel>
        
    </s:Application>
    其中dwmDF.dateChoosers.dateLabel = ["日","周","月","年"];是对日期选择器标签的设置,日期选择器就是由这个标签来生成的。 总共有["日","周","月","年"]4个日期标签,如果该值设置为["日","周"]的话,那就只有日周2个日期选择器。dwmDF.dateChoosers.afterMonthCount = 4;表示月份日期选择器日期范围需要在当前月份推后的月份数,比如现在是2013年7月, 值为2则表示从该日期往后推2个月,也就是说,日期选择最后可以是2013年9月,同理dwmDF.dateChoosers.afterYearCount = 3;是对年份选择器的设置,年份日期选择器日期范围需要在当前年份推后的月份数,比如现在是2013年, 值为2则表示从该日期往后推2年,也就是说,日期选择最后可以是2015年。dwmDF.dateChoosers.disabledRanges是禁用日期的,这个和DateChooser是一致的。
    日周月日期选择器这样就功能实现了,在选择后,我们可以通过dwmDF.dateSlectLabel.text获取我们选择的日期内容。
    最后附上完整代码地址:http://files.cnblogs.com/jackyWHJ/DateFieldTest.zip,有需要的童鞋拿去,可以的话给我保留下著作声明

     

     
     
     
  • 相关阅读:
    tomcat-1
    oscache-2
    oscache-3
    oscache-1
    oscache-4
    缓存概要
    Criterion & DetachedCriteria
    Hibernate <查询缓存>
    Hibernate <二级缓存>
    Hibernate <一级缓存>
  • 原文地址:https://www.cnblogs.com/jackyWHJ/p/3725840.html
Copyright © 2020-2023  润新知