【springmvc+mybatis项目实战】杰信商贸-33.出口报运修改+报运货物批量展现-批量修改控件2

具体批量修改的几个要点:
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事件增加记录

具体代码:
[html]  view plain copy
  1. <%@ page language="java" pageEncoding="UTF-8"%>  
  2. <%@ include file="../../base.jsp"%>  
  3. <%@ taglib uri="http://java.sun.com/jsp/jstl/fmt"  prefix="fmt"%>  
  4. <html xmlns="http://www.w3.org/1999/xhtml">  
  5. <head>  
  6.     <title>修改出口报运信息</title>  
  7.     <script language="javascript" src="${ctx}/js/datepicker/WdatePicker.js"></script>  
  8.       
  9.     <script type="text/javascript" src="${ctx}/components/jquery-ui/jquery-1.2.6.js"></script>  
  10.     <script type="text/javascript" src="${ctx}/js/tabledo.js"></script>  
  11.       
  12.     <script type="text/javascript">  
  13.     $().ready(function(){  
  14.         ${mRecordData}  
  15.     });  
  16.       
  17.   
  18.   
  19.     /* 实现表格序号列自动调整 created by tony 20081219 */  
  20.     function sortnoTR(){  
  21.         sortno('mRecordTable', 2, 1);  
  22.     }  
  23.   
  24.   
  25.     //鼠标抬起时为该行添加更改标记  
  26.     function setTRUpdateFlag(obj){  
  27.           
  28.         var currTr = obj.parentElement.parentElement;  
  29.         if(currTr.innerHTML.toLowerCase().indexOf("<span")==0){  
  30.              currTr=obj.parentElement.parentElement.parentElement;  
  31.         }  
  32.           
  33.         if(obj.value!=obj.defaultValue){      
  34.             //当填写的框内容发生变化时,设置本行记录发生变化标识  
  35.             currTr.cells[1].childNodes[2].value = "1";  
  36.         }  
  37.           
  38.     }  
  39.       
  40.         //实现动态增加一行  
  41.     function addTRRecord(objId, id, productNo, cnumber, grossWeight, netWeight, sizeLength, sizeWidth, sizeHeight, exPrice, tax) {  
  42.           
  43.         var _tmpSelect = "";  
  44.         var tableObj = document.getElementById(objId);      //得到表格对象  
  45.         var rowLength = tableObj.rows.length;               //获取行的长度  
  46.           
  47.         oTR = tableObj.insertRow();                         //新增一行  
  48.           
  49.         oTD = oTR.insertCell(0);                            //新增单元格,下标从0开始  
  50.         oTD.style.whiteSpace="nowrap";  
  51.         oTD.ondragover = function(){this.className="drag_over" };   //动态加事件, 改变样式类  
  52.         oTD.ondragleave = function(){this.className="drag_leave" };  
  53.         oTD.onmousedown = function(){ clearTRstyle("result"); this.parentNode.style.background = '#0099cc';};     
  54.         //this.style.background="#0099cc url(../images/arroww.gif) 4px 9px no-repeat";  
  55.         oTD.innerHTML = "  ";   
  56.         oTD = oTR.insertCell(1);  
  57.         oTD.innerHTML = "<inputinput 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\">";  
  58.         oTD = oTR.insertCell(2);  
  59.         oTD.innerHTML = "<inputinput class=\"input\" type=\"text\" name=\"mr_orderNo\" readonly size=\"3\" value=\"\">";  
  60.         oTD = oTR.insertCell(3);  
  61.         oTD.innerHTML = "<b><font face='微软雅黑'><font color='blue'>"+productNo;+"</font></font></b> "  
  62.         oTD = oTR.insertCell(4);  
  63.         oTD.innerHTML = "<input type=\"text\" name=\"mr_cnumber\" maxLength=\"10\" value=\""+cnumber+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  64.         oTD = oTR.insertCell(5);  
  65.         oTD.innerHTML = "<input type=\"text\" name=\"mr_grossWeight\" maxLength=\"10\" value=\""+grossWeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  66.         oTD = oTR.insertCell(6);  
  67.         oTD.innerHTML = "<input type=\"text\" name=\"mr_netWeight\" maxLength=\"10\" value=\""+netWeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  68.         oTD = oTR.insertCell(7);  
  69.         oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeLength\" maxLength=\"10\" value=\""+sizeLength+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  70.         oTD = oTR.insertCell(8);  
  71.         oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeWidth\" maxLength=\"10\" value=\""+sizeWidth+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  72.         oTD = oTR.insertCell(9);  
  73.         oTD.innerHTML = "<input type=\"text\" name=\"mr_sizeHeight\" maxLength=\"10\" value=\""+sizeHeight+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  74.         oTD = oTR.insertCell(10);  
  75.         oTD.innerHTML = "<input type=\"text\" name=\"mr_exPrice\" maxLength=\"10\" value=\""+exPrice+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  76.         oTD = oTR.insertCell(11);  
  77.         oTD.innerHTML = "<input type=\"text\" name=\"mr_tax\" maxLength=\"10\" value=\""+tax+"\" onBlur=\"setTRUpdateFlag(this);\" size=\"15\">";  
  78.   
  79.   
  80.         dragtableinit();    //拖动表格行  
  81.         sortnoTR();         //排序号  
  82.           
  83.     }      
  84.   
  85.   
  86.     </script>  
  87. </head>  
  88. <body>  
  89. <form method="post">  
  90.   
  91.   
  92. <div id="menubar">  
  93. <div id="middleMenubar">  
  94. <div id="innerMenubar">  
  95.     <div id="navMenubar">  
  96. <ul>  
  97. <li id="save"><a href="#" onclick="formSubmit('update.action','_self');">确定</a></li>  
  98. <li id="back"><a href="list.action">返回</a></li>  
  99. </ul>  
  100.     </div>  
  101. </div>  
  102. </div>  
  103. </div>  
  104.        
  105. <div class="textbox" id="centerTextbox">  
  106.       
  107.     <div class="textbox-header">  
  108.     <div class="textbox-inner-header">  
  109.     <div class="textbox-title">  
  110.         修改出口报运信息  
  111.     </div>   
  112.     </div>  
  113.     </div>  
  114. <div>  
  115.    
  116.     <div>  
  117.         <table class="commonTable" cellspacing="1">  
  118.                 <input type="hidden" name="id" value="${obj.id}"/>  
  119.                 <tr>  
  120.                     <td class="columnTitle_mustbe">合同或确认书号:</td>  
  121.                     <td class="tableContent">${obj.customerContract }</td>  
  122.                     <td class="columnTitle_mustbe">制单日期:</td>  
  123.                     <td class="tableContent">  
  124.                     <input type="text" style="width: 90px" name="inputDate" class="Wdate" value="<fmt:formatDate value="${obj.inputDate }" pattern="yyyy-MM-dd"/>"  
  125.                      onclick="WdatePicker({el:this,isShowOthers:true,dateFmt:'yyyy-MM-dd'});"/>  
  126.                     </td>  
  127.                 </tr>  
  128.                   
  129.                 <tr>  
  130.                     <td class="columnTitle_mustbe">信用证号:</td>  
  131.                     <td class="tableContent"><input type="text" name="lcno" value="${obj.lcno }"/></td>  
  132.                     <td class="columnTitle_mustbe">收货人及地址:</td>  
  133.                     <td class="tableContent"><input type="text" name="consignee" value="${obj.consignee}"/></td>  
  134.                 </tr>  
  135.                   
  136.                 <tr>  
  137.                     <td class="columnTitle_mustbe">装运港:</td>  
  138.                     <td class="tableContent"><input type="text" name="shipmentPort" value="${obj.shipmentPort}"/></td>  
  139.                     <td class="columnTitle_mustbe">目的港:</td>  
  140.                     <td class="tableContent"><input type="text" name="destinationPort" value="${obj.destinationPort}"/></td>  
  141.                 </tr>  
  142.                   
  143.                 <tr>  
  144.                     <td class="columnTitle_mustbe">价格条件:</td>  
  145.                     <td class="tableContent">  
  146.                     <input type="radio" name="priceCondition" value="2" <c:if test="${obj.priceCondition=='FOB'}"> checked="checked"</c:if>/>FOB  
  147.                     <input type="radio" name="priceCondition" value="1" <c:if test="${obj.priceCondition=='CIF'}"> checked="checked"</c:if>/>CIF  
  148.                     </td>  
  149.                     <td class="columnTitle_mustbe">运输方式:</td>  
  150.                     <td class="tableContent">  
  151.                     <input type="radio" name="transportMode" value="2" <c:if test="${obj.transportMode=='AIR'}"> checked="checked"</c:if>/>AIR  
  152.                     <input type="radio" name="transportMode" value="1" <c:if test="${obj.transportMode=='SEA'}"> checked="checked"</c:if>/>SEA  
  153.                     </td>  
  154.                 </tr>  
  155.                   
  156.                 <tr>  
  157.                     <td class="columnTitle_mustbe">唛头:</td>  
  158.                     <td class="tableContent"><textarea  name="marks" style="height:200px;width: 400px">${obj.marks}</textarea></td>  
  159.                     <td class="columnTitle_mustbe">备注:</td>  
  160.                     <td class="tableContent"><textarea  name="remark" style="height:200px;width: 400px">${obj.remark}</textarea></td>  
  161.                 </tr>  
  162.             </table>  
  163.     </div>  
  164. </div>  
  165.   
  166.   
  167. <div class="textbox" id="centerTextbox">  
  168.       
  169.     <div class="textbox-header">  
  170.     <div class="textbox-inner-header">  
  171.     <div class="textbox-title">  
  172.         报运下货物的列表信息  
  173.     </div>   
  174.     </div>  
  175.     </div>  
  176. <div>   
  177.    
  178. <div class="listTablew">  
  179.         <table class="commonTable_main" cellSpacing="1" id="mRecordTable">  
  180.             <tr class="rowTitle" align="middle">  
  181.                 <td width="25" title="可以拖动下面行首,实现记录的位置移动.">  
  182.                     <img src="../../images/drag.gif">  
  183.                 </td>  
  184.                 <td width="20">  
  185.                     <input class="input" type="checkbox" name="ck_del" onclick="checkGroupBox(this);" />  
  186.                 </td>  
  187.                 <td width="33">序号</td>  
  188.                 <td>货号</td>  
  189.                 <td>数量</td>  
  190.                 <td>毛重</td>  
  191.                 <td>净重</td>  
  192.                 <td></td>  
  193.                 <td></td>  
  194.                 <td></td>  
  195.                 <td>出口单价</td>  
  196.                 <td>含税</td>  
  197.             </tr>  
  198.         </table>  
  199.     </div>  
  200.   
  201.   
  202.   
  203.   
  204.     </div>  
  205.     <div class="textbox-bottom">  
  206.         <div class="textbox-inner-bottom">  
  207.             <div class="textbox-go-top">  
  208.             </div>  
  209.         </div>  
  210.     </div>  
  211. </div>  
  212.    
  213. </form>  
  214. </body>  
  215. </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中新增一个方法:
[java]  view plain copy
  1. //拼接javascript方法串  
  2. //addTRRecord(objId, id, productNo, cnumber, grossWeight, netWeight, sizeLength, sizeWidth, sizeHeight, exPrice, tax)  
  3. @Override  
  4. public String getMrecordData(String exportId){  
  5.     Map paraMap=new HashMap();  
  6.     paraMap.put("exportId", exportId);  
  7.       
  8.     List<ExportProduct> oList=exportProductDao.find(paraMap);  
  9.   
  10.   
  11.     StringBuffer sBuf=new StringBuffer();  
  12.       
  13.     for (ExportProduct ep:oList) {  
  14.             sBuf.append("addTRRecord(\"mRecordTable\", \"")  
  15.             .append(ep.getId()).append("\", \"").append(ep.getProductNo())  
  16.             .append("\", \"").append(ep.getCnumber()).append("\", \"").append(UtilFuns.convertNull(ep.getGrossWeight()))  
  17.             .append("\", \"").append(UtilFuns.convertNull(ep.getNetWeight())).append("\", \"").append(UtilFuns.convertNull(ep.getSizeLength()))  
  18.             .append("\", \"").append(UtilFuns.convertNull(ep.getSizeWidth())).append("\", \"").append(UtilFuns.convertNull(ep.getSizeHeight()))  
  19.             .append("\", \"").append(UtilFuns.convertNull(ep.getExPrice())).append("\", \"").append(UtilFuns.convertNull(ep.getTax())).append("\");");  
  20.         }  
  21.       
  22.     return sBuf.toString();  
  23.       
  24. }  
(其中convertNull()方法是我们字符串处理工具类UtilFuns中检测null并返回空串""的方法)

这个方法会返回封装了相应出口报运下的所有货物的属性的js方法,这样在界面上就会增加新的包含真实货物数据的行。

这个方法在我们准备跳转到编辑页面的时候执行,所以我们在Controller的toupdate方法中添加这个方法:
[java]  view plain copy
  1. //转向修改界面  
  2. @RequestMapping("/cargo/export/toupdate.action")  
  3. public String toupdate(String id,Model model){  
  4.     Export obj=exportService.get(id);  
  5.     model.addAttribute("obj", obj);  
  6.       
  7.     //准备批量修改控件的数据mrecord  
  8.     model.addAttribute("mRecordData",exportService.getMrecordData(id));  
  9.       
  10.     return "/cargo/export/jExportUpdate.jsp";  
  11. }  
ok,然后我们进行测试,现在点击修改第一行的出口报运信息:

得到页面:

发现我们得到了出口报运下的所有货物的信息。
可以看到,我们的一些信息显示为空,这里我们就可以进行修改了。

2)批量提交

我们之前说过,修改报运下的货物信息时,用户修改货物的数量只能改小。如果用户故意把它货物数量改大,我们会检测到,然后相应的input框的背景会变成红色,而且提交的时候会告诉用户不能提交。

如果已经分次报运,它只显示剩余的值=合同的货物总数-实际出货数量。

那么当我们提交数据的时候,货物信息都是js生成的,所有列的name属性都是一样的,那么我们提交的时候信息就会封装成一个String数组,总之会有以下几种方法来获取货物表格的值:

A.页面上使用同名框,使用reqest.getParameterValues()获取货物表格的值,形成一个Sring数组。

B.Struts2框架封装为可以根据它的类型数组,改造ModelDriver
字符类型,将多个值拼接成一个字符串,之间用逗号+空格隔开
整形、浮点型、日期等,只保留第一个

C.Springmvc框架封装为数组,在方法调用参数上声明
字符类型,将多个值拼接成一个字符串,之间用逗号隔开
整形、浮点型、日期等,只保留第一个


所以我们修改就不单单修改出口报运信息了,我们还要把我们批量修改的货物信息要求一并修改,所以我们要在Controller中修改我们的update方法:

首先修改参数(利用Springmvc的同名参数封装),修改Service传入的参数:
[java]  view plain copy
  1. //进行修改  
  2. @RequestMapping("/cargo/export/update.action")  
  3. public String update(Export export,String [] mr_id,  
  4.     Integer [] mr_orderNo,Integer [] mr_cnumber,  
  5.     Double [] mr_grossWeight,Double [] mr_netWeight,  
  6.     Double [] mr_sizeLength,Double [] mr_sizeWidth,  
  7.     Double [] mr_sizeHeight,Double [] mr_exPrice,  
  8.     Double [] mr_tax){  
  9.       
  10.     exportService.update(export,mr_id,mr_orderNo,  
  11.             mr_cnumber,mr_grossWeight,mr_netWeight,  
  12.             mr_sizeLength,mr_sizeWidth,  
  13.             mr_sizeHeight,mr_exPrice,  
  14.             mr_tax);  
  15.       
  16.     return "redirect:/cargo/export/list.action";  
  17. }  

然后我们把Service的接口和实现方法中的参数也替换掉,下面我们在ExportService中的update方法中对我们取得的数据进行处理:
[java]  view plain copy
  1. @Override  
  2. public void update(Export export,String [] mr_id,  
  3.         Integer [] mr_orderNo,Integer [] mr_cnumber,  
  4.         Double [] mr_grossWeight,Double [] mr_netWeight,  
  5.         Double [] mr_sizeLength,Double [] mr_sizeWidth,  
  6.         Double [] mr_sizeHeight,Double [] mr_exPrice,  
  7.         Double [] mr_tax) {  
  8.       
  9.     exportDao.update(export);  
  10.     //批量修改货物信息  
  11.       
  12.     for (int i = 0; i < mr_id.length; i++) {  
  13.         ExportProduct ep=exportProductDao.get(mr_id[i]);  
  14.         ep.setOrderNo(mr_orderNo[i].toString());  
  15.         ep.setCnumber(mr_cnumber[i]);  
  16.         ep.setGrossWeight(mr_grossWeight[i]);  
  17.         ep.setNetWeight(mr_netWeight[i]);  
  18.         ep.setSizeLength(mr_sizeLength[i]);  
  19.         ep.setSizeWidth(mr_sizeWidth[i]);  
  20.         ep.setSizeHeight(mr_sizeHeight[i]);  
  21.         ep.setExPrice(mr_exPrice[i]);  
  22.         ep.setTax(mr_tax[i]);  
  23.           
  24.         exportProductDao.update(ep);  
  25.     }  
  26.       
  27. }  

我们进行测试:

点击修改:



然后填写数据,点击保存:



再次点击修改时,发现货物数值已经被保存(加点是因为我们保存的是浮点数),批量修改成功!


这个时候其实是有一个问题的,我们的修改并不一定是所有的值都要进行修改,可能我们只简单的修改一个值,没有必要把所有货物的值全部都传递过去修改。

所以我们要进行优化。

3)批量保存优化

我们的优化方法就是:哪个框修改了,我们就在后台只修改这个框的数值。
我们在每一个框后面加一个隐藏域(hidden的input),里面是“mr_changed”属性,当你修改某一行的数据的时候,鼠标抬起的时候我们检测鼠标抬起事件(setTRUpdateFlag(this)),然后在相应行的“mr_changed”属性input隐藏域中设定值,“1”是这一行被改过,没数值就没有改过。这样我们在后台只需要修改“mr_change”属性为1的信息,这样我们系统就优化了。

回顾鼠标抬起js方法(之前只能在IE上使用,现在我修改了一下):
[javascript]  view plain copy
  1. //鼠标抬起时为该行添加更改标记  
  2. function setTRUpdateFlag(obj){  
  3.           
  4.         var currTr = obj.parentElement.parentElement;  
  5.         if(currTr.innerHTML.toLowerCase().indexOf("<span")==0){  
  6.             currTr = obj.parentElement.parentElement.parentElement;  
  7.         }  
  8.           
  9.         if(obj.value!=obj.defaultValue){    //当填写的框内容发生变化时,设置本行记录发生变化标识  
  10.             currTr.cells[1].childNodes[2].value = "1";  
  11.         }  
  12.           
  13. }  

Controller:
[java]  view plain copy
  1. //进行修改  
  2. @RequestMapping("/cargo/export/update.action")  
  3. public String update(Export export,String [] mr_id,  
  4.     Integer [] mr_orderNo,Integer [] mr_cnumber,  
  5.     Double [] mr_grossWeight,Double [] mr_netWeight,  
  6.     Double [] mr_sizeLength,Double [] mr_sizeWidth,  
  7.     Double [] mr_sizeHeight,Double [] mr_exPrice,  
  8.     Double [] mr_tax,Integer [] mr_changed){  
  9.       
  10.     exportService.update(export,mr_id,mr_orderNo,  
  11.             mr_cnumber,mr_grossWeight,mr_netWeight,  
  12.             mr_sizeLength,mr_sizeWidth,  
  13.             mr_sizeHeight,mr_exPrice,  
  14.             mr_tax,mr_changed);  
  15.       
  16.     return "redirect:/cargo/export/list.action";  
  17. }  

Service:

[java]  view plain copy
  1. @Override  
  2. public void update(Export export,String [] mr_id,  
  3.         Integer [] mr_orderNo,Integer [] mr_cnumber,  
  4.         Double [] mr_grossWeight,Double [] mr_netWeight,  
  5.         Double [] mr_sizeLength,Double [] mr_sizeWidth,  
  6.         Double [] mr_sizeHeight,Double [] mr_exPrice,  
  7.         Double [] mr_tax,Integer [] mr_changed) {  
  8.       
  9.     exportDao.update(export);  
  10.     //批量修改货物信息  
  11.       
  12.     for (int i = 0; i < mr_id.length; i++) {  
  13.         if(mr_changed[i]!=null && mr_changed[i]==1){    //修改标识,只有用户修改的才进行更新  
  14.             ExportProduct ep=exportProductDao.get(mr_id[i]);  
  15.             ep.setOrderNo(mr_orderNo[i].toString());  
  16.             ep.setCnumber(mr_cnumber[i]);  
  17.             ep.setGrossWeight(mr_grossWeight[i]);  
  18.             ep.setNetWeight(mr_netWeight[i]);  
  19.             ep.setSizeLength(mr_sizeLength[i]);  
  20.             ep.setSizeWidth(mr_sizeWidth[i]);  
  21.             ep.setSizeHeight(mr_sizeHeight[i]);  
  22.             ep.setExPrice(mr_exPrice[i]);  
  23.             ep.setTax(mr_tax[i]);  
  24.               
  25.             exportProductDao.update(ep);  
  26.         }  
  27.     }  
  28.       
  29. }  

至此我们完成了出口报运下的货物批量修改以及优化工作。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值