目的:
ExtJS中提供了下拉日期选择控件Ext.form.field.Date与下拉时间选择控件Ext.form.field.Time。不过没有一个在选择日期时选择时间的控件datetimefield。目的就是运用自定义组件的方法,来扩展下拉日期选择控件Ext.form.field.Date,在下拉框中添加时间选择的组件。目标效果:
第一步:继承Ext.picker.Date,创建My.picker.DateTime类
1 Ext.define('My.picker.DateTime', { 2 extend: 'Ext.picker.Date', 3 alias: 'widget.datetimepicker', 4 okText:'确定', 5 okTip:'确定', 6 7 renderTpl: [ 8 '<div id="{id}-innerEl" data-ref="innerEl" role="grid">', 9 '<div role="presentation" class="{baseCls}-header">', 10 '<a id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="button" title="{prevText}" hidefocus="on" ></a>', 11 '<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month">{%this.renderMonthBtn(values, out)%}</div>', 12 '<a id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="button" title="{nextText}" hidefocus="on" ></a>', 13 '</div>', 14 '<table id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" cellspacing="0" role="grid">', 15 '<thead role="presentation"><tr role="row">', 16 '<tpl for="dayNames">', 17 '<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">', 18 '<div class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>', 19 '</th>', 20 '</tpl>', 21 '</tr></thead>', 22 '<tbody role="presentation"><tr role="row">', 23 '<tpl for="days">', 24 '{#:this.isEndOfWeek}', 25 '<td role="gridcell" id="{[Ext.id()]}">', 26 // The '#' is needed for keyboard navigation 27 '<a href="#" role="button" hidefocus="on" class="{parent.baseCls}-date"></a>', 28 '</td>', 29 '</tpl>', 30 '</tr></tbody>', 31 '</table>', 32 '<tpl if="showToday">', 33 '<div id="{id}-footerEl" data-ref="footerEl" role="presentation" class="{baseCls}-footer">{%this.renderTodayBtn(values, out)%}</div>', 34 '</tpl>', 35 '</div>', 36 { 37 firstInitial: function(value) { 38 return Ext.picker.Date.prototype.getDayInitial(value); 39 }, 40 isEndOfWeek: function(value) { 41 // convert from 1 based index to 0 based 42 // by decrementing value once. 43 value--; 44 var end = value % 7 === 0 && value !== 0; 45 return end ? '</tr><tr role="row">' : ''; 46 }, 47 renderTodayBtn: function(values, out) { 48 Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out); 49 }, 50 renderMonthBtn: function(values, out) { 51 Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out); 52 } 53 } 54 ] 55 });
其中renderTpl部分与后面按钮渲染部分出自源码。
效果:
第二步:在原布局中添加3个组件用来选取时、分、秒,添加一个确认按钮,并在组件渲染之前,将自定义添加的时、分、秒和确认按钮进行初始化
1 Ext.define('My.picker.DateTime', { 2 extend: 'Ext.picker.Date', 3 alias: 'widget.datetimepicker', 4 okText:'确定', 5 okTip:'确定', 6 7 renderTpl: [ 8 '<div id="{id}-innerEl" data-ref="innerEl" role="grid">', 9 '<div role="presentation" class="{baseCls}-header">', 10 '<a id="{id}-prevEl" data-ref="prevEl" class="{baseCls}-prev {baseCls}-arrow" role="button" title="{prevText}" hidefocus="on" ></a>', 11 '<div id="{id}-middleBtnEl" data-ref="middleBtnEl" class="{baseCls}-month">{%this.renderMonthBtn(values, out)%}</div>', 12 '<a id="{id}-nextEl" data-ref="nextEl" class="{baseCls}-next {baseCls}-arrow" role="button" title="{nextText}" hidefocus="on" ></a>', 13 '</div>', 14 '<table id="{id}-eventEl" data-ref="eventEl" class="{baseCls}-inner" cellspacing="0" role="grid">', 15 '<thead role="presentation"><tr role="row">', 16 '<tpl for="dayNames">', 17 '<th role="columnheader" class="{parent.baseCls}-column-header" title="{.}">', 18 '<div class="{parent.baseCls}-column-header-inner">{.:this.firstInitial}</div>', 19 '</th>', 20 '</tpl>', 21 '</tr></thead>', 22 '<tbody role="presentation"><tr role="row">', 23 '<tpl for="days">', 24 '{#:this.isEndOfWeek}', 25 '<td role="gridcell" id="{[Ext.id()]}">', 26 // The '#' is needed for keyboard navigation 27 '<a href="#" role="button" hidefocus="on" class="{parent.baseCls}-date"></a>', 28 '</td>', 29 '</tpl>', 30 '</tr></tbody>', 31 32 '<table id="{id}-timeEl" style="table-layout:auto;width:auto;margin:0 3px;" class="x-datepicker-inner" cellspacing="0">', 33 '<tbody><tr>', 34 '<td>{%this.renderHourBtn(values,out)%}</td>', 35 '<td>{%this.renderMinuteBtn(values,out)%}</td>', 36 '<td>{%this.renderSecondBtn(values,out)%}</td>', 37 '</tr></tbody>', 38 '</table>', 39 40 '<tpl if="showToday">', 41 '<div id="{id}-footerEl" role="presentation" class="{baseCls}-footer">{%this.renderOkBtn(values, out)%}{%this.renderTodayBtn(values, out)%}</div>', 42 '</tpl>', 43 '</div>', 44 { 45 firstInitial: function(value) { 46 return Ext.picker.Date.prototype.getDayInitial(value); 47 }, 48 isEndOfWeek: function(value) { 49 // convert from 1 based index to 0 based 50 // by decrementing value once. 51 value--; 52 var end = value % 7 === 0 && value !== 0; 53 return end ? '</tr><tr role="row">' : ''; 54 }, 55 renderTodayBtn: function(values, out) { 56 Ext.DomHelper.generateMarkup(values.$comp.todayBtn.getRenderTree(), out); 57 }, 58 renderMonthBtn: function(values, out) { 59 Ext.DomHelper.generateMarkup(values.$comp.monthBtn.getRenderTree(), out); 60 }, 61 renderHourBtn: function(values, out) { 62 Ext.DomHelper.generateMarkup(values.$comp.hourBtn.getRenderTree(), out); 63 }, 64 renderMinuteBtn: function(values, out) { 65 Ext.DomHelper.generateMarkup(values.$comp.minuteBtn.getRenderTree(), out); 66 }, 67 renderSecondBtn: function(values, out) { 68 Ext.DomHelper.generateMarkup(values.$comp.secondBtn.getRenderTree(), out); 69 }, 70 renderOkBtn: function(values, out) { 71 Ext.DomHelper.generateMarkup(values.$comp.okBtn.getRenderTree(), out); 72 } 73 } 74 ], 75 beforeRender: function () { 76 var me = this; 77 me.hourBtn=new Ext.form.field.Number({ 78 minValue:0, 79 maxValue:23, 80 step:1, 81 width:55 82 }); 83 me.minuteBtn=new Ext.form.field.Number({ 84 minValue:0, 85 maxValue:59, 86 step:1, 87 width:70, 88 labelWidth:10, 89 fieldLabel:' ' 90 }); 91 me.secondBtn=new Ext.form.field.Number({ 92 minValue:0, 93 maxValue:59, 94 step:1, 95 width:70, 96 labelWidth:10, 97 fieldLabel:' ' 98 }); 99 100 me.okBtn = new Ext.button.Button({ 101 ownerCt: me, 102 ownerLayout: me.getComponentLayout(), 103 text: me.okText, 104 tooltip: me.okTip, 105 tooltipType:'title', 106 handler:me.okHandler, 107 scope: me 108 }); 109 me.callParent(); 110 } 111 });
效果:
第三步:添加按钮事件绑定,各种内部逻辑的处理,获取选定的时间等等