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、一年的第一周为该年中第一个满四天的周;