[Ext JS 4] 实战之 带week(星期)的日期选择控件

本文介绍如何在ExtJS4中扩展日期选择器组件,以显示星期信息,包括一年中的第几周。通过改写renderTpl和fullUpdate方法,实现了自定义的DatePickerWithWeek组件。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

Ext JS 3 和 Ext JS 4中都有提供日期选择的组件(当然早期版本也有)。

 

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

遗憾的是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 要给一个空函数,否则选日期的时候会执行两次。

 

 

 

 

之前在网上想找个简单易用的周日历选择插件,发现这种前端周日历插件很少,而且很多文章写的周的算法都不是统的,所以自己实现了个基于jquery的周日历插件(还支持跳转到指定年份和周哦)。 插件中周的算法:每周以周日为起始,第周以每年第星期四所在的周为第周(网上找的好像这个算法比较正规) 实现的效果是在手机端,也可以在PC端用,毕竟功能才是主要的。如果觉得样式不入眼可以自行随意修改。 //调用周日历方法 var weekfn = new jcalendar_week({ element: "#jcalendar_week",//填充日历的dom元素 dayaddclass:function(date){ //添加某天时给添加类名(参数:1.日)(返回类名字符串,多个以空格分开) return ""; }, dayclick:function(date,obj){ //day点击事件(参数:1.日,2.所点击DOM元素) $(obj).addClass("calendar_day_act").siblings().removeClass("calendar_day_act"); } }); 点击上方显示当前年份和周的DOM部分可选择并跳转到指定年份和周。 插件提供的方法: //获取周第天方法weekfirstdate(),传入年份和周数 console.log(weekfn.weekfirstdate(2018,36)); //获取传入日为当年第几周getweeknum(),传入年,月,日(注:这里的月份从0开始) console.log(weekfn.getweeknum(2018,0,16)); //跳转到指定周confirmweek(),传入年份和周数 weekfn.confirmweek(getyear,getweek); //跳转到本周nowweek() weekfn.nowweek();
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值