`

jqGrid与Struts2的结合应用(三) —— 使用自定义表单对话框编辑Grid数据

 
阅读更多

上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗?

这一篇就来说说服务器端的操作。

首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。

  1. packagecn.gengv.struts2ex.jqGrid;
  2. importjava.util.List;
  3. importcom.byzl.hare.model.Contact;
  4. importcom.byzl.hare.model.PatentCase;
  5. importcom.byzl.hare.service.ContactService;
  6. importcom.opensymphony.xwork2.ActionSupport;
  7. @SuppressWarnings("serial")
  8. publicclassViewContactActionextendsActionSupport{
  9. privateContactcontact;
  10. privateList<PatentCase>patentCases;
  11. privateContactServicecontactService;
  12. privateStringajaxResult;
  13. publicStringviewContact(){
  14. intid=contact.getId();
  15. contact=contactService.queryById(contact.getId());
  16. if(contact==null){
  17. ajaxResult="未能找到ID为"+id+"的联系人";
  18. returnERROR;
  19. }
  20. ajaxResult=SUCCESS;
  21. returnSUCCESS;
  22. }
  23. publicContactgetContact(){
  24. returncontact;
  25. }
  26. publicvoidsetContact(Contactcontact){
  27. this.contact=contact;
  28. }
  29. publicStringgetAjaxResult(){
  30. returnajaxResult;
  31. }
  32. publicvoidsetAjaxResult(StringajaxResult){
  33. this.ajaxResult=ajaxResult;
  34. }
  35. publicvoidsetContactService(ContactServicecontactService){
  36. this.contactService=contactService;
  37. }
  38. publicList<PatentCase>getPatentCases(){
  39. returnpatentCases;
  40. }
  41. publicvoidsetPatentCases(List<PatentCase>patentCases){
  42. this.patentCases=patentCases;
  43. }
  44. }

  1. packagecn.gengv.struts2ex.jqGrid;
  2. importcom.byzl.hare.model.Contact;
  3. importcom.byzl.hare.service.ContactService;
  4. importcom.opensymphony.xwork2.ActionSupport;
  5. @SuppressWarnings("serial")
  6. publicclassContactConsoleActionextendsActionSupport{
  7. privateContactServicecontactService;
  8. privateContactcontact;
  9. privateStringajaxResult;
  10. //创建新的Contact
  11. publicStringcreateContact(){
  12. try{
  13. contact.setId(this.contactService.addNew(contact));
  14. ajaxResult=SUCCESS;
  15. returnSUCCESS;
  16. }catch(Exceptione){
  17. e.printStackTrace();
  18. this.addActionError(e.getMessage());
  19. ajaxResult="创建新联系人失败!"+e.getMessage();
  20. returnERROR;
  21. }
  22. }
  23. //更新Contact信息
  24. publicStringupdateContact(){
  25. try{
  26. this.contactService.update(contact);
  27. }catch(Exceptione){
  28. e.printStackTrace();
  29. this.addActionError(e.getMessage());
  30. ajaxResult="更新联系人信息失败!"+e.getMessage();
  31. returnERROR;
  32. }
  33. ajaxResult=SUCCESS;
  34. returnSUCCESS;
  35. }
  36. //删除Contact
  37. publicStringdeleteContact(){
  38. try{
  39. this.contactService.delete(contact);
  40. }catch(Exceptione){
  41. e.printStackTrace();
  42. this.addActionError(e.getMessage());
  43. ajaxResult="删除联系人失败!"+e.getMessage();
  44. returnERROR;
  45. }
  46. ajaxResult=SUCCESS;
  47. returnSUCCESS;
  48. }
  49. publicContactgetContact(){
  50. returncontact;
  51. }
  52. publicvoidsetContact(Contactcontact){
  53. this.contact=contact;
  54. }
  55. publicStringgetAjaxResult(){
  56. returnajaxResult;
  57. }
  58. publicvoidsetAjaxResult(StringajaxResult){
  59. this.ajaxResult=ajaxResult;
  60. }
  61. publicvoidsetContactService(ContactServicecontactService){
  62. this.contactService=contactService;
  63. }
  64. }

说明:

  • 因为客户端会和Server进行ajax交互,所以我在类里面加入了一个成员变量ajaxResult,用来保存操作实际的结果。当action产生json类型的result时,这个成员变量也会被串行化进json结果中,发送到客户端。客户端的javascript代码会解析这个值,以执行相应操作。
  • 这两个类都是用了Object-backed Action的方式来传递数据(关于Object-backed Action可以参考《Struts2 in Action》一书的3.4节)。

在配置文件中,按如下配置Action:

  1. <actionname="viewContact"
  2. class="cn.gengv.struts2ex.jqGrid.ViewContactAction"method="viewContact">
  3. <resultname="success"type="json">
  4. <paramname="includeProperties">
  5. contact.*,ajaxResult
  6. </param>
  7. <paramname="noCache">true</param>
  8. <paramname="ignoreHierarchy">false</param>
  9. <paramname="excludeNullProperties">true</param>
  10. </result>
  11. </action>
  12. <actionname="createContact"
  13. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="createContact">
  14. <resultname="success"type="json">
  15. <paramname="includeProperties">
  16. contact/.id,ajaxResult
  17. </param>
  18. <paramname="noCache">true</param>
  19. <paramname="ignoreHierarchy">false</param>
  20. </result>
  21. </action>
  22. <actionname="updateContact"
  23. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="updateContact">
  24. <resultname="success"type="json">
  25. <paramname="includeProperties">
  26. contact/.id,ajaxResult
  27. </param>
  28. <paramname="noCache">true</param>
  29. <paramname="ignoreHierarchy">false</param>
  30. </result>
  31. </action>
  32. <actionname="deleteContact"
  33. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="deleteContact">
  34. <resultname="success"type="json">
  35. <paramname="includeProperties">
  36. contact/.id,ajaxResult
  37. </param>
  38. <paramname="noCache">true</param>
  39. <paramname="ignoreHierarchy">false</param>
  40. </result>
  41. </action>

说明:

  • 请注意result的类型为json,而且includeProperties属性中包括ajaxResult这个成员变量名;
  • 由于添加contact时,id属性值是由后台自动生成的,因此需要将这个值传回客户端作为Grid的行id值。

服务器端的代码似乎没有什么更多需要说明的地方了,应该一目了然。

下面看看客户端部分,这里面似乎有不少值得说明一下的部分。

首先看一下html的完整代码:

  1. <!DOCTYPEhtml
  2. PUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="zh-CN"lang="zh-CN">
  5. <head>
  6. <title>jqGrid03</title>
  7. <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/jquery-ui-1.8.1.custom.css"mce_href="css/themes/aero/jquery-ui-1.8.1.custom.css"/>
  8. <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/ui.jqgrid.custom.css"mce_href="css/themes/aero/ui.jqgrid.custom.css"/>
  9. <linkhref="../css/genericFormTable.css"mce_href="css/genericFormTable.css"rel="stylesheet"type="text/css"/>
  10. <mce:scripttype="text/javascript"src="../js/jquery-1.4.2.min.js"mce_src="js/jquery-1.4.2.min.js"></mce:script>
  11. <mce:scriptsrc="../js/jquery-ui-1.8.1.custom.min.js"mce_src="js/jquery-ui-1.8.1.custom.min.js"type="text/javascript"></mce:script>
  12. <mce:scriptsrc="../js/i18n/grid.locale-zh-CN.js"mce_src="js/i18n/grid.locale-zh-CN.js"type="text/javascript"></mce:script>
  13. <mce:scriptsrc="../js/jquery.jqGrid.min.js"mce_src="js/jquery.jqGrid.min.js"type="text/javascript"></mce:script>
  14. <mce:scriptsrc="js/jqGrid03.js"mce_src="js/jqGrid03.js"type="text/javascript"></mce:script>
  15. </head>
  16. <body>
  17. <h3>
  18. jqGrid测试03
  19. </h3>
  20. <div>
  21. <tableid="gridTable"></table>
  22. <divid="gridPager"></div>
  23. </div>
  24. <br/>
  25. <div>
  26. <buttononclick="openDialog4Adding()">添加联系人</button>
  27. <buttononclick="openDialog4Updating()">修改联系人</button>
  28. <buttononclick="openDialog4Deleting()">删除联系人</button>
  29. </div>
  30. <divid="consoleDlg">
  31. <divid="formContainer">
  32. <formid="consoleForm">
  33. <inputtype="hidden"id="selectId"/>
  34. <tableclass="formTable">
  35. <tr>
  36. <th>姓:</th>
  37. <td>
  38. <inputtype="text"class="textField"id="lastName"name="lastName"/>
  39. </td>
  40. </tr>
  41. <tr>
  42. <th>名:</th>
  43. <td>
  44. <inputtype="text"class="textField"id="firstName"name="firstName"/>
  45. </td>
  46. </tr>
  47. <tr>
  48. <th>国籍:</th>
  49. <td>
  50. <inputtype="text"class="textField"id="nationality"name="nationality"/>
  51. </td>
  52. </tr>
  53. <tr>
  54. <th>身份证号:</th>
  55. <td>
  56. <inputtype="text"class="textField"id="idCardNo"name="idCardNo"/>
  57. </td>
  58. </tr>
  59. <tr>
  60. <th>电子邮箱:</th>
  61. <td>
  62. <inputtype="text"class="textField"id="email"name="email"/>
  63. </td>
  64. </tr>
  65. <tr>
  66. <th>电话:</th>
  67. <td>
  68. <inputtype="text"class="textField"id="telNo"name="telNo"/>
  69. </td>
  70. </tr>
  71. <tr>
  72. <th>地址:</th>
  73. <td>
  74. <inputtype="text"class="textField"id="address"name="address"/>
  75. </td>
  76. </tr>
  77. </table>
  78. </form>
  79. </div>
  80. </div>
  81. </body>
  82. </html>

相比较之前的例子,这个例子最重要的变化是添加了一个id为consoleDlg的<div>块。在javascript的页面初始化部分我将使用jQuery UI的API将这个div生成为一个模态对话框,用作编辑数据的界面。

虽然jqGrid也提供了表单格式的编辑数据的界面,但是我个人感觉那个界面太基础,适用于简单的数据编辑情况,对于复杂的情况,可能还是自己写点代码更加灵活。

另一个项目中,我自己实现的相对复杂的表单界面:

回到本例中,上面的“对话框”div中,有一个form,其中有一个<input type="hidden" id="selectId"/>(当准备修改或者删除一行记录的时候,这行的id将被保存在这里,以备后用),以及若干个<input type="text">。

再来看看javascript部分,javascript部分主要功能分成几块:

  • 初始化表格;
  • 初始化对话框;
  • 添加记录时打开对话框;
  • 执行添加操作;
  • 载入行数据到对话框;
  • 修改记录时打开对话框;
  • 执行修改操作;
  • 删除记录时打开对话框;
  • 执行删除操作。

先看一下完整代码,然后逐块分析:

[javascript] view plaincopyprint?
  1. $(function(){
  2. //配置jqGrid组件
  3. $("#gridTable").jqGrid({
  4. url:"jqGrid03.action",
  5. datatype:"json",
  6. mtype:"GET",
  7. height:350,
  8. width:600,
  9. colModel:[
  10. {name:"id",index:"id",label:"编码",width:40},
  11. {name:"lastName",index:"lastName",label:"姓",width:80,sortable:false},
  12. {name:"firstName",index:"firstName",label:"名",width:80,sortable:false},
  13. {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
  14. {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
  15. ],
  16. viewrecords:true,
  17. rowNum:15,
  18. rowList:[15,50,100],
  19. prmNames:{search:"search"},
  20. jsonReader:{
  21. root:"gridModel",
  22. records:"record",
  23. repeatitems:false
  24. },
  25. pager:"#gridPager",
  26. caption:"联系人列表",
  27. hidegrid:false,
  28. shrikToFit:true
  29. });
  30. //配置对话框
  31. $("#consoleDlg").dialog({
  32. autoOpen:false,
  33. modal:true,//设置对话框为模态(modal)对话框
  34. resizable:true,
  35. width:480,
  36. buttons:{//为对话框添加按钮
  37. "取消":function(){$("#consoleDlg").dialog("close")},
  38. "创建":addContact,
  39. "保存":updateContact,
  40. "删除":deleteContact
  41. }
  42. });
  43. });
  44. varopenDialog4Adding=function(){
  45. varconsoleDlg=$("#consoleDlg");
  46. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  47. consoleDlg.find("input").removeAttr("disabled").val("");
  48. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  49. dialogButtonPanel.find("button:contains('创建')").show();
  50. consoleDlg.dialog("option","title","创建新联系人").dialog("open");
  51. };
  52. varopenDialog4Updating=function(){
  53. varconsoleDlg=$("#consoleDlg");
  54. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  55. consoleDlg.find("input").removeAttr("disabled");
  56. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  57. dialogButtonPanel.find("button:contains('保存')").show();
  58. consoleDlg.dialog("option","title","修改联系人信息");
  59. loadSelectedRowData();
  60. }
  61. varopenDialog4Deleting=function(){
  62. varconsoleDlg=$("#consoleDlg");
  63. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  64. consoleDlg.find("input").attr("disabled",true);
  65. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  66. dialogButtonPanel.find("button:contains('删除')").show();
  67. consoleDlg.dialog("option","title","删除联系人");
  68. loadSelectedRowData();
  69. }
  70. varloadSelectedRowData=function(){
  71. varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
  72. if(!selectedRowId){
  73. alert("请先选择需要编辑的行!");
  74. returnfalse;
  75. }else{
  76. varparams={
  77. "contact.id":selectedRowId
  78. };
  79. varactionUrl="viewContact.action";
  80. //从Server读取对应ID的JSON数据
  81. $.ajax({
  82. url:actionUrl,
  83. data:params,
  84. dataType:"json",
  85. cache:false,
  86. error:function(textStatus,errorThrown){
  87. alert("系统ajax交互错误:"+textStatus);
  88. },
  89. success:function(data,textStatus){
  90. //如果读取结果成功,则将信息载入到对话框中
  91. varrowData=data.contact;
  92. varconsoleDlg=$("#consoleDlg");
  93. consoleDlg.find("#selectId").val(rowData.id);
  94. consoleDlg.find("#lastName").val(rowData.lastName);
  95. consoleDlg.find("#firstName").val(rowData.firstName);
  96. consoleDlg.find("#certificateNo").val(rowData.certificateNo);
  97. consoleDlg.find("#email").val(rowData.email);
  98. consoleDlg.find("#telNo").val(rowData.telNo);
  99. consoleDlg.find("#address").val(rowData.address);
  100. consoleDlg.find("#idCardNo").val(rowData.idCardNo);
  101. consoleDlg.find("#nationality").val(rowData.nationality);
  102. //根据新载入的数据将表格中的对应数据行一并更新一下
  103. vardataRow={
  104. id:rowData.id,
  105. lastName:rowData.lastName,
  106. firstName:rowData.firstName,
  107. email:rowData.email,
  108. telNo:rowData.telNo
  109. };
  110. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
  111. //打开对话框
  112. consoleDlg.dialog("open");
  113. }
  114. });
  115. }
  116. };
  117. varaddContact=function(){
  118. varconsoleDlg=$("#consoleDlg");
  119. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  120. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  121. varpEmail=$.trim(consoleDlg.find("#email").val());
  122. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  123. varpAddress=$.trim(consoleDlg.find("#address").val());
  124. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  125. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  126. varparams={
  127. "contact.lastName":pLastName,
  128. "contact.firstName":pFirstName,
  129. "contact.email":pEmail,
  130. "contact.telNo":pTelNo,
  131. "contact.address":pAddress,
  132. "contact.idCardNo":pIdCardNo,
  133. "contact.nationality":pNationality
  134. };
  135. varactionUrl="createContact.action"
  136. $.ajax({
  137. url:actionUrl,
  138. data:params,
  139. dataType:"json",
  140. cache:false,
  141. error:function(textStatus,errorThrown){
  142. alert("系统ajax交互错误:"+textStatus);
  143. },
  144. success:function(data,textStatus){
  145. if(data.ajaxResult=="success"){
  146. vardataRow={
  147. id:data.contact.id,//从Server端得到系统分配的id
  148. lastName:pLastName,
  149. firstName:pFirstName,
  150. email:pEmail,
  151. telNo:pTelNo
  152. };
  153. varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");
  154. if(srcrowid){
  155. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);
  156. }else{
  157. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");
  158. }
  159. consoleDlg.dialog("close");
  160. alert("联系人添加操作成功!");
  161. }else{
  162. alert("添加操作失败!");
  163. }
  164. }
  165. });
  166. };
  167. varupdateContact=function(){
  168. varconsoleDlg=$("#consoleDlg");
  169. varpId=$.trim(consoleDlg.find("#selectId").val());
  170. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  171. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  172. varpEmail=$.trim(consoleDlg.find("#email").val());
  173. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  174. varpAddress=$.trim(consoleDlg.find("#address").val());
  175. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  176. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  177. varparams={
  178. "contact.id":pId,
  179. "contact.lastName":pLastName,
  180. "contact.firstName":pFirstName,
  181. "contact.email":pEmail,
  182. "contact.telNo":pTelNo,
  183. "contact.address":pAddress,
  184. "contact.idCardNo":pIdCardNo,
  185. "contact.nationality":pNationality
  186. };
  187. varactionUrl="updateContact.action";
  188. $.ajax({
  189. url:actionUrl,
  190. data:params,
  191. dataType:"json",
  192. cache:false,
  193. error:function(textStatus,errorThrown){
  194. alert("系统ajax交互错误:"+textStatus);
  195. },
  196. success:function(data,textStatus){
  197. if(data.ajaxResult=="success"){
  198. vardataRow={
  199. id:data.contact.id,
  200. lastName:pLastName,
  201. firstName:pFirstName,
  202. email:pEmail,
  203. telNo:pTelNo
  204. };
  205. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});
  206. alert("联系人信息更新成功!");
  207. consoleDlg.dialog("close");
  208. }else{
  209. alert("修改操作失败!");
  210. }
  211. }
  212. });
  213. };
  214. vardeleteContact=function(){
  215. varconsoleDlg=$("#consoleDlg");
  216. varpId=$.trim(consoleDlg.find("#selectId").val());
  217. varparams={
  218. "contact.id":pId
  219. };
  220. varactionUrl="deleteContact.action";
  221. $.ajax({
  222. url:actionUrl,
  223. data:params,
  224. dataType:"json",
  225. cache:false,
  226. error:function(textStatus,errorThrown){
  227. alert("系统ajax交互错误:"+textStatus);
  228. },
  229. success:function(data,textStatus){
  230. if(data.ajaxResult=="success"){
  231. $("#gridTable").jqGrid("delRowData",pId);
  232. consoleDlg.dialog("close");
  233. alert("联系人删除成功!");
  234. }else{
  235. alert("删除操作失败!");
  236. }
  237. }
  238. });
  239. };

1. 初始化Grid表格:
这一部分的代码,和上一篇中的例子完全相同,不再赘述。

2. 初始化对话框:

[javascript] view plaincopyprint?
  1. $("#consoleDlg").dialog({
  2. autoOpen:false,
  3. modal:true,//(1)设置对话框为模态(modal)对话框
  4. resizable:true,
  5. width:480,
  6. buttons:{//(2)为对话框添加按钮
  7. "取消":function(){$("#consoleDlg").dialog("close")},
  8. "创建":addContact,
  9. "保存":updateContact,
  10. "删除":deleteContact
  11. }
  12. });

说明:

(1)处将modal属性设为true,即将对话框设置为“模态”,当对话框打开状态时,下层的Grid表格式不能被编辑的(注意z-Index的值);

(2)处为对话框添加了4个按钮,因为增、删、查都共用一个对话框,所以添加4个按钮是比较方便的,只要控制它们不同状态下的显隐状态就OK了。点击每个按钮都会执行各自对应的函数。

注:jQuery UI的dialog方法可以详细参考jQuery UI的文档。

3. 添加记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Adding=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");//(1)
  4. consoleDlg.find("input").removeAttr("disabled").val("");//(2)
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();//(3)
  6. dialogButtonPanel.find("button:contains('创建')").show();//(4)
  7. consoleDlg.dialog("option","title","创建新联系人").dialog("open");//(5)
  8. };

说明:
(1)处先获得对话框按钮的父元素;

(2)将所有的input元素解除disabled状态(在打开删除对话框时,会diable这些input元素);

(3)(4)处调整对话框按钮的显示隐藏状态;

(5)更新对话框标题。

4. 执行添加操作:

[javascript] view plaincopyprint?
  1. varaddContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. //(1)
  4. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  5. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  6. varpEmail=$.trim(consoleDlg.find("#email").val());
  7. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  8. varpAddress=$.trim(consoleDlg.find("#address").val());
  9. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  10. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  11. varparams={
  12. "contact.lastName":pLastName,
  13. "contact.firstName":pFirstName,
  14. "contact.email":pEmail,
  15. "contact.telNo":pTelNo,
  16. "contact.address":pAddress,
  17. "contact.idCardNo":pIdCardNo,
  18. "contact.nationality":pNationality
  19. };
  20. varactionUrl="createContact.action"
  21. $.ajax({
  22. url:actionUrl,
  23. data:params,
  24. dataType:"json",
  25. cache:false,
  26. error:function(textStatus,errorThrown){//(2)
  27. alert("系统ajax交互错误:"+textStatus);
  28. },
  29. success:function(data,textStatus){//(3)
  30. if(data.ajaxResult=="success"){//(4)
  31. vardataRow={
  32. id:data.contact.id,//(5)从Server端得到系统分配的id
  33. lastName:pLastName,
  34. firstName:pFirstName,
  35. email:pEmail,
  36. telNo:pTelNo
  37. };
  38. varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");//(6)
  39. if(srcrowid){
  40. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);//(7)
  41. }else{
  42. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");//(8)
  43. }
  44. consoleDlg.dialog("close");
  45. alert("联系人添加操作成功!");
  46. }else{//(9)
  47. alert("添加操作失败!");
  48. }
  49. }
  50. });
  51. };

说明:

(1)从对话框的表单中读取各个输入项的值;
(2)在$.ajax()方法遇到error时,会提示错误(从而让jqGrid不再继续后面的Grid操作);
(3)如果$.ajax()成功,则执行回调函数,但是应当注意这里的“success”,是指ajax请求成功得到response,而不是Struts2 Action的“success”。当Action的result的name为“error”、“input”、“login”等的时候,只要它能够给客户端返回一个格式正确的json数据(我们这里定义了需要的是json),那么都会被认为是“success”;
(4)因此通过传回来的json数据中的ajaxResult项的值,来判断逻辑事务操作是否成功;(在正式项目中,我为不同的Action result定义了不同的ajaxResult值,以方便客户端判断,执行相应后续操作。这里为了演示简便,只定义了success一种,Action配置文件中也只定义了success结果,即使出现error或input等其他结果,Struts2也会因为找不到其他result配置,而抛出异常,也就不会向客户端发送json数据。客户端也就认为ajax请求失败了,从而执行$.ajax()中error项定义的回调方法。)
(5)如果执行成功,则根据Action配置文件的定义,json数据中会包括"contact.id":value这段数据;而jqGrid也就应该继续后续操作,更新Grid表格内的数据;
(6)获得最后选中行的行id;
(7)(8)如果最后选中行的行id不为null,则将新数据行插入到这行上面;否则将新数据加入到Grid的顶端;
(9)如果ajaxResult的值不为success,即逻辑实务操作没有成功,jqGrid不再进行后续操作,同时向用户提示操作失败。

5. 载入行数据到对话框:

当修改或者删除某行数据的时候,通常需要先打开这行记录,让用户看到并确认操作。这就需要将行数据载入到对话框中。

[javascript] view plaincopyprint?
  1. varloadSelectedRowData=function(){
  2. varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
  3. if(!selectedRowId){//(1)
  4. alert("请先选择需要编辑的行!");
  5. returnfalse;
  6. }else{
  7. varparams={
  8. "contact.id":selectedRowId
  9. };
  10. varactionUrl="viewContact.action";
  11. //从Server读取对应ID的JSON数据
  12. $.ajax({
  13. url:actionUrl,
  14. data:params,
  15. dataType:"json",
  16. cache:false,
  17. error:function(textStatus,errorThrown){
  18. alert("系统ajax交互错误:"+textStatus);
  19. },
  20. success:function(data,textStatus){
  21. //如果读取结果成功,则将信息载入到对话框中
  22. varrowData=data.contact;
  23. varconsoleDlg=$("#consoleDlg");
  24. //(2)
  25. consoleDlg.find("#selectId").val(rowData.id);
  26. consoleDlg.find("#lastName").val(rowData.lastName);
  27. consoleDlg.find("#firstName").val(rowData.firstName);
  28. consoleDlg.find("#certificateNo").val(rowData.certificateNo);
  29. consoleDlg.find("#email").val(rowData.email);
  30. consoleDlg.find("#telNo").val(rowData.telNo);
  31. consoleDlg.find("#address").val(rowData.address);
  32. consoleDlg.find("#idCardNo").val(rowData.idCardNo);
  33. consoleDlg.find("#nationality").val(rowData.nationality);
  34. //(3)根据新载入的数据将表格中的对应数据行一并更新一下
  35. vardataRow={
  36. id:rowData.id,
  37. lastName:rowData.lastName,
  38. firstName:rowData.firstName,
  39. email:rowData.email,
  40. telNo:rowData.telNo
  41. };
  42. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
  43. consoleDlg.dialog("open");//(4)
  44. }
  45. });
  46. }
  47. };

说明:

(1)如果没有行被选中,则提示用户;

(2)如果成功地从Server得到行数据,则将行数据的内容置入对话框表单中;

(3)根据新载入的数据将表格中的对应数据行一并更新一下;

(4)数据载入完毕后,打开对话框。

注:其实(3)是可选的部分,我的考虑是既然已经将最新的数据从Server取回来了,干脆就将Grid表格中的数据也更新一下。不论修改或删除操作是否被用户提交,更新一下数据总是好的,也不太费事。既然用户选择了这行数据,说明这行应该是用户关心的,有可能用户打开Grid页面一段时间了,而这行数据实际已经被其他用户更新了。当前用户通过打开对话框,也能得到最新的数据,即便没有修改或者删除,也不算无“功”而返啊。这主要也是从用户体验的角度出发。

6. 修改记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Updating=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  4. consoleDlg.find("input").removeAttr("disabled");
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  6. dialogButtonPanel.find("button:contains('保存')").show();
  7. consoleDlg.dialog("option","title","修改联系人信息");
  8. loadSelectedRowData();//(1)
  9. }

说明:
前几行的代码与添加记录是打开对话框时的过程相似,不再赘述;(1)处即在打开对话框之前,将对应行数据载入对话框。

7. 执行修改操作:

[javascript] view plaincopyprint?
  1. varupdateContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. varpId=$.trim(consoleDlg.find("#selectId").val());
  4. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  5. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  6. varpEmail=$.trim(consoleDlg.find("#email").val());
  7. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  8. varpAddress=$.trim(consoleDlg.find("#address").val());
  9. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  10. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  11. varparams={
  12. "contact.id":pId,
  13. "contact.lastName":pLastName,
  14. "contact.firstName":pFirstName,
  15. "contact.email":pEmail,
  16. "contact.telNo":pTelNo,
  17. "contact.address":pAddress,
  18. "contact.idCardNo":pIdCardNo,
  19. "contact.nationality":pNationality
  20. };
  21. varactionUrl="updateContact.action";
  22. $.ajax({
  23. url:actionUrl,
  24. data:params,
  25. dataType:"json",
  26. cache:false,
  27. error:function(textStatus,errorThrown){
  28. alert("系统ajax交互错误:"+textStatus);
  29. },
  30. success:function(data,textStatus){
  31. if(data.ajaxResult=="success"){
  32. vardataRow={
  33. id:data.contact.id,
  34. lastName:pLastName,
  35. firstName:pFirstName,
  36. email:pEmail,
  37. telNo:pTelNo
  38. };
  39. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});//(1)
  40. alert("联系人信息更新成功!");
  41. consoleDlg.dialog("close");
  42. }else{
  43. alert("修改操作失败!");
  44. }
  45. }
  46. });
  47. };

说明:参考执行添加操作的说明,这段应该很好理解。(1)处更新Grid中对应行的数据,并添加CSS样式。

8. 删除记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Deleting=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  4. consoleDlg.find("input").attr("disabled",true);//(1)
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  6. dialogButtonPanel.find("button:contains('删除')").show();
  7. consoleDlg.dialog("option","title","删除联系人");
  8. loadSelectedRowData();
  9. }

说明:(1)处将所有input全部disable掉,使之不能输入内容。

9. 执行删除操作:

[javascript] view plaincopyprint?
  1. vardeleteContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. varpId=$.trim(consoleDlg.find("#selectId").val());
  4. varparams={
  5. "contact.id":pId
  6. };
  7. varactionUrl="deleteContact.action";
  8. $.ajax({
  9. url:actionUrl,
  10. data:params,
  11. dataType:"json",
  12. cache:false,
  13. error:function(textStatus,errorThrown){
  14. alert("系统ajax交互错误:"+textStatus);
  15. },
  16. success:function(data,textStatus){
  17. if(data.ajaxResult=="success"){
  18. $("#gridTable").jqGrid("delRowData",pId);
  19. consoleDlg.dialog("close");
  20. alert("联系人删除成功!");
  21. }else{
  22. alert("删除操作失败!");
  23. }
  24. }
  25. });
  26. };




以上就是实际应用中,使用自定义表单对话框编辑Grid数据的过程。下一篇说一下排序与搜索。


上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗?

这一篇就来说说服务器端的操作。

首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。

  1. packagecn.gengv.struts2ex.jqGrid;
  2. importjava.util.List;
  3. importcom.byzl.hare.model.Contact;
  4. importcom.byzl.hare.model.PatentCase;
  5. importcom.byzl.hare.service.ContactService;
  6. importcom.opensymphony.xwork2.ActionSupport;
  7. @SuppressWarnings("serial")
  8. publicclassViewContactActionextendsActionSupport{
  9. privateContactcontact;
  10. privateList<PatentCase>patentCases;
  11. privateContactServicecontactService;
  12. privateStringajaxResult;
  13. publicStringviewContact(){
  14. intid=contact.getId();
  15. contact=contactService.queryById(contact.getId());
  16. if(contact==null){
  17. ajaxResult="未能找到ID为"+id+"的联系人";
  18. returnERROR;
  19. }
  20. ajaxResult=SUCCESS;
  21. returnSUCCESS;
  22. }
  23. publicContactgetContact(){
  24. returncontact;
  25. }
  26. publicvoidsetContact(Contactcontact){
  27. this.contact=contact;
  28. }
  29. publicStringgetAjaxResult(){
  30. returnajaxResult;
  31. }
  32. publicvoidsetAjaxResult(StringajaxResult){
  33. this.ajaxResult=ajaxResult;
  34. }
  35. publicvoidsetContactService(ContactServicecontactService){
  36. this.contactService=contactService;
  37. }
  38. publicList<PatentCase>getPatentCases(){
  39. returnpatentCases;
  40. }
  41. publicvoidsetPatentCases(List<PatentCase>patentCases){
  42. this.patentCases=patentCases;
  43. }
  44. }

  1. packagecn.gengv.struts2ex.jqGrid;
  2. importcom.byzl.hare.model.Contact;
  3. importcom.byzl.hare.service.ContactService;
  4. importcom.opensymphony.xwork2.ActionSupport;
  5. @SuppressWarnings("serial")
  6. publicclassContactConsoleActionextendsActionSupport{
  7. privateContactServicecontactService;
  8. privateContactcontact;
  9. privateStringajaxResult;
  10. //创建新的Contact
  11. publicStringcreateContact(){
  12. try{
  13. contact.setId(this.contactService.addNew(contact));
  14. ajaxResult=SUCCESS;
  15. returnSUCCESS;
  16. }catch(Exceptione){
  17. e.printStackTrace();
  18. this.addActionError(e.getMessage());
  19. ajaxResult="创建新联系人失败!"+e.getMessage();
  20. returnERROR;
  21. }
  22. }
  23. //更新Contact信息
  24. publicStringupdateContact(){
  25. try{
  26. this.contactService.update(contact);
  27. }catch(Exceptione){
  28. e.printStackTrace();
  29. this.addActionError(e.getMessage());
  30. ajaxResult="更新联系人信息失败!"+e.getMessage();
  31. returnERROR;
  32. }
  33. ajaxResult=SUCCESS;
  34. returnSUCCESS;
  35. }
  36. //删除Contact
  37. publicStringdeleteContact(){
  38. try{
  39. this.contactService.delete(contact);
  40. }catch(Exceptione){
  41. e.printStackTrace();
  42. this.addActionError(e.getMessage());
  43. ajaxResult="删除联系人失败!"+e.getMessage();
  44. returnERROR;
  45. }
  46. ajaxResult=SUCCESS;
  47. returnSUCCESS;
  48. }
  49. publicContactgetContact(){
  50. returncontact;
  51. }
  52. publicvoidsetContact(Contactcontact){
  53. this.contact=contact;
  54. }
  55. publicStringgetAjaxResult(){
  56. returnajaxResult;
  57. }
  58. publicvoidsetAjaxResult(StringajaxResult){
  59. this.ajaxResult=ajaxResult;
  60. }
  61. publicvoidsetContactService(ContactServicecontactService){
  62. this.contactService=contactService;
  63. }
  64. }

说明:

  • 因为客户端会和Server进行ajax交互,所以我在类里面加入了一个成员变量ajaxResult,用来保存操作实际的结果。当action产生json类型的result时,这个成员变量也会被串行化进json结果中,发送到客户端。客户端的javascript代码会解析这个值,以执行相应操作。
  • 这两个类都是用了Object-backed Action的方式来传递数据(关于Object-backed Action可以参考《Struts2 in Action》一书的3.4节)。

在配置文件中,按如下配置Action:

  1. <actionname="viewContact"
  2. class="cn.gengv.struts2ex.jqGrid.ViewContactAction"method="viewContact">
  3. <resultname="success"type="json">
  4. <paramname="includeProperties">
  5. contact.*,ajaxResult
  6. </param>
  7. <paramname="noCache">true</param>
  8. <paramname="ignoreHierarchy">false</param>
  9. <paramname="excludeNullProperties">true</param>
  10. </result>
  11. </action>
  12. <actionname="createContact"
  13. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="createContact">
  14. <resultname="success"type="json">
  15. <paramname="includeProperties">
  16. contact/.id,ajaxResult
  17. </param>
  18. <paramname="noCache">true</param>
  19. <paramname="ignoreHierarchy">false</param>
  20. </result>
  21. </action>
  22. <actionname="updateContact"
  23. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="updateContact">
  24. <resultname="success"type="json">
  25. <paramname="includeProperties">
  26. contact/.id,ajaxResult
  27. </param>
  28. <paramname="noCache">true</param>
  29. <paramname="ignoreHierarchy">false</param>
  30. </result>
  31. </action>
  32. <actionname="deleteContact"
  33. class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="deleteContact">
  34. <resultname="success"type="json">
  35. <paramname="includeProperties">
  36. contact/.id,ajaxResult
  37. </param>
  38. <paramname="noCache">true</param>
  39. <paramname="ignoreHierarchy">false</param>
  40. </result>
  41. </action>

说明:

  • 请注意result的类型为json,而且includeProperties属性中包括ajaxResult这个成员变量名;
  • 由于添加contact时,id属性值是由后台自动生成的,因此需要将这个值传回客户端作为Grid的行id值。

服务器端的代码似乎没有什么更多需要说明的地方了,应该一目了然。

下面看看客户端部分,这里面似乎有不少值得说明一下的部分。

首先看一下html的完整代码:

  1. <!DOCTYPEhtml
  2. PUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"
  3. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
  4. <htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="zh-CN"lang="zh-CN">
  5. <head>
  6. <title>jqGrid03</title>
  7. <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/jquery-ui-1.8.1.custom.css"mce_href="css/themes/aero/jquery-ui-1.8.1.custom.css"/>
  8. <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/ui.jqgrid.custom.css"mce_href="css/themes/aero/ui.jqgrid.custom.css"/>
  9. <linkhref="../css/genericFormTable.css"mce_href="css/genericFormTable.css"rel="stylesheet"type="text/css"/>
  10. <mce:scripttype="text/javascript"src="../js/jquery-1.4.2.min.js"mce_src="js/jquery-1.4.2.min.js"></mce:script>
  11. <mce:scriptsrc="../js/jquery-ui-1.8.1.custom.min.js"mce_src="js/jquery-ui-1.8.1.custom.min.js"type="text/javascript"></mce:script>
  12. <mce:scriptsrc="../js/i18n/grid.locale-zh-CN.js"mce_src="js/i18n/grid.locale-zh-CN.js"type="text/javascript"></mce:script>
  13. <mce:scriptsrc="../js/jquery.jqGrid.min.js"mce_src="js/jquery.jqGrid.min.js"type="text/javascript"></mce:script>
  14. <mce:scriptsrc="js/jqGrid03.js"mce_src="js/jqGrid03.js"type="text/javascript"></mce:script>
  15. </head>
  16. <body>
  17. <h3>
  18. jqGrid测试03
  19. </h3>
  20. <div>
  21. <tableid="gridTable"></table>
  22. <divid="gridPager"></div>
  23. </div>
  24. <br/>
  25. <div>
  26. <buttononclick="openDialog4Adding()">添加联系人</button>
  27. <buttononclick="openDialog4Updating()">修改联系人</button>
  28. <buttononclick="openDialog4Deleting()">删除联系人</button>
  29. </div>
  30. <divid="consoleDlg">
  31. <divid="formContainer">
  32. <formid="consoleForm">
  33. <inputtype="hidden"id="selectId"/>
  34. <tableclass="formTable">
  35. <tr>
  36. <th>姓:</th>
  37. <td>
  38. <inputtype="text"class="textField"id="lastName"name="lastName"/>
  39. </td>
  40. </tr>
  41. <tr>
  42. <th>名:</th>
  43. <td>
  44. <inputtype="text"class="textField"id="firstName"name="firstName"/>
  45. </td>
  46. </tr>
  47. <tr>
  48. <th>国籍:</th>
  49. <td>
  50. <inputtype="text"class="textField"id="nationality"name="nationality"/>
  51. </td>
  52. </tr>
  53. <tr>
  54. <th>身份证号:</th>
  55. <td>
  56. <inputtype="text"class="textField"id="idCardNo"name="idCardNo"/>
  57. </td>
  58. </tr>
  59. <tr>
  60. <th>电子邮箱:</th>
  61. <td>
  62. <inputtype="text"class="textField"id="email"name="email"/>
  63. </td>
  64. </tr>
  65. <tr>
  66. <th>电话:</th>
  67. <td>
  68. <inputtype="text"class="textField"id="telNo"name="telNo"/>
  69. </td>
  70. </tr>
  71. <tr>
  72. <th>地址:</th>
  73. <td>
  74. <inputtype="text"class="textField"id="address"name="address"/>
  75. </td>
  76. </tr>
  77. </table>
  78. </form>
  79. </div>
  80. </div>
  81. </body>
  82. </html>

相比较之前的例子,这个例子最重要的变化是添加了一个id为consoleDlg的<div>块。在javascript的页面初始化部分我将使用jQuery UI的API将这个div生成为一个模态对话框,用作编辑数据的界面。

虽然jqGrid也提供了表单格式的编辑数据的界面,但是我个人感觉那个界面太基础,适用于简单的数据编辑情况,对于复杂的情况,可能还是自己写点代码更加灵活。

另一个项目中,我自己实现的相对复杂的表单界面:

回到本例中,上面的“对话框”div中,有一个form,其中有一个<input type="hidden" id="selectId"/>(当准备修改或者删除一行记录的时候,这行的id将被保存在这里,以备后用),以及若干个<input type="text">。

再来看看javascript部分,javascript部分主要功能分成几块:

  • 初始化表格;
  • 初始化对话框;
  • 添加记录时打开对话框;
  • 执行添加操作;
  • 载入行数据到对话框;
  • 修改记录时打开对话框;
  • 执行修改操作;
  • 删除记录时打开对话框;
  • 执行删除操作。

先看一下完整代码,然后逐块分析:

[javascript] view plaincopyprint?
  1. $(function(){
  2. //配置jqGrid组件
  3. $("#gridTable").jqGrid({
  4. url:"jqGrid03.action",
  5. datatype:"json",
  6. mtype:"GET",
  7. height:350,
  8. width:600,
  9. colModel:[
  10. {name:"id",index:"id",label:"编码",width:40},
  11. {name:"lastName",index:"lastName",label:"姓",width:80,sortable:false},
  12. {name:"firstName",index:"firstName",label:"名",width:80,sortable:false},
  13. {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
  14. {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
  15. ],
  16. viewrecords:true,
  17. rowNum:15,
  18. rowList:[15,50,100],
  19. prmNames:{search:"search"},
  20. jsonReader:{
  21. root:"gridModel",
  22. records:"record",
  23. repeatitems:false
  24. },
  25. pager:"#gridPager",
  26. caption:"联系人列表",
  27. hidegrid:false,
  28. shrikToFit:true
  29. });
  30. //配置对话框
  31. $("#consoleDlg").dialog({
  32. autoOpen:false,
  33. modal:true,//设置对话框为模态(modal)对话框
  34. resizable:true,
  35. width:480,
  36. buttons:{//为对话框添加按钮
  37. "取消":function(){$("#consoleDlg").dialog("close")},
  38. "创建":addContact,
  39. "保存":updateContact,
  40. "删除":deleteContact
  41. }
  42. });
  43. });
  44. varopenDialog4Adding=function(){
  45. varconsoleDlg=$("#consoleDlg");
  46. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  47. consoleDlg.find("input").removeAttr("disabled").val("");
  48. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  49. dialogButtonPanel.find("button:contains('创建')").show();
  50. consoleDlg.dialog("option","title","创建新联系人").dialog("open");
  51. };
  52. varopenDialog4Updating=function(){
  53. varconsoleDlg=$("#consoleDlg");
  54. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  55. consoleDlg.find("input").removeAttr("disabled");
  56. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  57. dialogButtonPanel.find("button:contains('保存')").show();
  58. consoleDlg.dialog("option","title","修改联系人信息");
  59. loadSelectedRowData();
  60. }
  61. varopenDialog4Deleting=function(){
  62. varconsoleDlg=$("#consoleDlg");
  63. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  64. consoleDlg.find("input").attr("disabled",true);
  65. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  66. dialogButtonPanel.find("button:contains('删除')").show();
  67. consoleDlg.dialog("option","title","删除联系人");
  68. loadSelectedRowData();
  69. }
  70. varloadSelectedRowData=function(){
  71. varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
  72. if(!selectedRowId){
  73. alert("请先选择需要编辑的行!");
  74. returnfalse;
  75. }else{
  76. varparams={
  77. "contact.id":selectedRowId
  78. };
  79. varactionUrl="viewContact.action";
  80. //从Server读取对应ID的JSON数据
  81. $.ajax({
  82. url:actionUrl,
  83. data:params,
  84. dataType:"json",
  85. cache:false,
  86. error:function(textStatus,errorThrown){
  87. alert("系统ajax交互错误:"+textStatus);
  88. },
  89. success:function(data,textStatus){
  90. //如果读取结果成功,则将信息载入到对话框中
  91. varrowData=data.contact;
  92. varconsoleDlg=$("#consoleDlg");
  93. consoleDlg.find("#selectId").val(rowData.id);
  94. consoleDlg.find("#lastName").val(rowData.lastName);
  95. consoleDlg.find("#firstName").val(rowData.firstName);
  96. consoleDlg.find("#certificateNo").val(rowData.certificateNo);
  97. consoleDlg.find("#email").val(rowData.email);
  98. consoleDlg.find("#telNo").val(rowData.telNo);
  99. consoleDlg.find("#address").val(rowData.address);
  100. consoleDlg.find("#idCardNo").val(rowData.idCardNo);
  101. consoleDlg.find("#nationality").val(rowData.nationality);
  102. //根据新载入的数据将表格中的对应数据行一并更新一下
  103. vardataRow={
  104. id:rowData.id,
  105. lastName:rowData.lastName,
  106. firstName:rowData.firstName,
  107. email:rowData.email,
  108. telNo:rowData.telNo
  109. };
  110. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
  111. //打开对话框
  112. consoleDlg.dialog("open");
  113. }
  114. });
  115. }
  116. };
  117. varaddContact=function(){
  118. varconsoleDlg=$("#consoleDlg");
  119. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  120. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  121. varpEmail=$.trim(consoleDlg.find("#email").val());
  122. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  123. varpAddress=$.trim(consoleDlg.find("#address").val());
  124. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  125. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  126. varparams={
  127. "contact.lastName":pLastName,
  128. "contact.firstName":pFirstName,
  129. "contact.email":pEmail,
  130. "contact.telNo":pTelNo,
  131. "contact.address":pAddress,
  132. "contact.idCardNo":pIdCardNo,
  133. "contact.nationality":pNationality
  134. };
  135. varactionUrl="createContact.action"
  136. $.ajax({
  137. url:actionUrl,
  138. data:params,
  139. dataType:"json",
  140. cache:false,
  141. error:function(textStatus,errorThrown){
  142. alert("系统ajax交互错误:"+textStatus);
  143. },
  144. success:function(data,textStatus){
  145. if(data.ajaxResult=="success"){
  146. vardataRow={
  147. id:data.contact.id,//从Server端得到系统分配的id
  148. lastName:pLastName,
  149. firstName:pFirstName,
  150. email:pEmail,
  151. telNo:pTelNo
  152. };
  153. varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");
  154. if(srcrowid){
  155. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);
  156. }else{
  157. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");
  158. }
  159. consoleDlg.dialog("close");
  160. alert("联系人添加操作成功!");
  161. }else{
  162. alert("添加操作失败!");
  163. }
  164. }
  165. });
  166. };
  167. varupdateContact=function(){
  168. varconsoleDlg=$("#consoleDlg");
  169. varpId=$.trim(consoleDlg.find("#selectId").val());
  170. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  171. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  172. varpEmail=$.trim(consoleDlg.find("#email").val());
  173. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  174. varpAddress=$.trim(consoleDlg.find("#address").val());
  175. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  176. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  177. varparams={
  178. "contact.id":pId,
  179. "contact.lastName":pLastName,
  180. "contact.firstName":pFirstName,
  181. "contact.email":pEmail,
  182. "contact.telNo":pTelNo,
  183. "contact.address":pAddress,
  184. "contact.idCardNo":pIdCardNo,
  185. "contact.nationality":pNationality
  186. };
  187. varactionUrl="updateContact.action";
  188. $.ajax({
  189. url:actionUrl,
  190. data:params,
  191. dataType:"json",
  192. cache:false,
  193. error:function(textStatus,errorThrown){
  194. alert("系统ajax交互错误:"+textStatus);
  195. },
  196. success:function(data,textStatus){
  197. if(data.ajaxResult=="success"){
  198. vardataRow={
  199. id:data.contact.id,
  200. lastName:pLastName,
  201. firstName:pFirstName,
  202. email:pEmail,
  203. telNo:pTelNo
  204. };
  205. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});
  206. alert("联系人信息更新成功!");
  207. consoleDlg.dialog("close");
  208. }else{
  209. alert("修改操作失败!");
  210. }
  211. }
  212. });
  213. };
  214. vardeleteContact=function(){
  215. varconsoleDlg=$("#consoleDlg");
  216. varpId=$.trim(consoleDlg.find("#selectId").val());
  217. varparams={
  218. "contact.id":pId
  219. };
  220. varactionUrl="deleteContact.action";
  221. $.ajax({
  222. url:actionUrl,
  223. data:params,
  224. dataType:"json",
  225. cache:false,
  226. error:function(textStatus,errorThrown){
  227. alert("系统ajax交互错误:"+textStatus);
  228. },
  229. success:function(data,textStatus){
  230. if(data.ajaxResult=="success"){
  231. $("#gridTable").jqGrid("delRowData",pId);
  232. consoleDlg.dialog("close");
  233. alert("联系人删除成功!");
  234. }else{
  235. alert("删除操作失败!");
  236. }
  237. }
  238. });
  239. };

1. 初始化Grid表格:
这一部分的代码,和上一篇中的例子完全相同,不再赘述。

2. 初始化对话框:

[javascript] view plaincopyprint?
  1. $("#consoleDlg").dialog({
  2. autoOpen:false,
  3. modal:true,//(1)设置对话框为模态(modal)对话框
  4. resizable:true,
  5. width:480,
  6. buttons:{//(2)为对话框添加按钮
  7. "取消":function(){$("#consoleDlg").dialog("close")},
  8. "创建":addContact,
  9. "保存":updateContact,
  10. "删除":deleteContact
  11. }
  12. });

说明:

(1)处将modal属性设为true,即将对话框设置为“模态”,当对话框打开状态时,下层的Grid表格式不能被编辑的(注意z-Index的值);

(2)处为对话框添加了4个按钮,因为增、删、查都共用一个对话框,所以添加4个按钮是比较方便的,只要控制它们不同状态下的显隐状态就OK了。点击每个按钮都会执行各自对应的函数。

注:jQuery UI的dialog方法可以详细参考jQuery UI的文档。

3. 添加记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Adding=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");//(1)
  4. consoleDlg.find("input").removeAttr("disabled").val("");//(2)
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();//(3)
  6. dialogButtonPanel.find("button:contains('创建')").show();//(4)
  7. consoleDlg.dialog("option","title","创建新联系人").dialog("open");//(5)
  8. };

说明:
(1)处先获得对话框按钮的父元素;

(2)将所有的input元素解除disabled状态(在打开删除对话框时,会diable这些input元素);

(3)(4)处调整对话框按钮的显示隐藏状态;

(5)更新对话框标题。

4. 执行添加操作:

[javascript] view plaincopyprint?
  1. varaddContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. //(1)
  4. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  5. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  6. varpEmail=$.trim(consoleDlg.find("#email").val());
  7. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  8. varpAddress=$.trim(consoleDlg.find("#address").val());
  9. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  10. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  11. varparams={
  12. "contact.lastName":pLastName,
  13. "contact.firstName":pFirstName,
  14. "contact.email":pEmail,
  15. "contact.telNo":pTelNo,
  16. "contact.address":pAddress,
  17. "contact.idCardNo":pIdCardNo,
  18. "contact.nationality":pNationality
  19. };
  20. varactionUrl="createContact.action"
  21. $.ajax({
  22. url:actionUrl,
  23. data:params,
  24. dataType:"json",
  25. cache:false,
  26. error:function(textStatus,errorThrown){//(2)
  27. alert("系统ajax交互错误:"+textStatus);
  28. },
  29. success:function(data,textStatus){//(3)
  30. if(data.ajaxResult=="success"){//(4)
  31. vardataRow={
  32. id:data.contact.id,//(5)从Server端得到系统分配的id
  33. lastName:pLastName,
  34. firstName:pFirstName,
  35. email:pEmail,
  36. telNo:pTelNo
  37. };
  38. varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");//(6)
  39. if(srcrowid){
  40. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);//(7)
  41. }else{
  42. $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");//(8)
  43. }
  44. consoleDlg.dialog("close");
  45. alert("联系人添加操作成功!");
  46. }else{//(9)
  47. alert("添加操作失败!");
  48. }
  49. }
  50. });
  51. };

说明:

(1)从对话框的表单中读取各个输入项的值;
(2)在$.ajax()方法遇到error时,会提示错误(从而让jqGrid不再继续后面的Grid操作);
(3)如果$.ajax()成功,则执行回调函数,但是应当注意这里的“success”,是指ajax请求成功得到response,而不是Struts2 Action的“success”。当Action的result的name为“error”、“input”、“login”等的时候,只要它能够给客户端返回一个格式正确的json数据(我们这里定义了需要的是json),那么都会被认为是“success”;
(4)因此通过传回来的json数据中的ajaxResult项的值,来判断逻辑事务操作是否成功;(在正式项目中,我为不同的Action result定义了不同的ajaxResult值,以方便客户端判断,执行相应后续操作。这里为了演示简便,只定义了success一种,Action配置文件中也只定义了success结果,即使出现error或input等其他结果,Struts2也会因为找不到其他result配置,而抛出异常,也就不会向客户端发送json数据。客户端也就认为ajax请求失败了,从而执行$.ajax()中error项定义的回调方法。)
(5)如果执行成功,则根据Action配置文件的定义,json数据中会包括"contact.id":value这段数据;而jqGrid也就应该继续后续操作,更新Grid表格内的数据;
(6)获得最后选中行的行id;
(7)(8)如果最后选中行的行id不为null,则将新数据行插入到这行上面;否则将新数据加入到Grid的顶端;
(9)如果ajaxResult的值不为success,即逻辑实务操作没有成功,jqGrid不再进行后续操作,同时向用户提示操作失败。

5. 载入行数据到对话框:

当修改或者删除某行数据的时候,通常需要先打开这行记录,让用户看到并确认操作。这就需要将行数据载入到对话框中。

[javascript] view plaincopyprint?
  1. varloadSelectedRowData=function(){
  2. varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
  3. if(!selectedRowId){//(1)
  4. alert("请先选择需要编辑的行!");
  5. returnfalse;
  6. }else{
  7. varparams={
  8. "contact.id":selectedRowId
  9. };
  10. varactionUrl="viewContact.action";
  11. //从Server读取对应ID的JSON数据
  12. $.ajax({
  13. url:actionUrl,
  14. data:params,
  15. dataType:"json",
  16. cache:false,
  17. error:function(textStatus,errorThrown){
  18. alert("系统ajax交互错误:"+textStatus);
  19. },
  20. success:function(data,textStatus){
  21. //如果读取结果成功,则将信息载入到对话框中
  22. varrowData=data.contact;
  23. varconsoleDlg=$("#consoleDlg");
  24. //(2)
  25. consoleDlg.find("#selectId").val(rowData.id);
  26. consoleDlg.find("#lastName").val(rowData.lastName);
  27. consoleDlg.find("#firstName").val(rowData.firstName);
  28. consoleDlg.find("#certificateNo").val(rowData.certificateNo);
  29. consoleDlg.find("#email").val(rowData.email);
  30. consoleDlg.find("#telNo").val(rowData.telNo);
  31. consoleDlg.find("#address").val(rowData.address);
  32. consoleDlg.find("#idCardNo").val(rowData.idCardNo);
  33. consoleDlg.find("#nationality").val(rowData.nationality);
  34. //(3)根据新载入的数据将表格中的对应数据行一并更新一下
  35. vardataRow={
  36. id:rowData.id,
  37. lastName:rowData.lastName,
  38. firstName:rowData.firstName,
  39. email:rowData.email,
  40. telNo:rowData.telNo
  41. };
  42. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
  43. consoleDlg.dialog("open");//(4)
  44. }
  45. });
  46. }
  47. };

说明:

(1)如果没有行被选中,则提示用户;

(2)如果成功地从Server得到行数据,则将行数据的内容置入对话框表单中;

(3)根据新载入的数据将表格中的对应数据行一并更新一下;

(4)数据载入完毕后,打开对话框。

注:其实(3)是可选的部分,我的考虑是既然已经将最新的数据从Server取回来了,干脆就将Grid表格中的数据也更新一下。不论修改或删除操作是否被用户提交,更新一下数据总是好的,也不太费事。既然用户选择了这行数据,说明这行应该是用户关心的,有可能用户打开Grid页面一段时间了,而这行数据实际已经被其他用户更新了。当前用户通过打开对话框,也能得到最新的数据,即便没有修改或者删除,也不算无“功”而返啊。这主要也是从用户体验的角度出发。

6. 修改记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Updating=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  4. consoleDlg.find("input").removeAttr("disabled");
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  6. dialogButtonPanel.find("button:contains('保存')").show();
  7. consoleDlg.dialog("option","title","修改联系人信息");
  8. loadSelectedRowData();//(1)
  9. }

说明:
前几行的代码与添加记录是打开对话框时的过程相似,不再赘述;(1)处即在打开对话框之前,将对应行数据载入对话框。

7. 执行修改操作:

[javascript] view plaincopyprint?
  1. varupdateContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. varpId=$.trim(consoleDlg.find("#selectId").val());
  4. varpLastName=$.trim(consoleDlg.find("#lastName").val());
  5. varpFirstName=$.trim(consoleDlg.find("#firstName").val());
  6. varpEmail=$.trim(consoleDlg.find("#email").val());
  7. varpTelNo=$.trim(consoleDlg.find("#telNo").val());
  8. varpAddress=$.trim(consoleDlg.find("#address").val());
  9. varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
  10. varpNationality=$.trim(consoleDlg.find("#nationality").val());
  11. varparams={
  12. "contact.id":pId,
  13. "contact.lastName":pLastName,
  14. "contact.firstName":pFirstName,
  15. "contact.email":pEmail,
  16. "contact.telNo":pTelNo,
  17. "contact.address":pAddress,
  18. "contact.idCardNo":pIdCardNo,
  19. "contact.nationality":pNationality
  20. };
  21. varactionUrl="updateContact.action";
  22. $.ajax({
  23. url:actionUrl,
  24. data:params,
  25. dataType:"json",
  26. cache:false,
  27. error:function(textStatus,errorThrown){
  28. alert("系统ajax交互错误:"+textStatus);
  29. },
  30. success:function(data,textStatus){
  31. if(data.ajaxResult=="success"){
  32. vardataRow={
  33. id:data.contact.id,
  34. lastName:pLastName,
  35. firstName:pFirstName,
  36. email:pEmail,
  37. telNo:pTelNo
  38. };
  39. $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});//(1)
  40. alert("联系人信息更新成功!");
  41. consoleDlg.dialog("close");
  42. }else{
  43. alert("修改操作失败!");
  44. }
  45. }
  46. });
  47. };

说明:参考执行添加操作的说明,这段应该很好理解。(1)处更新Grid中对应行的数据,并添加CSS样式。

8. 删除记录时打开对话框:

[javascript] view plaincopyprint?
  1. varopenDialog4Deleting=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
  4. consoleDlg.find("input").attr("disabled",true);//(1)
  5. dialogButtonPanel.find("button:not(:contains('取消'))").hide();
  6. dialogButtonPanel.find("button:contains('删除')").show();
  7. consoleDlg.dialog("option","title","删除联系人");
  8. loadSelectedRowData();
  9. }

说明:(1)处将所有input全部disable掉,使之不能输入内容。

9. 执行删除操作:

[javascript] view plaincopyprint?
  1. vardeleteContact=function(){
  2. varconsoleDlg=$("#consoleDlg");
  3. varpId=$.trim(consoleDlg.find("#selectId").val());
  4. varparams={
  5. "contact.id":pId
  6. };
  7. varactionUrl="deleteContact.action";
  8. $.ajax({
  9. url:actionUrl,
  10. data:params,
  11. dataType:"json",
  12. cache:false,
  13. error:function(textStatus,errorThrown){
  14. alert("系统ajax交互错误:"+textStatus);
  15. },
  16. success:function(data,textStatus){
  17. if(data.ajaxResult=="success"){
  18. $("#gridTable").jqGrid("delRowData",pId);
  19. consoleDlg.dialog("close");
  20. alert("联系人删除成功!");
  21. }else{
  22. alert("删除操作失败!");
  23. }
  24. }
  25. });
  26. };




以上就是实际应用中,使用自定义表单对话框编辑Grid数据的过程。下一篇说一下排序与搜索。


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics