Ext JS 4实现带week(星期)的日期选择控件(实战一)


Posted in Javascript onAugust 21, 2013

前言

Ext JS 3 和 Ext JS 4中都有提供日期选择的组件(当然早期版本也有)。
Ext JS 4实现带week(星期)的日期选择控件(实战一) 

但是有一些日期选择的需求是要看到星期,就是日期中的哪一天是这一年的第几周。

遗憾的是Ext js 并没有提供这样的配置。

(针对Ext js 4来说,理想的相法是在Ext.picker.Date有一个 类似showWeek这样的配置项)

现有的解法

到网络上去看看基于Ext js 的解法:有找到两个

http://enikao.net/extjs/weeknumber/weeknumber.html

http://www.lubber.de/extjs/datepickerplus/

第一种解法在IE上work, 在其他浏览器上显示不出来, 直接忽视。

第二种解法支持 Ext js 2 和 Ext js 3 版本,但是不支持Ext js 4。凭着个人在Ext js 升级上的一些经验,一开始觉得把这个扩展升级到Ext js 4应该没有什么问题。鼓捣了半天,放弃了。 Ext js 3 升级到Ext js 4后, 日期页面的显示元素也做了修改, 旧版本用 tr td 居多,新版本中多了一些 div 和 a 元素。而且class 的名字也换掉了。这样看起来,升级阻力较大。只能自己来实现这个扩展了。

Ext JS 4 日期控件扩展

先贴上代码:

/********************************* 
* @author: oscar999 
* @Description: New Widgets Extend from Ext 
* @verion: V1.0 
**********************************/ /** 
* Date Picker with Week 
*/ 
Ext.define('Ext.ux.DatePickerWithWeek',{ 
extend: "Ext.picker.Date", 
alias : "widget.datepickerwithweek", 
width: 197, 
numWeeks: 6, 
renderTpl:[ 
'<div id="{id}-innerEl" role="grid">', 
'<div role="presentation" class="{baseCls}-header">', 
'<a id="{id}-prevEl" class="{baseCls}-prev {baseCls}-arrow" href="#" role="button" title="{prevText}" hidefocus="on" ></a>', 
'<div class="{baseCls}-month" id="{id}-middleBtnEl">{%this.renderMonthBtn(values, out)%}</div>', 
'<a id="{id}-nextEl" class="{baseCls}-next {baseCls}-arrow" href="#" role="button" title="{nextText}" hidefocus="on" ></a>', 
'</div>', 
'<table id="{id}-eventEl" class="{baseCls}-inner" cellspacing="0" role="grid">', 
'<thead role="presentation"><tr role="row">', 
'<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">', 
'<div class="{parent.baseCls}-column-header-inner">Wk</div>', 
'</th>', 
'<tpl for="dayNames">', 
'<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">', 
'<div class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>', 
'</th>', 
'</tpl>', 
'</tr></thead>', 
'<tbody role="presentation"><tr role="row">', 
'<tpl for="days">', 
'{#:this.isEndOfWeek}', 
'{#:this.isBeginOfWeek}', 
'<td role="gridcell" id="{[Ext.id()]}">', 
'<a role="presentation" hidefocus="on" class="{parent.baseCls}-date" href="#"></a>', 
'</td>', 
'</tpl>', 
'</tr></tbody>', 
'</table>', 
'<tpl if="showToday">', 
'<div id="{id}-footerEl" role="presentation" class="{baseCls}-footer">{%this.renderTodayBtn(values, out)%}</div>', 
'</tpl>', 
'</div>', 
{ 
firstInitial: function(value) { 
//alert(value); 
return Ext.picker.Date.prototype.getDayInitial(value); 
}, 
isBeginOfWeek: function(value){ 
//value--; 
//value--; 
var end = (value === 1 || (value-1)%7 === 0); 
return end ? '<td role="weekcell" id="{[Ext.id()]}"><a role="presentation"></a></td>' : ''; 
}, 
isEndOfWeek: function(value) { 
value--; 
var end = value % 7 === 0 && value !== 0; 
return end ? '</tr><tr role="row">' : ''; 
}, 
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){ 
this.callParent([date]); 
var me = this; 
var weekNodes = me.weekNodes; 
var curWeekStart = Ext.Date.clearTime(new Date(date.getFullYear(), date.getMonth(), 1)); 
var begMonWeek = Ext.Date.getWeekOfYear(curWeekStart); 
var firstDayOfMonth = Ext.Date.getFirstDayOfMonth(curWeekStart); 
if(firstDayOfMonth===0) 
{ 
begMonWeek +=1; 
} 
for(j=0;j<me.numWeeks;j++) 
{ 
weekNodes[j].innerHTML = begMonWeek.toString(); 
begMonWeek++; 
} 
}, 
onRender : function(container, position){ 
var me = this; 
me.callParent(arguments); 
me.cells = me.eventEl.select('tbody td[role="gridcell"]'); 
me.textNodes = me.eventEl.query('tbody td[role="gridcell"] a'); 
//begin extend 
me.weekcells= me.eventEl.select('tbody td[role="weekcell"]'); 
me.weekNodes= me.eventEl.query('tbody td[role="weekcell"] a'); 
//end extend 
me.mon(me.eventEl, { 
scope: me, 
mousewheel: me.handleMouseWheel, 
click: { 
//fn: me.handleDateClick, 
fn: function(){}, 
delegate: 'a.' + me.baseCls + '-date' 
} 
}); 
} 
/*,initComponent: function(){ 
this.callParent(); 
}*/ 
}); 
/* 
* Date Form field use Date Picker with Week 
*/ 
Ext.define('Ext.ux.DateFieldWithWeek',{ 
extend: "Ext.form.field.Date", 
alias : "widget.datefieldwithweek", 
/*initComponent: function(){ 
this.callParent(); 
},*/ 
createPicker : function(){ 
var me = this 
format = Ext.String.format; 
return new Ext.ux.DatePickerWithWeek({ 
pickerField: me, 
ownerCt: me.ownerCt, 
renderTo: document.body, 
floating: true, 
hidden: true, 
focusOnShow: 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(); 
} 
} 
}); 
} 
});

原理很简单:

1. 改写 renderTpl, 增加星期显示的列

2. 改写fullUpdate, 设置星期的值。 Ext 有提供getWeekOfYear这个方法可以获取星期

3. onRender。 这里需要特别注意的就是click 中的fn: me.handleDateClick 要给一个空函数,否则选日期的时候会执行两次。

Javascript 相关文章推荐
JQuery 学习笔记 element属性控制
Jul 23 Javascript
需要做特殊处理的DOM元素属性的访问
Nov 05 Javascript
js固定DIV高度,超出部分自动添加滚动条的简单方法
Jul 10 Javascript
JavaScript实现复制功能各浏览器支持情况实测
Jul 18 Javascript
showModelDialog弹出文件下载窗口的使用示例
Nov 19 Javascript
JS实现FLASH幻灯片图片切换效果的方法
Mar 04 Javascript
jQuery获取页面及个元素高度、宽度的总结——超实用
Jul 28 Javascript
浅析Node.js的Stream模块中的Readable对象
Jul 29 Javascript
vue的mixins属性详解
Mar 14 Javascript
原生js实现下拉选项卡
Nov 27 Javascript
使用pkg打包ThinkJS项目的方法步骤
Dec 30 Javascript
OpenLayers3实现鼠标移动显示坐标
Sep 25 Javascript
jquery.qrcode在线生成二维码使用示例
Aug 21 #Javascript
jquery设置控件位置的方法
Aug 21 #Javascript
获取表单控件原始(初始)值的方法
Aug 21 #Javascript
Js放到HTML文件中的哪个位置有什么区别
Aug 21 #Javascript
使用jQuery避免鼠标双击的解决方案
Aug 21 #Javascript
jquery ready(fn)事件使用介绍
Aug 21 #Javascript
javaScript面向对象继承方法经典实现
Aug 20 #Javascript
You might like
一个用于MySQL的PHP XML类
2006/10/09 PHP
PHP编码规范-php coding standard
2007/03/16 PHP
php实现Session存储到Redis
2015/11/11 PHP
使用JavaScript创建新样式表和新样式规则
2016/06/14 PHP
yii2 数据库读写分离配置示例
2017/02/10 PHP
异步加载script的代码
2011/01/12 Javascript
查找页面中所有类为test的结点的方法
2014/03/28 Javascript
js 数组去重的四种实用方法
2014/09/09 Javascript
nodejs教程之制作一个简单的文章发布系统
2014/11/21 NodeJs
js实现完全自定义可带多级目录的网页鼠标右键菜单方法
2015/02/28 Javascript
JS实现按比例缩放图片的方法(附C#版代码)
2015/12/08 Javascript
JavaScript遍历求解数独问题的主要思路小结
2016/06/12 Javascript
JS判断输入字符串长度实例代码(汉字算两个字符,字母数字算一个)
2016/08/02 Javascript
JS输出空格的简单实现方法
2016/09/08 Javascript
jQuery中的on与bind绑定事件区别实例详解
2017/02/28 Javascript
js获取css的各种样式并且设置他们的方法
2017/08/22 Javascript
Vue-router 切换组件页面时进入进出动画方法
2018/09/01 Javascript
vue实现鼠标经过动画
2019/10/16 Javascript
在nuxt中使用路由重定向的实例
2020/11/06 Javascript
ant design的table组件实现全选功能以及自定义分页
2020/11/17 Javascript
Python字符串和文件操作常用函数分析
2015/04/08 Python
Python中的高级函数map/reduce使用实例
2015/04/13 Python
pygame学习笔记(3):运动速率、时间、事件、文字
2015/04/15 Python
Python随手笔记之标准类型内建函数
2015/12/02 Python
教你用Python写安卓游戏外挂
2018/01/11 Python
如何把python项目部署到linux服务器
2020/08/26 Python
如何让PyQt5中QWebEngineView与JavaScript交互
2020/10/21 Python
Tarte Cosmetics官网:美国最受欢迎的化妆品公司之一
2017/08/24 全球购物
自我鉴定范文
2013/11/10 职场文书
群众路线教育党课主持词
2014/04/01 职场文书
干部作风建设工作总结
2014/10/29 职场文书
工作检讨书怎么写
2015/01/23 职场文书
党校毕业个人总结
2015/02/28 职场文书
员工工作表扬信
2015/05/05 职场文书
Java网络编程之UDP实现原理解析
2021/09/04 Java/Android
详解MySQL的内连接和外连接
2023/05/08 MySQL