在仿照费控和用友做邮件审批时,增加了对表单内容的显示。在系统中做审批时,表单内容有丰富的控件展示,简单的有input,textarea,radio,复杂的有自定义的审批控件、附件控件和人员选择器等。目前复杂控件展示没有问题,复杂控件为只读状态时,展示给用户的就是普通的input或table;简单控件中当为select时出现无法绑定值的问题。即不管其选中项是什么,展示出来的始终是第一项。
根据问题症状,之前在审批展示时,也出现过因下拉菜单展示有问题(如始终展示第一项或最后一项)导致的问题。究其根源是由于对select的val的不支持,解决方案是增加以下js代码
$("select").each(function(index, element) { $(this).attr("style", "color:rgb(0, 0, 0)"); var _val = $(element).attr("val"); if (_val) { $("option[value=‘" + _val + "‘]", $(element)).attr( "selected", "selected"); } });
以上的思路即为先即得select的val值,然后将对应val值的option选项置为selected。
以下是整个解决过程:
1.首先对以上思路进行测试,加入代码:
from = from +"<script type=\"text/javascript\">$(function(){$(\"select\").each(function(index, element) {var _val = $(element).attr(\"val\");if (_val) {$(\"option[value=‘\" + _val + \"‘]\", $(element)).attr(\"selected\", \"selected\")}});});</script>";
由于缺失jquery,所以肯定是失败的。
2.由于freemarker只提供了解析接口,希望通过重写某些方法实现思路1中的方案,但freemarker的解析没有找到源码,可能代价较大,放弃;
3.在网页中选中elements,发现val值被过滤,validate(jQuery的validate)也被滤除;
跟踪相应代码发现freemarker生成的html并无问题;一直向后跟踪至javaMail发送邮件的content的set处,content值也没有问题。在进行跟踪时,发现content的type是Multipart/mixed,mixed格式一般是指包含丰富展现的情况,于滤除val值和validate无关。
4.由于validate是jquery所支持的,考虑到可能与jQuery未被引入有关。OA系统中存在jQuery,是存储在服务器静态资源中,oa在提供服务的时候,可以读取,由于oa需要通过vpn访问,所以初步断定直接引用oastatic中的jquery是拿不到的。在内网、外网访问该静态资源地址时做对比也印证了以上推断。于是希望引入互联网上的jquery资源,代码如下:
from = from + "<script src=\"http://code.jquery.com/jquery-1.8.0.min.js\"></script>";
如果是因为validate无法识别,导致val丢失,理论上加入jquery引入是可以解决的。但测试下来不光没有解决,在F12搜索引入的script发现,script也被过滤掉,根本无法引入并解析执行。
5.由于引入jQuery不成功,所以希望将所有的valieate直接过滤掉,使用如下正则表达式:
from = from.replaceAll("validate=\"(.*)}\"","");
validate虽然被过滤掉,但val还是不存在。在html的select标签的介绍中,可以看出,val和同时被过滤的validate都不是基本的属性。所以解决的思路应该转向邮箱正文展示应以最基本属性为主。
6.仍然按照思路1,将select使用val指定选中项,改为按照option selected,使用正则表达式替换,代码如下:
if(readHtml.contains("select")){ String regex = "value=\"" + value + "\""; String str = readHtml; Pattern pat = Pattern.compile(regex); Matcher matcher = pat.matcher(str); while (matcher.find()) { String temp = str.substring(matcher.start(),matcher.end()); str = str.replaceAll(temp, temp.substring(0,temp.lastIndexOf(value))+ "" + value + "\"" + " selected=‘true‘"); } readHtml = str; }
经确认,问题解决。选中的option后会追加selected=true,显示正常。该方式也解决了之前需要在各页面或统一js中必须增加val转换为selected=true的问题。