1、CSS中加上(图片路径自己修改就行,glass-bg.gif在ext包下面搜一下,肯定有。arrowLeft和arrowRight也在example里有):
.minutecss{
padding:4px;
height:100%;
border-top: 1px solid #a3bad9;
background: #dfecfb url(../ext/resources/images/state/shared/glass-bg.gif) repeat-x left top;
}
.y-hour-middle,.y-hour-left,.y-hour-right {
font:bold 11px "sans serif", tahoma, verdana, helvetica;
overflow:hidden;
}
.y-hour-right, .y-hour-left {
width:18px;
}
.y-hour-right{
text-align:right;
}
.y-hour-middle {
padding-top:2px;
padding-bottom:2px;
color:#5C95FE;
}
.y-hour-right a, .y-hour-left a{
display:block;
width:16px;
height:16px;
background-position: center;
background-repeat: no-repeat;
cursor:pointer;
}
.y-hour-right a {
background-image: url(../images/arrowRight.gif);
margin-right:2px;
}
.y-hour-left a{
background-image: url(../images/arrowLeft.gif);
margin-left:2px;
}
.y-minute-middle,.y-minute-left,.y-minute-right {
font:bold 11px "sans serif", tahoma, verdana, helvetica;
overflow:hidden;
}
.y-minute-right, .y-minute-left {
width:18px;
}
.y-minute-right{
text-align:right;
}
.y-minute-middle {
padding-top:2px;
padding-bottom:2px;
color:#5C95FE;
}
.y-minute-right a, .y-minute-left a{
display:block;
width:16px;
height:16px;
background-position: center;
background-repeat: no-repeat;
cursor:pointer;
}
.y-minute-right a {
background-image: url(../images/arrowRight.gif);
margin-right:2px;
}
.y-minute-left a{
background-image: url(../images/arrowLeft.gif);
margin-left:2px;
}
.y-second-middle,.y-second-left,.y-second-right {
font:bold 11px "sans serif", tahoma, verdana, helvetica;
overflow:hidden;
}
.y-second-right, .y-second-left {
width:18px;
}
.y-second-right{
text-align:right;
}
.y-second-middle {
padding-top:2px;
padding-bottom:2px;
color:#5C95FE;
}
.y-second-right a, .y-second-left a{
display:block;
width:16px;
height:16px;
background-position: center;
background-repeat: no-repeat;
cursor:pointer;
}
.y-second-right a {
background-image: url(../images/arrowRight.gif);
margin-right:2px;
}
.y-second-left a{
background-image: url(../images/arrowLeft.gif);
margin-left:2px;
}
2.JS文件里加上如下代码
/********** CONSTRUCTOR ******
* Parameters: as per Ext.DatePicker
****/
DatetimePicker = function(config){
/** Call superclass constructor **/
DatetimePicker.superclass.constructor.call(this, config);
};
// 重写datePicker
Ext.extend(DatetimePicker, Ext.DatePicker, {
/**
* Method Name: onRender
* Description: as per Ext.DatePicker's onRender, except renders year in its own cell with arrow-changers in additional columns
* Parameters: as per Ext.DatePicker's onRender
* Returns: n/a
* Throws: n/a
*/
// 点击今天 按钮
selectToday : function(){
this.setValue(new Date().clearTime());
var val1 = this.value;
val1.setHours(this.theHours);
val1.setMinutes(this.theMinutes);
val1.setSeconds(this.theSeconds);
this.fireEvent("select", this, val1);
},
// 选择某个日期
handleDateClick : function(e, t){
e.stopEvent();
if(t.dateValue && !Ext.fly(t.parentNode).hasClass("x-date-disabled")){
this.setValue(new Date(t.dateValue));
var val1 = this.value;
val1.setHours(this.theHours);
val1.setMinutes(this.theMinutes);
val1.setSeconds(this.theSeconds);
this.fireEvent("select", this, val1);
}
},
onRender : function(container, position){
var m = [
'<table cellspacing="0">',
'<tr><td colspan="3"><table cellspacing="0" width="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></table></td></tr>',
'<tr><td colspan="3"><table class="x-date-inner" cellspacing="0"><thead><tr>'];
var dn = this.dayNames;
for(var i = 0; i < 7; i++){
var d = this.startDay+i;
if(d > 6){
d = d-7;
}
m.push("<th><span>", dn[d].substr(0,1), "</span></th>");
}
m[m.length] = "</tr></thead><tbody><tr>";
for(i = 0; i < 42; i++) {
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] = '</tr></tbody></table></td></tr><tr><td class="minutecss"><table cellspacing="0" ><tr>';
m[m.length] = '<td class="y-hour-left"><a href="#" title="down"> </a></td><td class="y-hour-middle" align="center"></td><td class="y-hour-right"><a href="#" title="up"> </a></td>';
m[m.length] = '<td class="y-minute-left"><a href="#" title="down"> </a></td><td class="y-minute-middle" align="center"></td><td class="y-minute-right"><a href="#" title="up"> </a></td>';
m[m.length] = '<td class="y-second-left"><a href="#" title="down"> </a></td><td class="y-second-middle" align="center"></td><td class="y-second-right"><a href="#" title="up"> </a></td>';
m[m.length] = '</tr></table></td><td colspan="2" class="x-date-bottom" align="center"></td></tr></table><div class="x-date-mp"></div>';
// 创建一个用于显示显示选择日期和时间的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);
try{
// 24小时
var divHour = this.createSelectDiv(24,'时')
this.createSelectDiv(24,'时');
el.parentNode.appendChild(divHour);
// 60分
var divMinute = this.createSelectDiv(60,'分');
el.parentNode.appendChild(divMinute);
// 60秒
var divSecond = this.createSelectDiv(60,'秒');
el.parentNode.appendChild(divSecond);
// 点击小时
new Ext.util.ClickRepeater(this.el.child("td.y-hour-middle"), {
handler: function(){
divMinute.style.display = "none";
divSecond.style.display = "none";
divHour.style.display = "block";
divHour.style.top = 80+"px";
divHour.style.left = 0+"px";
}.createDelegate(this),
scope: this
});
// 点击分钟
new Ext.util.ClickRepeater(this.el.child("td.y-minute-middle"), {
handler: function(){
divSecond.style.display = "none";
divHour.style.display = "none";
divMinute.style.display = "block";
divMinute.style.top = 100+"px";
divMinute.style.left = 50+"px";
}.createDelegate(this),
scope: this
});
// 点击秒
new Ext.util.ClickRepeater(this.el.child("td.y-second-middle"), {
handler: function(){
divHour.style.display = "none";
divMinute.style.display = "none";
divSecond.style.display = "block";
divSecond.style.top = 100+"px";
divSecond.style.left = 120+"px";
}.createDelegate(this),
scope: this
});
}catch(e){
alert(e.message);
}
//=====================日期左右选择
new Ext.util.ClickRepeater(this.el.child("td.x-date-left a"), {
handler: this.showPrevMonth,
scope: this,
preventDefault:true,
stopDefault:true
});
new Ext.util.ClickRepeater(this.el.child("td.x-date-right a"), {
handler: this.showNextMonth,
scope: this,
preventDefault:true,
stopDefault:true
});
//=====================时左右选择
new Ext.util.ClickRepeater(this.el.child("td.y-hour-left a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
// 如果当前小时为0,左点击后,变为24,在进入下一步
if(this.theHours == 0)
this.theHours = 24;
if(this.theHours>0){
this.theHours--;
this.theHours = this.theHours %24;
var txt = '';
if(this.theHours<10){
txt='0'+this.theHours;
}
else{
txt= this.theHours;
}
this.hourLabel.update(txt+'时');
}
}.createDelegate(this),
scope: this
});
new Ext.util.ClickRepeater(this.el.child("td.y-hour-right a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
this.theHours++;
this.theHours = this.theHours % 24;
var txt = '';
if(this.theHours<10){
txt='0'+this.theHours;
}
else{
txt= this.theHours;
}
this.hourLabel.update(txt+'时');
}.createDelegate(this),
scope: this
});
//=====================分钟左右选择
new Ext.util.ClickRepeater(this.el.child("td.y-minute-left a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
// 如果当前分钟为0,左点击后,变为60,在进入下一步
if(this.theMinutes == 0)
this.theMinutes = 60;
if(this.theMinutes>0){
this.theMinutes--;
this.theMinutes = this.theMinutes % 60;
var txt = '';
if(this.theMinutes<10){
txt='0'+this.theMinutes;
}
else{
txt= this.theMinutes;
}
this.minuteLabel.update(txt+'分');
}
}.createDelegate(this),
scope: this
});
new Ext.util.ClickRepeater(this.el.child("td.y-minute-right a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
this.theMinutes++;
this.theMinutes = this.theMinutes % 60;
var txt = '';
if(this.theMinutes<10){
txt='0'+this.theMinutes;
}
else{
txt= this.theMinutes;
}
this.minuteLabel.update(txt+'分');
}.createDelegate(this),
scope: this
});
//=====================秒左右选择
new Ext.util.ClickRepeater(this.el.child("td.y-second-left a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
// 如果当前秒为0,左点击后,变为60,在进入下一步
if(this.theSeconds == 0)
this.theSeconds = 60;
if(this.theSeconds>0){
this.theSeconds--;
this.theSeconds = this.theSeconds % 60;
var txt = '';
if(this.theSeconds<10){
txt='0'+this.theSeconds;
}
else{
txt= this.theSeconds;
}
this.secondLabel.update(txt+'秒');
}
}.createDelegate(this),
scope: this
});
new Ext.util.ClickRepeater(this.el.child("td.y-second-right a"), {
handler: function(){
this.hiddenSelectDiv(divHour,divMinute,divSecond);
this.theSeconds++;
this.theSeconds = this.theSeconds % 60;
var txt = '';
if(this.theSeconds<10){
txt='0'+this.theSeconds;
}
else{
txt= this.theSeconds;
}
this.secondLabel.update(txt+'秒');
}.createDelegate(this),
scope: this
});
this.eventEl.on("mousewheel", this.handleMouseWheel, this);
this.monthPicker = this.el.down('div.x-date-mp');
this.monthPicker.enableDisplayMode('block');
var kn = new Ext.KeyNav(this.eventEl, {
"left" : function(e){
e.ctrlKey ?
this.showPrevMonth() :
this.update(this.activeDate.add("d", -1));
},
"right" : function(e){
e.ctrlKey ?
this.showNextMonth() :
this.update(this.activeDate.add("d", 1));
},
"up" : function(e){
e.ctrlKey ?
this.showNextYear() :
this.update(this.activeDate.add("d", -7));
},
"down" : function(e){
e.ctrlKey ?
this.showPrevYear() :
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.eventEl.on("click", this.handleDateClick, this, {delegate: "a.x-date-date"});
this.eventEl.addKeyListener(Ext.EventObject.SPACE, this.selectToday, 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.on('click', this.showMonthPicker, this);
this.mbtn.el.child(this.mbtn.menuClassTarget).addClass("x-btn-with-menu");
var dt1 = new Date();
var txt = '';
this.hourLabel = this.el.child("td.y-hour-middle");
this.theHours = dt1.getHours();
if(this.theHours<10){
txt='0'+this.theHours;
}
else{
txt= this.theHours;
}
this.hourLabel.update(txt+'时');
this.minuteLabel = this.el.child("td.y-minute-middle");
this.theMinutes = dt1.getMinutes();
if(this.theMinutes<10){
txt='0'+this.theMinutes;
}
else{
txt= this.theMinutes;
}
this.minuteLabel.update(txt+'分');
this.secondLabel = this.el.child("td.y-second-middle");
this.theSeconds = dt1.getSeconds();
if(this.theSeconds<10){
txt='0'+this.theSeconds;
}
else{
txt= this.theSeconds;
}
this.secondLabel.update(txt+'秒');
var today = (new Date()).dateFormat(this.format);
var 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
});
if(Ext.isIE){
this.el.repaint();
}
this.update(this.value);
},
/**
* Method Name: update
* Description: as per Ext.DatePicker's update, except updates year label in its own cell
* Parameters: as per Ext.DatePicker's update
* Returns: n/a
* Throws: n/a
*/
update : function(date){
var vd = this.activeDate;
this.activeDate = date;
if(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");
setTimeout(function(){
try{c.dom.firstChild.focus();}catch(e){}
}, 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;
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";
setTimeout(function(){
try{cell.firstChild.focus();}catch(e){}
}, 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; i++) {
textEls[i].innerHTML = (++prevStart);
d.setDate(d.getDate()+1);
cells[i].className = "x-date-prevday";
setCellClass(this, cells[i]);
}
for(; i < days; i++){
intDay = i - startingPos + 1;
textEls[i].innerHTML = (intDay);
d.setDate(d.getDate()+1);
cells[i].className = "x-date-active";
setCellClass(this, cells[i]);
}
var extraDays = 0;
for(; i < 42; i++) {
textEls[i].innerHTML = (++extraDays);
d.setDate(d.getDate()+1);
cells[i].className = "x-date-nextday";
setCellClass(this, cells[i]);
}
this.mbtn.setText(this.monthNames[date.getMonth()] + " " + date.getFullYear());
if(this.theHours<10){
txt='0'+this.theHours;
}
else{
txt= this.theHours;
}
this.hourLabel.update(txt+'时');
if(this.theMinutes<10){
txt='0'+this.theMinutes;
}
else{
txt= this.theMinutes;
}
this.minuteLabel.update(txt+'分');
if(this.theSeconds<10){
txt='0'+this.theSeconds;
}
else{
txt= this.theSeconds;
}
this.secondLabel.update(txt+'秒');
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]);
}
}
},
/*
* 创建选择时、分、秒的div
*/
createSelectDiv : function(number,type){
var div = document.createElement("div");
div.style.display = "none";
div.style.position = "absolute";
div.style.width = "50";
div.style.backgroundColor = "white";
div.style.border = "#86C9F0 1px solid";
var tbody = document.createElement("tbody");
var table = document.createElement("table");
table.appendChild(tbody);
var tr = document.createElement("tr");
var condition = number==24;
var instance = this;
for(i=0;i<number;i++){
var td = document.createElement("td");
td.align = "center";
td.style.border = "#F0F7FF 2px solid";
td.style.fontSize = "12px";
td.appendChild(document.createTextNode(i+""));
td.onclick = function(){
var txt = this.firstChild.nodeValue;
txt = (txt<10 ? '0':'') + txt;
if(type == '时'){
instance.hourLabel.update(txt+type);
instance.theHours = this.firstChild.nodeValue;
}else if(type == '分'){
instance.minuteLabel.update(txt+type);
instance.theMinutes = this.firstChild.nodeValue;
}else if(type == '秒'){
instance.secondLabel.update(txt+type);
instance.theSeconds = this.firstChild.nodeValue;
}
div.style.display = "none";
}
if(condition){
if(i != 0 && i%6 == 0){
tbody.appendChild(tr);
// 重新创建tr
tr = document.createElement("tr");
}
tr.appendChild(td);
}else{
if(i%5 == 0){
if(i != 0 && i%20 == 0){
tbody.appendChild(tr);
// 重新创建tr
tr = document.createElement("tr");
}
tr.appendChild(td);
}
}
}
// 添加最后一个tr
tbody.appendChild(tr);
div.appendChild(table);
return div;
},
/**
* 隐藏选择时分秒DIV
*/
hiddenSelectDiv : function(divHour,divMinute,divSecond){
divHour.style.display = "none";
divMinute.style.display = "none";
divSecond.style.display = "none";
},
// createTd : function(div,type){
// var td = document.createElement("td");
// td.align = "center";
// td.style.border = "#F0F7FF 2px solid";
// td.style.fontSize = "12px";
// td.appendChild(document.createTextNode(i+""));
// var instance = this;
// td.onclick = function(){
// if(type == '时'){
// instance.hourLabel.update(this.firstChild.nodeValue+type);
// instance.theHours = this.firstChild.nodeValue;
// }else if(type == '分'){
// instance.minuteLabel.update(this.firstChild.nodeValue+type);
// instance.theMinutes = this.firstChild.nodeValue;
// }else if(type == '秒'){
// instance.secondLabel.update(this.firstChild.nodeValue+type);
// instance.theSeconds = this.firstChild.nodeValue;
// }
// div.style.display = "none";
// }
// return td;
// },
/***** Public Instance Variables *****/
/**
* Variable Name: nextYearText, prevYearText
* Description: Hover text for the previous year and next year arrow changers
* Default: as shown
* Type: string
*/
nextYearText: 'Next Year (Control+Up)',
prevYearText: 'Previous Year (Control+Down)'
});
/** Class Name: DatetimeItem
* Inherits From: Ext.menu.Adapter
* Contains: DatetimePicker
* Purpose: Effectively overrides Ext.menu.DateItem so that it contains DatetimePicker instead of Ext.DatePicker
* Note: ORIGINAL and NEW comments are used to denote what differs from Ext.menu.DateItem
*/
DatetimeItem = function(config){
DatetimeItem.superclass.constructor.call(this , config);
//this.picker = new DatetimePicker(config);
this.component = new DatetimePicker(config);
this.picker = this.component;
this.addEvents({select: true});
this.picker.on("render", function(picker){
picker.getEl().swallowEvent("click");
picker.container.addClass("x-menu-date-item");
});
this.picker.on("select", this.onSelect, this);
};
Ext.extend(DatetimeItem, Ext.menu.BaseItem, {
// private
canActivate : true,
// private
onRender : function(container, position){
this.component.render(container);
this.el = this.component.getEl();
},
// private
activate : function(){
if(this.disabled){
return false;
}
this.component.focus();
this.fireEvent("activate", this);
return true;
},
// private
deactivate : function(){
this.fireEvent("deactivate", this);
},
// private
disable : function(){
this.component.disable();
DatetimeItem.superclass.disable.call(this);
},
// private
enable : function(){
this.component.enable();
DatetimeItem.superclass.enable.call(this);
}
,
onSelect : function(picker, date){
this.fireEvent("select", this, date, picker);
if(this.parentMenu && this.parentMenu.hide)
DatetimeItem.superclass.handleClick.call(this);
}
});
/*
Ext.extend(DatetimeItem, Ext.menu.Adapter, {
onSelect : function(picker, date){
this.fireEvent("select", this, date, picker);
// ORIGINAL:
//Ext.menu.DateItem.superclass.handleClick.call(this);
// NEW:
DatetimeItem.superclass.handleClick.call(this);
// END NEW
}
});
*/
/** Class Name: DatetimeMenu
* Inherits From: Ext.menu.Menu
* Contains: DatetimeItem
* Purpose: Effectively overrides Ext.menu.DateMenu so that it contains DatetimeItem instead of Ext.menu.DateItem
* Note: ORIGINAL and NEW comments are used to denote what differs from Ext.menu.DateMenu
*/
DatetimeMenu = function(config){
// ORIGINAL:
//Ext.menu.DateMenu.superclass.constructor.call(this, config);
//this.plain = true;
//var di = new Ext.menu.DateItem(config);
// NEW:
DatetimeMenu.superclass.constructor.call(this, config);
this.plain = true;
var di = new DatetimeItem(config);
// END NEW
this.add(di);
this.picker = di.picker;
// this.picker = di.component;
this.relayEvents(di, ["select"]);
};
Ext.extend(DatetimeMenu, Ext.menu.Menu);
3.应用案例:
{
name:"inEndDate",
fieldLabel:"终止时间",
xtype:"datefield",
format:"Y-m-d H:i:s",
typeAhead : true,
//editable:false,
readOnly:true,
allowBlank:false,
menu:new DatetimeMenu(),
blankText:"公告终止时间不能为空"
}
搞定!