ExtJS5 - 实现带周数的日期选择控件

Ext默认提供了日期选择控件Ext.date.Picker和日期输入框Ext.form.field.Date这两个类来完成日期选择等相关操作,并且通过单体类Ext.Date提供一些常用的日期时间处理方法。

但是在实际的业务场景中,我们常常期望日期选择控件能够显示每周的周数,以方便用户对日期进行筛选。下面的代码示例就通过对Ext.date.Picker和Ext.form.field.Date的扩展来实现带周数的日期选择控件:

Ext.onReady(function() {
	Ext.define("KwDatePicker", {
		extend: "Ext.picker.Date",
		alias: "widget.kwdatepicker",
		width: 242,
		numWeeks: 6, //每屏要显示的周数
		
		renderTpl: [
	        '<div id="{id}-innerEl" data-ref="innerEl">',
	            '<div class="{baseCls}-header">',
	                '<div id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="button" title="{prevText}"></div>',
	                '<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month" role="heading">{%this.renderMonthBtn(values, out)%}</div>',
	                '<div id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="button" title="{nextText}"></div>',
	            '</div>',
	            '<table role="grid" id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" {%',
	                // If the DatePicker is focusable, make its eventEl tabbable.
	                // Note that we're looking at the `focusable` property because
	                // calling `isFocusable()` will always return false at that point
	                // as the picker is not yet rendered.
	                'if (values.$comp.focusable) {out.push("tabindex=\\\"0\\\"");}',
	            '%} cellspacing="0">',
	                '<thead><tr role="row">',
	                	'<th role="columnheader" class="x-datepicker-column-header" aria-label="{.}">',
                            '<div role="presentation" class="x-datepicker-week">KW</div>',
                        '</th>',
	                    '<tpl for="dayNames">',
	                        '<th role="columnheader" class="{parent.baseCls}-column-header" aria-label="{.}">',
	                            '<div role="presentation" class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>',
	                        '</th>',
	                    '</tpl>',
	                '</tr></thead>',
	                '<tbody><tr role="row">',
	                    '<tpl for="days">',
	                        '{#:this.isEndOfWeek}',
	                        '{#:this.isBeginOfWeek}',
	                        '<td role="gridcell">',
	                            '<div hidefocus="on" class="{parent.baseCls}-date"></div>',
	                        '</td>',
	                    '</tpl>',
	                '</tr></tbody>',
	            '</table>',
	            '<tpl if="showToday">',
	                '<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer">{%this.renderTodayBtn(values, out)%}</div>',
	            '</tpl>',
	        '</div>',
	        {
	            firstInitial: function(value) {
	                return Ext.picker.Date.prototype.getDayInitial(value);
	            },
	            isEndOfWeek: function(value) {
	                // convert from 1 based index to 0 based
	                // by decrementing value once.
	                value--;
	                var end = value % 7 === 0 && value !== 0;
	                return end ? '</tr><tr role="row">' : '';
	            },
	            isBeginOfWeek: function(value){   
                    var end = (value === 1 || (value-1)%7 === 0);  
                    return end ? '<td role="weekcell"><div hidefocus="on" class="x-datepicker-week"></div></td>' : '';  
  
                },  
	            renderTodayBtn: function(values, out) {
	                Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out);
	            },
	            renderMonthBtn: function(values, out) {
	                Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out);
	            }
	        }
	    ],
	    fullUpdate: function(date) {
	    	var me = this;
	    	me.callParent(arguments);
	    	
	    	var weekTextNodes = me.weekTextNodes; 
            var firstDateOfMonth = Ext.Date.getFirstDateOfMonth(date); //获取当月第一天日期
            //var firstDayOfMonth = Ext.Date.getFirstDayOfMonth(date); //获取当月第一天星期 0-6
            //var firstWeekOfMonth = Ext.Date.getWeekOfYear(firstDateOfMonth); //当月第一天的周数
            
            for(j=0;j<me.numWeeks;j++) {
            	var weekNum = Ext.Date.getWeekOfYear(new Date(firstDateOfMonth.getTime()+j*7*24*60*60*1000));
                weekTextNodes[j].innerHTML = weekNum.toString();
            }  
	    },
	    onRender: function(container) {
	    	var me = this;
	        me.callParent(arguments);
	
	        me.cells = me.eventEl.select('tbody td[role="gridcell"]');
	        me.textNodes = me.eventEl.query('tbody td[role="gridcell"] div');
	        
	        me.weekCells = me.eventEl.select('tbody td[role="weekcell"]');
	        me.weekTextNodes = me.eventEl.query('tbody td[role="weekcell"] div');
	        
	        me.eventEl.set({ 'aria-labelledby': me.monthBtn.id });
	        me.mon(me.eventEl, {
	            scope: me,
	            mousewheel: me.handleMouseWheel,
	            click: {
	                fn: me.handleDateClick,
	                delegate: 'div.' + me.baseCls + '-date'
	            }
	        });
	    }
	});
	
	Ext.define("KwDateField", {
		extend: "Ext.form.field.Date",
		alias: "widget.kwdatefield",
		
		createPicker: function() {
			var me = this,
			format = Ext.String.format;

	        // Create floating Picker BoundList. It will acquire a floatParent by looking up
	        // its ancestor hierarchy (Pickers use their pickerField property as an upward link)
	        // for a floating component.
	        return new KwDatePicker({
	            pickerField: me,
	            floating: true,
	            focusable: false, // Key events are listened from the input field which is never blurred
	            hidden: true,
	            minDate: me.minValue,
	            maxDate: me.maxValue,
	            disabledDatesRE: me.disabledDatesRE,
	            disabledDatesText: me.disabledDatesText,
	            disabledDays: me.disabledDays,
	            disabledDaysText: me.disabledDaysText,
	            format: me.format,
	            showToday: me.showToday,
	            startDay: me.startDay,
	            minText: format(me.minText, me.formatDate(me.minValue)),
	            maxText: format(me.maxText, me.formatDate(me.maxValue)),
	            listeners: {
	                scope: me,
	                select: me.onSelect
	            },
	            keyNavConfig: {
	                esc: function() {
	                    me.collapse();
	                }
	            }
	        });
	    }
	});
	
	Ext.create("Ext.panel.Panel", {
		title: "Date Picker",
		width: 600,
		height: 400,
		border: true,
		bodyPadding: 10,
		items: [{
			xtype: "kwdatefield",
			startDay: 1,
			format: "Y-m-d"
		}],
		renderTo: Ext.getBody()
	});
});

然后可以通过添加一行简单的样式进行美化:

.x-datepicker-week {padding:4px 0;text-align:center;color:#006699;background-color:#fafafa;}

效果如下:



Ext采用ISO-8601的日期时间标准,其周数算法规则如下:

1、每周的第一天为星期一;

2、一年的第一周为该年中第一个满四天的周;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值