具体批量修改的几个要点:
1)批量展示 mrecord控件(自定义)
也就是在html界面上的table表格中添加新的行,这个时候我们使用javascript来实现这种效果就行了,innerHTML 实现往一个区域div增加一段html代码,table,tr,td都用利用js动态插入。这里我们使用控件来完成。
下面我们来实现
我们来修改我们的jExportupdate.jsp,在修改出口报运信息下添加报运下货物的列表信息,并且将需要添加的货物列表添加上去,并且将动态表格的js文件和javascript的代码加入进去:
修改步骤:
1)在页面中加入一个table只有标题行
2)引入js,jquery、tabledo.js
3)利用jquery ready事件增加记录
具体代码:
<%@ page language="java" pageEncoding="UTF-8"%><%@ include file="../../base.jsp"%><%@ taglib uri="http://java.sun.com/jsp/jstl/fmt" prefix="fmt"%><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>修改出口报运信息</title> <script language="javascript" src="${ctx}/js/datepicker/WdatePicker.js"></script> <script type="text/javascript" src="${ctx}/components/jquery-ui/jquery-1.2.6.js"></script> <script type="text/javascript" src="${ctx}/js/tabledo.js"></script> <script type="text/javascript"> $().ready(function(){ ${mRecordData} }); /* 实现表格序号列自动调整 created by tony 20081219 */ function sortnoTR(){ sortno('mRecordTable', 2, 1); } //鼠标抬起时为该行添加更改标记 function setTRUpdateFlag(obj){ var currTr = obj.parentElement.parentElement; if(currTr.innerHTML.toLowerCase().indexOf("<span")==0){ currTr=obj.parentElement.parentElement.parentElement; } if(obj.value!=obj.defaultValue){ //当填写的框内容发生变化时,设置本行记录发生变化标识 currTr.cells[1].childNodes[2].value = "1"; } } //实现动态增加一行 function addTRRecord(objId, id, productNo, cnumber, grossWeight, netWeight, sizeLength, sizeWidth, sizeHeight, exPrice, tax) { var _tmpSelect = ""; var tableObj = document.getElementById(objId); //得到表格对象 var rowLength = tableObj.rows.length; //获取行的长度 oTR = tableObj.insertRow(); //新增一行 oTD = oTR.insertCell(0); //新增单元格,下标从0开始 oTD.style.whiteSpace="nowrap"; oTD.ondragover = function(){this.className="drag_over" }; //动态加事件, 改变样式类 oTD.ondragleave = function(){this.className="drag_leave" }; oTD.onmousedown = function(){ clearTRstyle("result"); this.parentNode.style.background = '#0099cc';}; //this.style.background="#0099cc url(../images/arroww.gif) 4px 9px no-repeat"; oTD.innerHTML = " "; oTD = oTR.insertCell(1); oTD.innerHTML = "<input class=\"input\" type=\"checkbox\" name=\"del\" value=\""+id+"\"><input type=\"hidden\" name=\"mr_id\" value=\""+id+"\"><input class=\"input\" type=\"hidden\" id=\"mr_changed\" name=\"mr_changed\">"; oTD = oTR.insertCell(2); oTD.innerHTML = "<input class=\"input\" type=\"text\" name=\"mr_orderNo\" readonly size=\"3\" value=\"\">"; oTD = oTR.insertCell(3); oTD.innerHTML = "<b><font face='微软雅黑'><font color='blue'>"+productNo;+"</font></font></b> " oTD = oTR.insertCell(4); oTD.innerHTML = "<input type=\"text\" name=\"mr_cnumber\" maxLength=\"10\" value=\""+cnumber+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(5); oTD.innerHTML = "<input type=\"text\" name=\"mr_grossWeight\" maxLength=\"10\" value=\""+grossWeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(6); oTD.innerHTML = "<input type=\"text\" name=\"mr_netWeight\" maxLength=\"10\" value=\""+netWeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(7); oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeLength\" maxLength=\"10\" value=\""+sizeLength+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(8); oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeWidth\" maxLength=\"10\" value=\""+sizeWidth+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(9); oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeHeight\" maxLength=\"10\" value=\""+sizeHeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(10); oTD.innerHTML = "<input type=\"text\" name=\"mr_exPrice\" maxLength=\"10\" value=\""+exPrice+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; oTD = oTR.insertCell(11); oTD.innerHTML = "<input type=\"text\" name=\"mr_tax\" maxLength=\"10\" value=\""+tax+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">"; dragtableinit(); //拖动表格行 sortnoTR(); //排序号 } </script></head><body><form method="post"><div id="menubar"><div id="middleMenubar"><div id="innerMenubar"> <div id="navMenubar"><ul><li id="save"><a href="#" onclick="formSubmit('update.action','_self');">确定</a></li><li id="back"><a href="list.action">返回</a></li></ul> </div></div></div></div> <div class="textbox" id="centerTextbox"> <div class="textbox-header"> <div class="textbox-inner-header"> <div class="textbox-title"> 修改出口报运信息 </div> </div> </div><div> <div> <table class="commonTable" cellspacing="1"> <input type="hidden" name="id" value="${obj.id}"/> <tr> <td class="columnTitle_mustbe">合同或确认书号:</td> <td class="tableContent">${obj.customerContract }</td> <td class="columnTitle_mustbe">制单日期:</td> <td class="tableContent"> <input type="text" style="width: 90px" name="inputDate" class="Wdate" value="<fmt:formatDate value="${obj.inputDate }" pattern="yyyy-MM-dd"/>" onclick="WdatePicker({el:this,isShowOthers:true,dateFmt:'yyyy-MM-dd'});"/> </td> </tr> <tr> <td class="columnTitle_mustbe">信用证号:</td> <td class="tableContent"><input type="text" name="lcno" value="${obj.lcno }"/></td> <td class="columnTitle_mustbe">收货人及地址:</td> <td class="tableContent"><input type="text" name="consignee" value="${obj.consignee}"/></td> </tr> <tr> <td class="columnTitle_mustbe">装运港:</td> <td class="tableContent"><input type="text" name="shipmentPort" value="${obj.shipmentPort}"/></td> <td class="columnTitle_mustbe">目的港:</td> <td class="tableContent"><input type="text" name="destinationPort" value="${obj.destinationPort}"/></td> </tr> <tr> <td class="columnTitle_mustbe">价格条件:</td> <td class="tableContent"> <input type="radio" name="priceCondition" value="2" <c:if test="${obj.priceCondition=='FOB'}"> checked="checked"</c:if>/>FOB <input type="radio" name="priceCondition" value="1" <c:if test="${obj.priceCondition=='CIF'}"> checked="checked"</c:if>/>CIF </td> <td class="columnTitle_mustbe">运输方式:</td> <td class="tableContent"> <input type="radio" name="transportMode" value="2" <c:if test="${obj.transportMode=='AIR'}"> checked="checked"</c:if>/>AIR <input type="radio" name="transportMode" value="1" <c:if test="${obj.transportMode=='SEA'}"> checked="checked"</c:if>/>SEA </td> </tr> <tr> <td class="columnTitle_mustbe">唛头:</td> <td class="tableContent"><textarea name="marks" style="height:200px;width: 400px">${obj.marks}</textarea></td> <td class="columnTitle_mustbe">备注:</td> <td class="tableContent"><textarea name="remark" style="height:200px;width: 400px">${obj.remark}</textarea></td> </tr> </table> </div></div><div class="textbox" id="centerTextbox"> <div class="textbox-header"> <div class="textbox-inner-header"> <div class="textbox-title"> 报运下货物的列表信息 </div> </div> </div><div> <div class="listTablew"> <table class="commonTable_main" cellSpacing="1" id="mRecordTable"> <tr class="rowTitle" align="middle"> <td width="25" title="可以拖动下面行首,实现记录的位置移动."> <img src="../../images/drag.gif"> </td> <td width="20"> <input class="input" type="checkbox" name="ck_del" onclick="checkGroupBox(this);" /> </td> <td width="33">序号</td> <td>货号</td> <td>数量</td> <td>毛重</td> <td>净重</td> <td>长</td> <td>宽</td> <td>高</td> <td>出口单价</td> <td>含税</td> </tr> </table> </div> </div> <div class="textbox-bottom"> <div class="textbox-inner-bottom"> <div class="textbox-go-top"> </div> </div> </div></div> </form></body></html>
<script>中的addTRRecord()具体的关键代码已经做解释了,其中的tabledo.js封装了操作表格的一些方法,我们在addTRRecord()方法中使用到了这个js文件中的方法。
我们在$().ready(function(){ });中调用addTRRecord()方法既可以在表格中新增一行(第一个参数是要因人行的表格id名),然后我们刷新页面就可以看到效果:
下面就是,我们如何将数据加载到新添加的table列表的新行中呢?
可以看到我们上面的jsp页面的ready()的方法中有一个${mRecordData}变量,既然调用addTRRecord(objId, id, productNo, cnumber, grossWeight, netWeight, sizeLength, sizeWidth, sizeHeight, exPrice, tax)就可以新增一行数据,那我们就在后台去拼接这个方法以及参数就行了,然后把这个方法拼成字符串,然后封装成一个参数(也就是上面的mRecordData)带到jsp页面上就ok了。
我们就来修改出口报运的Service层的ExportServiceImpl中新增一个方法:
//拼接javascript方法串//addTRRecord(objId, id, productNo, cnumber, grossWeight, netWeight, sizeLength, sizeWidth, sizeHeight, exPrice, tax)@Overridepublic String getMrecordData(String exportId){ Map paraMap=new HashMap(); paraMap.put("exportId", exportId); List<ExportProduct> oList=exportProductDao.find(paraMap); StringBuffer sBuf=new StringBuffer(); for (ExportProduct ep:oList) { sBuf.append("addTRRecord(\"mRecordTable\", \"") .append(ep.getId()).append("\", \"").append(ep.getProductNo()) .append("\", \"").append(ep.getCnumber()).append("\", \"").append(UtilFuns.convertNull(ep.getGrossWeight())) .append("\", \"").append(UtilFuns.convertNull(ep.getNetWeight())).append("\", \"").append(UtilFuns.convertNull(ep.getSizeLength())) .append("\", \"").append(UtilFuns.convertNull(ep.getSizeWidth())).append("\", \"").append(UtilFuns.convertNull(ep.getSizeHeight())) .append("\", \"").append(UtilFuns.convertNull(ep.getExPrice())).append("\", \"").append(UtilFuns.convertNull(ep.getTax())).append("\");"); } return sBuf.toString(); }(其中convertNull()方法是我们字符串处理工具类UtilFuns中检测null并返回空串""的方法)
这个方法会返回封装了相应出口报运下的所有货物的属性的js方法,这样在界面上就会增加新的包含真实货物数据的行。
这个方法在我们准备跳转到编辑页面的时候执行,所以我们在Controller的toupdate方法中添加这个方法:
//转向修改界面@RequestMapping("/cargo/export/toupdate.action")public String toupdate(String id,Model model){ Export obj=exportService.get(id); model.addAttribute("obj", obj); //准备批量修改控件的数据mrecord model.addAttribute("mRecordData",exportService.getMrecordData(id)); return "/cargo/export/jExportUpdate.jsp";}ok,然后我们进行测试,现在点击修改第一行的出口报运信息:
得到页面:
发现我们得到了出口报运下的所有货物的信息。
可以看到,我们的一些信息显示为空,这里我们就可以进行修改了。
2)批量提交
我们之前说过,修改报运下的货物信息时,用户修改货物的数量只能改小。如果用户故意把它货物数量改大,我们会检测到,然后相应的input框的背景会变成红色,而且提交的时候会告诉用户不能提交。
如果已经分次报运,它只显示剩余的值=合同的货物总数-实际出货数量。
那么当我们提交数据的时候,货物信息都是js生成的,所有列的name属性都是一样的,那么我们提交的时候信息就会封装成一个String数组,总之会有以下几种方法来获取货物表格的值:
A.页面上使用同名框,使用reqest.getParameterValues()获取货物表格的值,形成一个Sring数组。
B.Struts2框架封装为可以根据它的类型数组,改造ModelDriver
字符类型,将多个值拼接成一个字符串,之间用逗号+空格隔开
整形、浮点型、日期等,只保留第一个
C.Springmvc框架封装为数组,在方法调用参数上声明
字符类型,将多个值拼接成一个字符串,之间用逗号隔开
整形、浮点型、日期等,只保留第一个
所以我们修改就不单单修改出口报运信息了,我们还要把我们批量修改的货物信息要求一并修改,所以我们要在Controller中修改我们的update方法:
首先修改参数(利用Springmvc的同名参数封装),修改Service传入的参数:
//进行修改@RequestMapping("/cargo/export/update.action")public String update(Export export,String [] mr_id, Integer [] mr_orderNo,Integer [] mr_cnumber, Double [] mr_grossWeight,Double [] mr_netWeight, Double [] mr_sizeLength,Double [] mr_sizeWidth, Double [] mr_sizeHeight,Double [] mr_exPrice, Double [] mr_tax){ exportService.update(export,mr_id,mr_orderNo, mr_cnumber,mr_grossWeight,mr_netWeight, mr_sizeLength,mr_sizeWidth, mr_sizeHeight,mr_exPrice, mr_tax); return "redirect:/cargo/export/list.action";}
然后我们把Service的接口和实现方法中的参数也替换掉,下面我们在ExportService中的update方法中对我们取得的数据进行处理:
@Overridepublic void update(Export export,String [] mr_id, Integer [] mr_orderNo,Integer [] mr_cnumber, Double [] mr_grossWeight,Double [] mr_netWeight, Double [] mr_sizeLength,Double [] mr_sizeWidth, Double [] mr_sizeHeight,Double [] mr_exPrice, Double [] mr_tax) { exportDao.update(export); //批量修改货物信息 for (int i = 0; i < mr_id.length; i++) { ExportProduct ep=exportProductDao.get(mr_id[i]); ep.setOrderNo(mr_orderNo[i].toString()); ep.setCnumber(mr_cnumber[i]); ep.setGrossWeight(mr_grossWeight[i]); ep.setNetWeight(mr_netWeight[i]); ep.setSizeLength(mr_sizeLength[i]); ep.setSizeWidth(mr_sizeWidth[i]); ep.setSizeHeight(mr_sizeHeight[i]); ep.setExPrice(mr_exPrice[i]); ep.setTax(mr_tax[i]); exportProductDao.update(ep); } }
我们进行测试:
点击修改:
然后填写数据,点击保存:
再次点击修改时,发现货物数值已经被保存(加点是因为我们保存的是浮点数),批量修改成功!
这个时候其实是有一个问题的,我们的修改并不一定是所有的值都要进行修改,可能我们只简单的修改一个值,没有必要把所有货物的值全部都传递过去修改。
所以我们要进行优化。
3)批量保存优化
我们的优化方法就是:哪个框修改了,我们就在后台只修改这个框的数值。
我们在每一个框后面加一个隐藏域(hidden的input),里面是“mr_changed”属性,当你修改某一行的数据的时候,鼠标抬起的时候我们检测鼠标抬起事件(setTRUpdateFlag(this)),然后在相应行的“mr_changed”属性input隐藏域中设定值,“1”是这一行被改过,没数值就没有改过。这样我们在后台只需要修改“mr_change”属性为1的信息,这样我们系统就优化了。
回顾鼠标抬起js方法(之前只能在IE上使用,现在我修改了一下):
//鼠标抬起时为该行添加更改标记function setTRUpdateFlag(obj){ var currTr = obj.parentElement.parentElement; if(currTr.innerHTML.toLowerCase().indexOf("<span")==0){ currTr = obj.parentElement.parentElement.parentElement; } if(obj.value!=obj.defaultValue){ //当填写的框内容发生变化时,设置本行记录发生变化标识 currTr.cells[1].childNodes[2].value = "1"; } }
Controller:
//进行修改@RequestMapping("/cargo/export/update.action")public String update(Export export,String [] mr_id, Integer [] mr_orderNo,Integer [] mr_cnumber, Double [] mr_grossWeight,Double [] mr_netWeight, Double [] mr_sizeLength,Double [] mr_sizeWidth, Double [] mr_sizeHeight,Double [] mr_exPrice, Double [] mr_tax,Integer [] mr_changed){ exportService.update(export,mr_id,mr_orderNo, mr_cnumber,mr_grossWeight,mr_netWeight, mr_sizeLength,mr_sizeWidth, mr_sizeHeight,mr_exPrice, mr_tax,mr_changed); return "redirect:/cargo/export/list.action";}
Service:
@Overridepublic void update(Export export,String [] mr_id, Integer [] mr_orderNo,Integer [] mr_cnumber, Double [] mr_grossWeight,Double [] mr_netWeight, Double [] mr_sizeLength,Double [] mr_sizeWidth, Double [] mr_sizeHeight,Double [] mr_exPrice, Double [] mr_tax,Integer [] mr_changed) { exportDao.update(export); //批量修改货物信息 for (int i = 0; i < mr_id.length; i++) { if(mr_changed[i]!=null && mr_changed[i]==1){ //修改标识,只有用户修改的才进行更新 ExportProduct ep=exportProductDao.get(mr_id[i]); ep.setOrderNo(mr_orderNo[i].toString()); ep.setCnumber(mr_cnumber[i]); ep.setGrossWeight(mr_grossWeight[i]); ep.setNetWeight(mr_netWeight[i]); ep.setSizeLength(mr_sizeLength[i]); ep.setSizeWidth(mr_sizeWidth[i]); ep.setSizeHeight(mr_sizeHeight[i]); ep.setExPrice(mr_exPrice[i]); ep.setTax(mr_tax[i]); exportProductDao.update(ep); } } }
至此我们完成了出口报运下的货物批量修改以及优化工作。
转载请注明出处:http://blog.csdn.net/acmman/article/details/49023917
版权声明:本文为博主原创文章,未经博主允许不得转载。