ExtJs中定制日历控件——带下拉列表

效果图:

日历组件部分代码:

  	/*********************日历组件部分**************************** begin */
  	var dateArray = new Array();
	var printDateArray = function(){
	};
	
	/** 班次数据源 */
	var classStore = new Ext.data.JsonStore({
		url: "./jxy/attendsystem/queryClassComboAction", 
		autoLoad: true,
		method  : 'post', 
		fields: ['id','clasName'],
		root: 'data',
		remoteSort: true,  
        listeners:{  
            load : function(store, records, options ){      
                var data = { "id": "0", "clasName": "休息"};      
                var rs = [new Ext.data.Record(data)];      
                store.insert(0,rs);  
            }  
        }  
	});

  	Ext.MyDatePicker = Ext.extend(Ext.DatePicker, {
	
			todayText : '确定',
		    okText : ' 确定 ',
		    cancelText : '取消',
		    todayTip : '{0} (Spacebar)',
		    minText : 'This date is before the minimum date', 
		    maxText : 'This date is after the maximum date',
		    format : 'Y-m-d',
		    disabledDaysText : 'Disabled',
		    disabledDatesText : 'Disabled',
		    dayNames : Date.dayNames,
		    nextText : 'Next Month (Control+Right)',
		    prevText : 'Previous Month (Control+Left)',
		    monthYearText : 'Choose a month (Control+Up/Down to move years)',
		    startDay : 0,
		    showToday : true,
		    
		    initComponent : function(){
		        Ext.MyDatePicker.superclass.initComponent.call(this);
		        this.value = this.value ?
		                 this.value.clearTime() : new Date().clearTime();
		        this.addEvents(
		            'select'
		        );
		        if(this.handler){
		            this.on('select', this.handler,  this.scope || this);
		        }
		        this.initDisabledDays();
		    },
		    onRender : function(container, position){
		        var m = [
		             '<table cellspacing="0" width="90%" height="100%">',
		                '<tr>',
		                	'<td class="x-date-left">',
		                		'<a href="#" title="', this.prevText ,'"> </a>',
		                	'</td>',
		                	'<td class="x-date-middle" align="center"></td>',
		                	'<td class="x-date-right">',
		                		'<a href="#" title="', this.nextText ,'"> </a>',
		                	'</td>',
		                '</tr>',
		                '<tr>',
		                	'<td colspan="3">',
		                		'<table class="x-date-inner" cellspacing="0">',
		                			'<thead>',
		                				'<tr>'
		               	],
		                dn = this.dayNames,
		                i;
		        for(i = 0; i < 7; ){
		            var d = this.startDay+i;
		            if(d > 6){
		                d = d-7;
		            }
		            m.push('<th><div align="center"><span >', '星期'+dn[d].substr(0,1), '</span></div></th>');//星期标题
		            i = i + 1;
		        }
		        m[m.length] = '</tr></thead><tbody ><tr>';
		        for(i = 0; i < 42; ) {
		            if(i % 7 === 0 && i !== 0){
		                m[m.length] = '</tr><tr>';
		            }
		            //m[m.length] = '<td><a href="#" hidefocus="on" class="x-date-date" tabIndex="1"><em><span></span></em></a></td>';
		            m[m.length] = '<td height="45px" align="center" style="border:1 solid #F0F0F0"><h hidefocus="on" class="x-date-date" tabIndex="1" ><em><span></span></em></h></td>';
		            i = i + 1;
		        }
		        m.push('</tr></tbody></table></td></tr>',
		                this.showToday ? '<tr><td colspan="3" class="x-date-bottom" align="center"></td></tr>' : '',
		                '</table><div class="x-date-mp"></div>');
		
		        var el = document.createElement('div');
		        el.className = 'x-date-picker';
		        el.innerHTML = m.join('');
		
		        container.dom.insertBefore(el, position);
		
		        this.el = Ext.get(el);
		        this.eventEl = Ext.get(el.firstChild);
		
		        this.prevRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-left a'), {
		            handler: this.showPrevMonth,
		            scope: this,
		            preventDefault:true,
		            stopDefault:true
		        });
		
		        this.nextRepeater = new Ext.util.ClickRepeater(this.el.child('td.x-date-right a'), {
		            handler: this.showNextMonth,
		            scope: this,
		            preventDefault:true,
		            stopDefault:true
		        });
		
		        this.monthPicker = this.el.down('div.x-date-mp');
		        this.monthPicker.enableDisplayMode('block');
		
		        this.keyNav = new Ext.KeyNav(this.eventEl, {
		            'left' : function(e){
		                if(e.ctrlKey){
		                    this.showPrevMonth();
		                }else{
		                    this.update(this.activeDate.add('d', -1));
		                }
		            },
		
		            'right' : function(e){
		                if(e.ctrlKey){
		                    this.showNextMonth();
		                }else{
		                    this.update(this.activeDate.add('d', 1));
		                }
		            },
		
		            'up' : function(e){
		                if(e.ctrlKey){
		                    this.showNextYear();
		                }else{
		                    this.update(this.activeDate.add('d', -7));
		                }
		            },
		
		            'down' : function(e){
		                if(e.ctrlKey){
		                    this.showPrevYear();
		                }else{
		                    this.update(this.activeDate.add('d', 7));
		                }
		            },
		
		            'pageUp' : function(e){
		                this.showNextMonth();
		            },
		
		            'pageDown' : function(e){
		                this.showPrevMonth();
		            },
		
		            'enter' : function(e){
		                e.stopPropagation();
		                return true;
		            },
		
		            scope : this
		        });
		
		        this.el.unselectable();
		
		        this.cells = this.el.select('table.x-date-inner tbody td');
		        this.textNodes = this.el.query('table.x-date-inner tbody span');
		
		        this.mbtn = new Ext.Button({
		            text: ' ',
		            tooltip: this.monthYearText,
		            renderTo: this.el.child('td.x-date-middle', true)
		        });
		        this.mbtn.el.child('em').addClass('x-btn-arrow');
		
		        if(this.showToday){
		            this.todayKeyListener = this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday,  this);
		            var today = (new Date()).dateFormat(this.format);
		            this.todayBtn = new Ext.Button({
		                renderTo: this.el.child('td.x-date-bottom', true),
		                text: String.format(this.todayText, today),
		                tooltip: String.format(this.todayTip, today),
		                handler: this.selectToday,
		                scope: this
		            });
		        }
		        this.mon(this.eventEl, 'mousewheel', this.handleMouseWheel, this);
		        this.mon(this.eventEl, 'click', this.handleDateClick,  this);
		        this.mon(this.mbtn, 'click', this.showMonthPicker, this);
		        this.onEnable(true);
		    },
		    selectToday : function(){
		        if(this.todayBtn && !this.todayBtn.disabled){
		            printDateArray();	//返回结果
		        }
		    },
		    handleDateClick : function(e, t){
		        //this.fireEvent('select', this, this.value);
		    },
		    update : function(date, forceRefresh){
		        var vd = this.activeDate, vis = this.isVisible();
		        this.activeDate = date;
		        if(!forceRefresh && vd && this.el){
		            var t = date.getTime();
		            if(vd.getMonth() == date.getMonth() && vd.getFullYear() == date.getFullYear()){
		                this.cells.removeClass('x-date-selected');
		                this.cells.each(function(c){
		                   if(c.dom.firstChild.dateValue == t){
		                       c.addClass('x-date-selected');
		                       if(vis){
		                           Ext.fly(c.dom.firstChild).focus(50);
		                       }
		                       return false;
		                   }
		                });
		                return;
		            }
		        }
		        var days = date.getDaysInMonth();
		        var firstOfMonth = date.getFirstDateOfMonth();
		        var startingPos = firstOfMonth.getDay()-this.startDay;
		
		        if(startingPos <= this.startDay){
		            startingPos += 7;
		        }
		
		        var pm = date.add('mo', -1);
		        var prevStart = pm.getDaysInMonth()-startingPos;
		
		        var cells = this.cells.elements;
		        var textEls = this.textNodes;
		        days += startingPos;
		
		        // convert everything to numbers so it's fast
		        var day = 86400000;
		        var d = (new Date(pm.getFullYear(), pm.getMonth(), prevStart)).clearTime();
		        var today = new Date().clearTime().getTime();
		        var sel = date.clearTime().getTime();
		        var min = this.minDate ? this.minDate.clearTime() : Number.NEGATIVE_INFINITY;
		        var max = this.maxDate ? this.maxDate.clearTime() : Number.POSITIVE_INFINITY;
		        var ddMatch = this.disabledDatesRE;
		        var ddText = this.disabledDatesText;
		        var ddays = this.disabledDays ? this.disabledDays.join('') : false;
		        var ddaysText = this.disabledDaysText;
		        var format = this.format;
		
		        if(this.showToday){
		            var td = new Date().clearTime();
		            var disable = (td < min || td > max ||
		                (ddMatch && format && ddMatch.test(td.dateFormat(format))) ||
		                (ddays && ddays.indexOf(td.getDay()) != -1));
		
		            if(!this.disabled){
		                this.todayBtn.setDisabled(disable);
		                this.todayKeyListener[disable ? 'disable' : 'enable']();
		            }
		        }
		
		        var setCellClass = function(cal, cell){
		            cell.title = '';
		            var t = d.getTime();
		            cell.firstChild.dateValue = t;
		            if(t == today){
		                cell.className += ' x-date-today';
		                cell.title = cal.todayText;
		            }
		            if(t == sel){
		                cell.className += ' x-date-selected';
		                if(vis){
		                    Ext.fly(cell.firstChild).focus(50);
		                }
		            }
		            // disabling
		            if(t < min) {
		                cell.className = ' x-date-disabled';
		                cell.title = cal.minText;
		                return;
		            }
		            if(t > max) {
		                cell.className = ' x-date-disabled';
		                cell.title = cal.maxText;
		                return;
		            }
		            if(ddays){
		                if(ddays.indexOf(d.getDay()) != -1){
		                    cell.title = ddaysText;
		                    cell.className = ' x-date-disabled';
		                }
		            }
		            if(ddMatch && format){
		                var fvalue = d.dateFormat(format);
		                if(ddMatch.test(fvalue)){
		                    cell.title = ddText.replace('%0', fvalue);
		                    cell.className = ' x-date-disabled';
		                }
		            }
		        };
		
		        var i = 0;
		        for(; i < startingPos; ) {
		            var tempId = "fruit"+i;
		            d.setDate(d.getDate()+1);
		            var fvalue = d.dateFormat(format);
		            textEls[i].innerHTML = '<div align="center"><font size ="2" color = "#8B8378" >'+(++prevStart)+'</font>'+'<br></div>';
		            cells[i].className = 'x-date-prevday';
		            setCellClass(this, cells[i]);
		            i = i + 1;
		        }
		        for(; i < days; ){
		            var divId = "div"+i;
		            var intDay = i - startingPos + 1;
		            d.setDate(d.getDate()+1);
		            var fvalue = d.dateFormat(format);
		            var comboId = "combo"+fvalue+"-"+i;
		            var clas = new Ext.form.ComboBox({
						store: classStore,
						id: comboId,
						width: 60,
						displayField: 'clasName',
						valueField: 'id',
						hiddenName: 'clasName1',
						typeAhead: true,
						triggerAction: 'all',
						forceSelection: true,
						selectOnFocus: true,
						mode: 'remote',
						editable: false
					});
					//classStore.on('load',function(){Ext.getCmp(comboId).setValue("0");});
		            textEls[i].innerHTML = '<div align="center"><font size ="2">'+(intDay)+'</font>'+'<br><div id="'+divId+'"></div></div>';
					clas.render(divId);
					
		            cells[i].className = 'x-date-active';
		            setCellClass(this, cells[i]);
		            clas.on('select',function(combo,record,index ){
	            		var str = "["+combo.id.substring(5,15)+" "+combo.getValue()+"]"
	            		dateArray[combo.id.substring(16,combo.id.length)] = str;
					}); 
					
					i = i + 1; 
		        }
		        var extraDays = 0;
		        for(; i < 42; ) {
		             var tempId = "fruit"+i;
		             d.setDate(d.getDate()+1);
		             var fvalue = d.dateFormat(format);
		             textEls[i].innerHTML = '<div align="center"><font size ="2" color = "#8B8378">'+(++extraDays)+'</font>'+'<br></div>';
		             cells[i].className = 'x-date-nextday';
		             setCellClass(this, cells[i]);
		             i = i + 1;
		        }
		        this.mbtn.setText(this.monthNames[date.getMonth()] + ' ' + date.getFullYear());
		
		        if(!this.internalRender){
		            var main = this.el.dom.firstChild;
		            var w = main.offsetWidth;
		            this.el.setWidth(w + this.el.getBorderWidth('lr'));
		            Ext.fly(main).setWidth(w);
		            this.internalRender = true;
		            // opera does not respect the auto grow header center column
		            // then, after it gets a width opera refuses to recalculate
		            // without a second pass
		            if(Ext.isOpera && !this.secondPass){
		                main.rows[0].cells[1].style.width = (w - (main.rows[0].cells[0].offsetWidth+main.rows[0].cells[2].offsetWidth)) + 'px';
		                this.secondPass = true;
		                this.update.defer(10, this, [date]);
		            }
		        }
		    },
		    beforeDestroy : function() {
		        if(this.rendered){
		            Ext.destroy(
		                this.keyNav,
		                this.monthPicker,
		                this.eventEl,
		                this.mbtn,
		                this.nextRepeater,
		                this.prevRepeater,
		                this.cells.el,
		                this.todayBtn
		            );
		            delete this.textNodes;
		            delete this.cells.elements;
		        }
		    }
		});
		Ext.reg('mydatepicker', Ext.MyDatePicker);
  	var myDate = new Ext.MyDatePicker();
  	/*********************日历组件部分**************************** end */


在每个日期格中有一个下拉列表,这里面可以是在本地定义,也可以在数据库中查询,这里的处理是:下拉框中选择了就按照相对应的key来存,如果没有选择的话就按照空来处理,单击【确定】按钮后获取的结果格式如下:

",,,,,,[2013-06-01 1],[2013-06-02 2],,,,,,,,,,,,,,,[2013-06-17 1],[2013-06-18 2],[2013-06-19 3],,,,,,,[2013-06-26 2]"

转成字符串(传递参数识别的类型):

	if(dateArray != null && dateArray != "") {
		content = dateArray.join(',');	//数组的话,不识别,要转换成字符串才可以
	}

 

引用日历组件的部分代码:

		, {
	   		xtype: 'panel',
	   		style: 'margin-left:50;',
	   		layout: 'column',
	   		id: 'calendarArea',
	   		width: 700,
	   		height: 400,
	   		border: true,
	   		items: [{
	   			layout: 'form',
	   			width: '98%',
	   			height: '98%',
				items:[
					/** 这里放置日历控件 */
					myDate
				]
			}]
		}


注意:单击【确定】按钮后获取的值可以根据用户自己的需求来定义,代码是在3个for循环中修改。

		        var i = 0;
		        for(; i < startingPos; ) {
		            var tempId = "fruit"+i;
		            d.setDate(d.getDate()+1);
		            var fvalue = d.dateFormat(format);
		            textEls[i].innerHTML = '<div align="center"><font size ="2" color = "#8B8378" >'+(++prevStart)+'</font>'+'<br></div>';
		            cells[i].className = 'x-date-prevday';
		            setCellClass(this, cells[i]);
		            i = i + 1;
		        }
		        for(; i < days; ){
		            var divId = "div"+i;
		            var intDay = i - startingPos + 1;
		            d.setDate(d.getDate()+1);
		            var fvalue = d.dateFormat(format);
		            var comboId = "combo"+fvalue+"-"+i;
		            var clas = new Ext.form.ComboBox({
						store: classStore,
						id: comboId,
						width: 60,
						displayField: 'clasName',
						valueField: 'id',
						hiddenName: 'clasName1',
						typeAhead: true,
						triggerAction: 'all',
						forceSelection: true,
						selectOnFocus: true,
						mode: 'remote',
						editable: false
					});
					//classStore.on('load',function(){Ext.getCmp(comboId).setValue("0");});
		            textEls[i].innerHTML = '<div align="center"><font size ="2">'+(intDay)+'</font>'+'<br><div id="'+divId+'"></div></div>';
					clas.render(divId);
					
		            cells[i].className = 'x-date-active';
		            setCellClass(this, cells[i]);
		            clas.on('select',function(combo,record,index ){
	            		var str = "["+combo.id.substring(5,15)+" "+combo.getValue()+"]"
	            		dateArray[combo.id.substring(16,combo.id.length)] = str;
					}); 
					
					i = i + 1; 
		        }
		        var extraDays = 0;
		        for(; i < 42; ) {
		             var tempId = "fruit"+i;
		             d.setDate(d.getDate()+1);
		             var fvalue = d.dateFormat(format);
		             textEls[i].innerHTML = '<div align="center"><font size ="2" color = "#8B8378">'+(++extraDays)+'</font>'+'<br></div>';
		             cells[i].className = 'x-date-nextday';
		             setCellClass(this, cells[i]);
		             i = i + 1;
		        }



如果有问题,欢迎指正和讨论。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值