首页 > 代码库 > Struts2中datetimepicker标签

Struts2中datetimepicker标签

在以前的struts2版本中s:datetimepicker只需要在head标签处设置<s:head theme="ajax"/>,就可以直接使用s:datetimepicker的标签了。
而在2.1.6版本中不能直接这样使用了,将datetimepicker移除了。原因是此标签调用了dojo的datetimepicker的库。
所以现在使用的时候首先要导入一个库:struts2-dojo-plugin-2.1.6.jar。
然后还要设置dojo的taglib
<%@ taglib prefix="sd" uri="/struts-dojo-tags" %>
同样也需要对theme进行设置
<s:head theme="xhtml"/>
<sd:head parseContent="true"/>
上面的设置在head标签中。
然后使用sd:datetimepocker就可以实现了。
完整示例:
<%@ page language="java" contentType="text/html; charset=utf-8"%>
<%@ taglib prefix="s" uri="/struts-tags"%>
<%@ taglib prefix="sx" uri="/struts-dojo-tags"%>
<html>
   <head>
      <s:head theme="xhtml" />
      <sx:head parseContent="true" />
   </head>
   <body>
      <sx:datetimepicker name="birthday" value=http://www.mamicode.com/"%{date}"
          displayFormat="yy-MM-dd" />
   </body>

Struts2 datetimepicker 日期乱码解决方案

在使用 Struts2 dateTimePicker 控件时, 9月份后会出现乱码现象。
(本人以struts2-dojo-plugin-2.2.1为例子) 
请替换或直接修改以下文件(并保存为UTF-8格式):
struts2-dojo-plugin-2.2.1.jar\org\apache\struts2\static\dojo\nls\
dojo_zh.js 和 dojo_zh-cn.js 文件
1. 文件 "dojo_zh.js"
------------------------------------------------------------------------------
dojo.provide("nls.dojo_zh");dojo.provide("dojo.i18n.calendar.nls.gregorian");
dojo.i18n.calendar.nls.gregorian._built=true;dojo.provide("dojo.i18n.calendar.nls.gregorian.zh");
dojo.i18n.calendar.nls.gregorian.zh={
"days-standAlone-narrow":["日","一","二","三","四","五","六"],
"eras":["公元前","公元"],
"am":"上午",
"months-format-abbr":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"days-format-abbr":["周日","周一","周二","周三","周四","周五","周六"],
"pm":"下午",
"months-format-wide":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"months-standAlone-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],
"days-format-wide":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
"field-weekday":"Day of the Week",
"dateFormat-medium":"yyyy MMM d",
"field-second":"Second",
"field-week":"Week",
"timeFormat-full":"HH:mm:ss z",
"field-year":"Year",
"field-minute":"Minute",
"timeFormat-medium":"HH:mm:ss",
"field-hour":"Hour",
"dateFormat-long":"yyyy MMMM d",
"field-day":"Day",
"field-dayperiod":"Dayperiod",
"field-month":"Month",
"dateFormat-short":"yy/MM/dd",
"field-era":"Era",
"timeFormat-short":"HH:mm",
"timeFormat-long":"HH:mm:ss z",
"dateFormat-full":"EEEE, yyyy MMMM dd",
"field-zone":"Zone"
};
dojo.provide("dojo.i18n.calendar.nls.gregorianExtras");
dojo.i18n.calendar.nls.gregorianExtras._built=true;
dojo.provide("dojo.i18n.calendar.nls.gregorianExtras.zh");
dojo.i18n.calendar.nls.gregorianExtras.zh={"dateFormat-yearOnly":"yyyy‘年‘"};
dojo.provide("dojo.i18n.calendar.nls.gregorian");
dojo.i18n.calendar.nls.gregorian._built=true;
dojo.provide("dojo.i18n.calendar.nls.gregorian.zh");
dojo.i18n.calendar.nls.gregorian.zh={
"days-standAlone-narrow":["日","一","二","三","四","五","六"],
"eras":["公元前","公元"],
"am":"上午",
"months-format-abbr":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"days-format-abbr":["周日","周一","周二","周三","周四","周五","周六"],
"pm":"下午","months-format-wide":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"months-standAlone-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],
"days-format-wide":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"],
"field-weekday":"Day of the Week",
"dateFormat-medium":"yyyy MMM d",
"field-second":"Second",
"field-week":"Week",
"timeFormat-full":"HH:mm:ss z",
"field-year":"Year",
"field-minute":"Minute",
"timeFormat-medium":"HH:mm:ss",
"field-hour":"Hour",
"dateFormat-long":"yyyy MMMM d",
"field-day":"Day",
"field-dayperiod":"Dayperiod",
"field-month":"Month",
"dateFormat-short":"yy/MM/dd",
"field-era":"Era",
"timeFormat-short":"HH:mm",
"timeFormat-long":"HH:mm:ss z",
"dateFormat-full":"EEEE, yyyy MMMM dd",
"field-zone":"Zone"
};
dojo.provide("dojo.widget.nls.TimePicker");
dojo.widget.nls.TimePicker._built=true;
dojo.provide("dojo.widget.nls.TimePicker.zh");
dojo.widget.nls.TimePicker.zh={"any":"any"};
dojo.provide("dojo.widget.nls.DropdownTimePicker");
dojo.widget.nls.DropdownTimePicker._built=true;
dojo.provide("dojo.widget.nls.DropdownTimePicker.zh");
dojo.widget.nls.DropdownTimePicker.zh={"selectTime":"Select time"};
dojo.provide("dojo.widget.nls.DropdownDatePicker");
dojo.widget.nls.DropdownDatePicker._built=true;
dojo.provide("dojo.widget.nls.DropdownDatePicker.zh");
dojo.widget.nls.DropdownDatePicker.zh={"selectDate":"Select a date"};
=============================================================================
2. 文件 "dojo_zh-cn.js"
------------------------------------------------------------------------------
dojo.provide("nls.dojo_zh-cn");
dojo.provide("dojo.i18n.calendar.nls.gregorian");
dojo.i18n.calendar.nls.gregorian._built=true;
dojo.provide("dojo.i18n.calendar.nls.gregorian.zh_cn");
dojo.i18n.calendar.nls.gregorian.zh_cn={
"dateFormat-medium":"yyyy-M-d",
"field-second":"秒钟",
"field-week":"周",
"timeFormat-full":"ahh‘时‘mm‘分‘ss‘秒‘ z",
"field-year":"年",
"field-minute":"分钟",
"timeFormat-medium":"ahh:mm:ss",
"field-hour":"小时",
"dateFormat-long":"yyyy‘年‘M‘月‘d‘日‘",
"field-day":"日",
"field-dayperiod":"上午/下午",
"field-month":"月",
"dateFormat-short":"yy-M-d",
"field-era":"时期",
"timeFormat-short":"ah:mm",
"timeFormat-long":"ahh‘时‘mm‘分‘ss‘秒‘",
"dateFormat-full":"yyyy‘年‘M‘月‘d‘日‘EEEE",
"field-weekday":"周天",
"field-zone":"区域",
"days-standAlone-narrow":["日","一","二","三","四","五","六"],"eras":["公元前","公元"],
"am":"上午",
"months-format-abbr":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"days-format-abbr":["周日","周一","周二","周三","周四","周五","周六"],
"pm":"下午",
"months-format-wide":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"months-standAlone-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],
"days-format-wide":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
};
dojo.provide("dojo.i18n.calendar.nls.gregorianExtras");
dojo.i18n.calendar.nls.gregorianExtras._built=true;
dojo.provide("dojo.i18n.calendar.nls.gregorianExtras.zh_cn");
dojo.i18n.calendar.nls.gregorianExtras.zh_cn={"dateFormat-yearOnly":"yyyy‘年‘"};
dojo.provide("dojo.i18n.calendar.nls.gregorian");
dojo.i18n.calendar.nls.gregorian._built=true;
dojo.provide("dojo.i18n.calendar.nls.gregorian.zh_cn");
dojo.i18n.calendar.nls.gregorian.zh_cn={
"dateFormat-medium":"yyyy-M-d",
"field-second":"秒钟",
"field-week":"周",
"timeFormat-full":"ahh‘时‘mm‘分‘ss‘秒‘ z",
"field-year":"年",
"field-minute":"分钟",
"timeFormat-medium":"ahh:mm:ss",
"field-hour":"小时",
"dateFormat-long":"yyyy‘年‘M‘月‘d‘日‘",
"field-day":"日",
"field-dayperiod":"上午/下午",
"field-month":"月",
"dateFormat-short":"yy-M-d",
"field-era":"时期",
"timeFormat-short":"ah:mm",
"timeFormat-long":"ahh‘时‘mm‘分‘ss‘秒‘",
"dateFormat-full":"yyyy‘年‘M‘月‘d‘日‘EEEE",
"field-weekday":"周天",
"field-zone":"区域",
"days-standAlone-narrow":["日","一","二","三","四","五","六"],
"eras":["公元前","公元"],
"am":"上午",
"months-format-abbr":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"days-format-abbr":["周日","周一","周二","周三","周四","周五","周六"],
"pm":"下午",
"months-format-wide":["一月","二月","三月","四月","五月","六月","七月","八月","九月","十月","十一月","十二月"],
"months-standAlone-narrow":["1月","2月","3月","4月","5月","6月","7月","8月","9月","10月","11月","12月"],
"days-format-wide":["星期日","星期一","星期二","星期三","星期四","星期五","星期六"]
};
dojo.provide("dojo.widget.nls.TimePicker");
dojo.widget.nls.TimePicker._built=true;
dojo.provide("dojo.widget.nls.TimePicker.zh_cn");
dojo.widget.nls.TimePicker.zh_cn={"any":"any"};
dojo.provide("dojo.widget.nls.DropdownTimePicker");
dojo.widget.nls.DropdownTimePicker._built=true;
dojo.provide("dojo.widget.nls.DropdownTimePicker.zh_cn");
dojo.widget.nls.DropdownTimePicker.zh_cn={"selectTime":"Select time"};
dojo.provide("dojo.widget.nls.DropdownDatePicker");
dojo.widget.nls.DropdownDatePicker._built=true;
dojo.provide("dojo.widget.nls.DropdownDatePicker.zh_cn");
dojo.widget.nls.DropdownDatePicker.zh_cn={"selectDate":"Select a date"}; 
 

 
 
**************************************************************************************************
 
 

最近项目使用Spring+Struts2+JPA(Hibernate)的框架进行开发,大量使用了Struts2的标签库,确实让JSP页面干净了不少,也大大提高了开发的效率。

但是在使用sx:datetimepicker标签时发现一个问题,就是在输入日期内容,然后删除内容,输入框内为""时,再点击日期选择的弹出控件时,发现日期全部变成了NaN。

下面分析原因和找到解决办法。如果只是想看解决办法,请直接看最后的 最终的解决办法 部分。

基本解决办法

开始的解决办法是,对日期的格式进行了校验,如果选择了NaN的日期提交,就提示日期格式错误,不让提交。

查找原因

然后网上查了一下,都没有彻底解决的办法,大都是说这个是个BUG,提交前校验就可以了。几年前就有的BUG了,估计Struts也没有心思去解决,所以,就准备自己去修正。

因为是使用了sx:datetimepicker标签,所以,先去看了一下该标签的源代码。

在源码包中struts-2.1.8\src\plugins\dojo\src\main\java\org\apache\struts2\dojo\components找到了DateTimePicker.java,查看了一下只是一个初始化设置和写出html代码的普通标签库而已。

所以,去看看它最终生成了什么样子的代码。生成的代码大致如下

<div
dojoType="struts:StrutsDatePicker" id="app.beginDate" value=http://www.mamicode.com/"2010-05-13T09:27:31" name="app.beginDate" inputName="dojo.app.beginDate" displayFormat="yyyy-MM-dd" saveFormat="rfc">


<script language="JavaScript" type="text/javascript">djConfig.searchIds.push("app.beginDate");</script>

头部声明部分引入了


<script language="JavaScript" type="text/javascript"
src=http://www.mamicode.com/"/应用名称/struts/dojo/struts_dojo.js"></script>
struts_dojo.js这个js。

同时进行了dojo设置,


<script language="JavaScript" type="text/javascript">
// Dojo configuration
djConfig = {
isDebug: false,
bindEncoding: "utf-8"
,baseRelativePath: "/dcap/struts/dojo/"
,baseScriptUri: "/dcap/struts/dojo/"
,parseWidgets : false
};
</script>


使用了dojo,所以,不出意外StrutsDatePicker这个小组件应该在struts_dojo.js这个文件中定义。

在该js中去搜索StrutsDatePicker,找到了


dojo.provide("struts.widget.StrutsDatePicker");


发现其又使用了


dojo.widget.DropdownDatePicker这个小组件。

继续查DropdownDatePicker,找到dojo.provide("dojo.widget.DropdownDatePicker");,在其代码中找到了


if(_e5f==""){
this.datePicker.setDate("");
}


这段代码,而_e5f就是改变为控制后的存储字符串,直接把


this.datePicker.setDate("");


注释掉,测试一下,发现不会再出现那个讨厌的NaN了。

但是显示的日期是清空输入框日期前的那个旧的日期,按照普通的逻辑,输入框日期为空,应该显示当前日期,和初始化时候的保持一致么。

继续找,发现了


this.datePicker=dojo.widget.createWidget("DatePicker",_e5b,this.containerNode,"child");


这行代码,是一个DatePicker小组件。

所以搜索DatePicker,找到了


dojo.provide("dojo.widget.DatePicker");


找到setDate函数,发现调用了this._preInitUI函数,继续查找,最终在_preInitUI函数中发现了


if(_e14<this.startDate||_e14>this.endDate){
_e14=new Date((_e14<this.startDate)?this.startDate:this.endDate);
}


只对日期大小做了校验,而没有对日期的""做校验,原因就在这里了。所以在


if(_e14<this.startDate||_e14>this.endDate){


之前加入


if(_e14==""){
_e14=new Date();
}
修改后的前后代码大概如下:

this.startDate.setHours(0,0,0,0);
this.endDate.setHours(24,0,0,-1);
if(_e14==""){
_e14=new Date();
}
if(_e14<this.startDate||_e14>this.endDate){
_e14=new Date((_e14<this.startDate)?this.startDate:this.endDate);
}

测试一下,一切OK,到此完满解决。

最终的解决办法

找到使用的
struts2-dojo-plugin-2.1.8.1.jar
解压缩到struts2-dojo-plugin-2.1.8.1文件夹,然后找到
struts2-dojo-plugin-2.1.8.1\org\apache\struts2\static\dojo
下的struts_dojo.js文件。


打开文件


找到
dojo.provide("dojo.widget.DatePicker");


然后往下找到
if(_e14<this.startDate||_e14>this.endDate){
_e14=new Date((_e14<this.startDate)?this.startDate:this.endDate);
}


在其前面添加
if(_e14==""){
_e14=new Date();
}
保存。


然后使用winrar或者winzip,进入struts2-dojo-plugin-2.1.8.1文件夹,将选择该文件夹下的所有文件压缩,注意选择zip格式压缩,压缩好之后,修改为将.zip修改为.jar即可。

好了,现在覆盖项目中对应的jar包,重新部署即可。测试的时候,注意清空浏览器的缓存,然后刷新即可。否则,还是bug时候的struts-dojo.js文件在客户端