if (!dojo._hasResource["bad.form.DateBox"]) { //_hasResource checks added by build. Do not use _hasResource directly in your code. dojo._hasResource["bad.form.DateBox"] = true; dojo.provide("bad.form.DateBox"); dojo.require("dijit._Calendar"); dojo.require("dijit.form.TimeTextBox"); dojo.require("bad.form._MonthPicker"); dojo.require("dojo.date.locale"); dojo.declare("bad.form.DateBox", [dijit.form.TimeTextBox], { /** @attr: 弹出窗口类型 */ _popupClass: "dijit._Calendar", /** @attr: {String}日期类型 * @example yyyy_MM_dd 其中MM要大写 */ datePattern: "", /** {String } */ _pattern: "", /**@attr: 年的开始位*/ _yearStart:"", /**@attr: 年的结束位*/ _yearEnd:"", /**@attr: 月的开始位*/ _monthStart:"", /**@attr: 月的结束位*/ _monthEnd:"", /**@attr: 日的开始位*/ _dateStart:"", /**@attr: 日的结束位*/ _dateEnd:"", /**@attr: 存储用户提示信息*/ _currentMessage: "请输入正确的日期", /**@attr: {Boolean} 是否显示day 为{false}时不显示,为{true}时显示 */ showDay: "", /**@attr: 日期可以显示的初始值*/ firstValue:'', /**@method将目前this.textbox.value进行格式化*/ formatInput: function() { var value=this.getFormatDate(); if(value instanceof Date) { this.setValue(value); } }, /** 当文本框失去焦点事件*/ _runBlur: function() { this.formatInput(); this.onChange(this.textbox.value); }, /** @method: 将参数或者目前显示的数字格式化,如果显示中数字位数超过6且显示天数,则将字符截取为yyyy(M)M(d)d * @return: {Date} * @remind: 可以自己添加返回值,比如判断现有的值无法转化,返回false,等等。 */ getFormatDate: function(value) { if(!value) { value = this.textbox.value; } if (typeof value == "string") { var numValue = ""; value.replace("-", ""); var stringArray = value.split(""); //取得value中的数字 for (var i = 0; (i < stringArray.length && (this.showDay ? numValue.length < 8 : numValue.length < 6)); i++) { if (!isNaN(stringArray[i])) { numValue += stringArray[i]; } } //如果显示day if (this.showDay) { if (numValue.length == 8) { return new Date(numValue.slice(this._yearStart, this._yearEnd), numValue.slice(this._monthStart, this._monthEnd) - 1, numValue.slice(this._dateStart, this._dateEnd)); } if (numValue.length == 7) { return new Date(numValue.slice(this._yearStart, this._yearEnd), numValue.slice(this._monthStart, this._monthEnd-1) - 1, numValue.slice(this._dateStart-1, this._dateEnd)); } if (numValue.length == 6) { return new Date(numValue.slice(this._yearStart, this._yearEnd), numValue.slice(this._monthStart,this._monthEnd-1) - 1, numValue.slice(this._dateStart-1, this._dateEnd-1)); } } else { if (numValue.length == 6) { return new Date(numValue.slice(this._yearStart, this._yearEnd), numValue.slice(this._monthStart, this._monthEnd) - 1); } if (numValue.length == 5) { return new Date(numValue.slice(this._yearStart, this._yearEnd), numValue.slice(this._monthStart,this._monthEnd-1) - 1); } } } }, /**@member: 扫描datePattern,获得年月(日)的位置*/ scanPattern: function() { this._pattern=""; for(var i=0;i<this.datePattern.length;i++) { switch(this.datePattern.charAt(i)) { case 'd': while(this.datePattern.charAt(i)=='d') { this._pattern+='d'; i++; } i--; break; case 'D': while(this.datePattern.charAt(i)=='D') { this._pattern+='d'; i++; } i--; break; case 'M': while(this.datePattern.charAt(i)=='M') { this._pattern+='M'; i++; } i--; break; case 'y': while(this.datePattern.charAt(i)=='y') { this._pattern+='y'; i++; } i--; break; case 'Y': while(this.datePattern.charAt(i)=='Y') { this._pattern+='y'; i++; } i--; break; default : break; //暂时不进行处理 } } for(var i=0;i<this._pattern.length;i++) { switch(this._pattern.charAt(i)) { case 'd': this._dateStart=i; while(this._pattern.charAt(i)=='d') { i++; } this._dateEnd=i; i--; break; case 'M': this._monthStart=i; while(this._pattern.charAt(i)=='M') { i++; } this._monthEnd=i; i--; break; case 'y': this._yearStart=i; while(this._pattern.charAt(i)=='y') { i++; } this._yearEnd=i; i--; break; default : break; //暂时不进行处理 } } console.log(this.datePattern+" "+this._yearStart+" "+this._yearEnd+" "+this._monthStart+" "+this._monthEnd+" "+this._dateStart+" "+this._dateEnd); }, _setPattern: function() { /* this._pattern=""; var size=this._yearEnd>this._monthEnd?(this._yearEnd>this._dateEnd? this._yearEnd:this._dateEnd):(this._monthEnd>this.dateEnd? this._monthEnd:this._dateEnd); console.log("length is "+size); for(var i=0;i<size;i++) { if(i>=this._yearStart&&i<this._yearEnd) { while(i<this._yearEnd) { this._pattern+="y"; i++; } i--; } else if(i>=this._monthStart&&i<this._monthEnd) { while(i<this._monthEnd) { this._pattern+="M"; i++; } i--; } else if(i>=this._dateStart&&i<this._dateEnd) { while(i<this._dateEnd) { this._pattern+="d"; i++; } i--; } } */ console.log("pattern is "+this._pattern); }, /**被绑定的onkeydown事件,火狐下回车事件有问题 * */ _onkeydown: function(key) { var c = String.fromCharCode(65); var code=this._getKeyCode(key); if(code==13) { var value=this.getFormatDate(); if(value instanceof Date) { var isie = (document.all) ? true : false; var eSrc =isie?key.srcElement:key.target; if(eSrc.tagName=="INPUT" && (eSrc.type=="text"||eSrc.type=="password")) { if(isie) { key.keyCode=9; } else { key.which=9; } if(this._opened) { this._close(); } } } } return true; }, _getKeyCode: function(e){ var isie = (document.all) ? true : false; var key=""; if (isie) { key = e.keyCode; } else { key = e.which; if (key == 120 || key == 228||key == 99 ||key == 0) { key = 8; } } return key; }, /** @method: 过滤字符加捕获回车*/ keycodefilter: function(key){ if (key.keyCode == dojo.keys.ENTER) { this.formatInput(); this.onChange(); } if(key.keyCode==dojo.keys.ESCAPE) { if(this._opened) { this._close(); } } }, /** @method: 验证,目前继承父类的验证方法*/ validate: function(){ this.inherited('validate', arguments); }, /** @method: 配置属性,继承父类的同名方法,目前主要是完成 this.datePattern默认配置将其配置为"yyyy-MM-dd" */ postMixInProperties: function() { this.inherited('postMixInProperties', arguments); this.constraints.selector = 'date'; this.datePattern=this.datePattern? this.datePattern:"yyyy-MM-dd"; this.showDay = (this.datePattern.indexOf("dd") != -1 || this.datePattern.indexOf("DD") != -1) ? true : false; //是否显示day this.constraints.datePattern = this.datePattern; if(!this.showDay) { this._popupClass="bad.form._MonthPicker"; } this.maxLength=this.datePattern.length; //输入长度不能超过验证长度 this.promptMessage="请输入形如"+this.datePattern; this.invalidMessage="请输入形如"+this.datePattern; }, /** @method: 继承父类同名方法,扫描格式,添加两个事件绑定,一个是键盘输入字符过滤,另一个是失去焦点对字符串进行格式化 如果有初值赋上初值*/ postCreate: function(){ this.inherited('postCreate', arguments); this.scanPattern(); this._setPattern(); dojo.connect(this.textbox, "onkeypress", this, this.keycodefilter); //绑定onkeypress事件 dojo.connect(this.textbox,"onkeydown",this,this._onkeydown); dojo.connect(this, "_onBlur", this, this._runBlur); //绑定失去焦点事件和字符格式化方法 this._lastValue=" "; if(this.firstValue) { this.setValue(this.firstValue); //赋上初值 } }, _onMouserOver: function(evt){ this.displayMessage(this._currentMessage); }, _onMouserOut: function(evt){ dijit.hideTooltip(this.domNode); }, /** @method: 验证,目前继承父类的验证方法 * @param: {Date}newValue * */ onChange: function(newValue) { this._lastValue=this.getValue(); this.inherited('onChange', arguments); }, /** @method: 将目前的显示值经过格式化返回 表单进行数据绑定会调用此方法获取当前值 @return: {Sring} 被格式化的值 */ getValue: function() { if(!this.textbox.value) { return ""; } return this.textbox.value; }, /** @method: 对this.textbox赋值 参数可以是Date对象或者String 若果能转换为Date对象,则显示值改变 * @param: {String}value or {Date}value * @return: {null} */ setValue: function(value) { //以下为没有弹出窗口对象时,新建一个弹出窗口对象并进行赋值防止出现NaN的情况 if(!this._picker) { this._open(); this._close(); } var v = []; if (value instanceof Date) { v[0] = value; } else if (typeof value == "string") { if(value.length==0) { this.textbox.value=""; return; } else if (value.length >= 6) { //setValue的类型为Date对象方能成功 v[0]=new Date(); v[0]=this.getFormatDate(value); } } console.log("v[0] is "+v[0]); console.log(v[0] instanceof Date&&v[0].getFullYear()); this.inherited("setValue", arguments, v); if(v[0] instanceof Date&&v[0].getFullYear()) { //var testValue=dojo.date.locale.format(v[0],this._pattern); if(this._lastValue!=this.textbox.value) { this._lastValue=this.textbox.value; console.log("_lastValue is "+this._lastValue); } } } }); }
原先改写了下dojo的日期控件,没太用心,做个反面例子。
代码如下,上级文件夹“包”叫bad.form,具体对象名字为“DateBox”
属性名 |
类型 |
默认值 |
描述 |
Id |
String |
无 |
组件标识 |
jsId |
String |
无 |
通过jsId可以获得控件对象 |
_popupClass |
String |
"dijit._Calendar" |
弹出窗口类型 |
datePattern |
String |
“yyyy-MM-dd” |
设置日期格式 |
dateValue |
Date |
new Date()即此时此刻 |
日期值 |
备注
目前_popupClass可选类型为"dijit._Calendar"和”bad.form._MonthPicker”两种,前一种完整显示年月日,后一种只显示年月。
datePattern设置日期验证的格式以及正确日期的显示格式以及按回车键对现有字符串中数字进行格式化的格式。可以设为”*yyyy*MM*dd*”或者”*yyyy*MM*”其中*可以代表除英文字符以外的任意字符串,MM必须要大写,如果datePattern为”*yyyy*MM*”,则_popupClass会变为_popupClass。
方法名 |
参数 |
返回值 |
描述 |
setValue |
{String or Date}value |
无 |
对控件赋值 |
getValue |
无 |
String |
获取控件的值 |
_open |
无 |
无 |
弹出窗口 |
_close |
无 |
无 |
关闭窗口 |
备注
setValue要求参数为Javascript的内置对象Date或者能转化为Date的String(如2000-10-11 00:00:00:0)
getValue默认返回形如"yyyy-MM-dd"的String,此方法可以重写,以需要的格式将值返回。
事件名 | 参数 | 返回值 | 描述 |
onValueChange | {Date}newValue,{Date}oldValue | 无 | 值改变事件 |