- 浏览: 71983 次
-
文章分类
最新评论
jqGrid与Struts2的结合应用(三) —— 使用自定义表单对话框编辑Grid数据
上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗?
这一篇就来说说服务器端的操作。
首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。
- packagecn.gengv.struts2ex.jqGrid;
- importjava.util.List;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.model.PatentCase;
- importcom.byzl.hare.service.ContactService;
- importcom.opensymphony.xwork2.ActionSupport;
- @SuppressWarnings("serial")
- publicclassViewContactActionextendsActionSupport{
- privateContactcontact;
- privateList<PatentCase>patentCases;
- privateContactServicecontactService;
- privateStringajaxResult;
- publicStringviewContact(){
- intid=contact.getId();
- contact=contactService.queryById(contact.getId());
- if(contact==null){
- ajaxResult="未能找到ID为"+id+"的联系人";
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- publicContactgetContact(){
- returncontact;
- }
- publicvoidsetContact(Contactcontact){
- this.contact=contact;
- }
- publicStringgetAjaxResult(){
- returnajaxResult;
- }
- publicvoidsetAjaxResult(StringajaxResult){
- this.ajaxResult=ajaxResult;
- }
- publicvoidsetContactService(ContactServicecontactService){
- this.contactService=contactService;
- }
- publicList<PatentCase>getPatentCases(){
- returnpatentCases;
- }
- publicvoidsetPatentCases(List<PatentCase>patentCases){
- this.patentCases=patentCases;
- }
- }
- packagecn.gengv.struts2ex.jqGrid;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.service.ContactService;
- importcom.opensymphony.xwork2.ActionSupport;
- @SuppressWarnings("serial")
- publicclassContactConsoleActionextendsActionSupport{
- privateContactServicecontactService;
- privateContactcontact;
- privateStringajaxResult;
- //创建新的Contact
- publicStringcreateContact(){
- try{
- contact.setId(this.contactService.addNew(contact));
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="创建新联系人失败!"+e.getMessage();
- returnERROR;
- }
- }
- //更新Contact信息
- publicStringupdateContact(){
- try{
- this.contactService.update(contact);
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="更新联系人信息失败!"+e.getMessage();
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- //删除Contact
- publicStringdeleteContact(){
- try{
- this.contactService.delete(contact);
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="删除联系人失败!"+e.getMessage();
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- publicContactgetContact(){
- returncontact;
- }
- publicvoidsetContact(Contactcontact){
- this.contact=contact;
- }
- publicStringgetAjaxResult(){
- returnajaxResult;
- }
- publicvoidsetAjaxResult(StringajaxResult){
- this.ajaxResult=ajaxResult;
- }
- publicvoidsetContactService(ContactServicecontactService){
- this.contactService=contactService;
- }
- }
说明:
- 因为客户端会和Server进行ajax交互,所以我在类里面加入了一个成员变量ajaxResult,用来保存操作实际的结果。当action产生json类型的result时,这个成员变量也会被串行化进json结果中,发送到客户端。客户端的javascript代码会解析这个值,以执行相应操作。
- 这两个类都是用了Object-backed Action的方式来传递数据(关于Object-backed Action可以参考《Struts2 in Action》一书的3.4节)。
在配置文件中,按如下配置Action:
- <actionname="viewContact"
- class="cn.gengv.struts2ex.jqGrid.ViewContactAction"method="viewContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact.*,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- <paramname="excludeNullProperties">true</param>
- </result>
- </action>
- <actionname="createContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="createContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
- <actionname="updateContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="updateContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
- <actionname="deleteContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="deleteContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
说明:
- 请注意result的类型为json,而且includeProperties属性中包括ajaxResult这个成员变量名;
- 由于添加contact时,id属性值是由后台自动生成的,因此需要将这个值传回客户端作为Grid的行id值。
服务器端的代码似乎没有什么更多需要说明的地方了,应该一目了然。
下面看看客户端部分,这里面似乎有不少值得说明一下的部分。
首先看一下html的完整代码:
- <!DOCTYPEhtml
- PUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="zh-CN"lang="zh-CN">
- <head>
- <title>jqGrid03</title>
- <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"/>
- <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/ui.jqgrid.custom.css"mce_href="css/themes/aero/ui.jqgrid.custom.css"/>
- <linkhref="../css/genericFormTable.css"mce_href="css/genericFormTable.css"rel="stylesheet"type="text/css"/>
- <mce:scripttype="text/javascript"src="../js/jquery-1.4.2.min.js"mce_src="js/jquery-1.4.2.min.js"></mce:script>
- <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>
- <mce:scriptsrc="../js/i18n/grid.locale-zh-CN.js"mce_src="js/i18n/grid.locale-zh-CN.js"type="text/javascript"></mce:script>
- <mce:scriptsrc="../js/jquery.jqGrid.min.js"mce_src="js/jquery.jqGrid.min.js"type="text/javascript"></mce:script>
- <mce:scriptsrc="js/jqGrid03.js"mce_src="js/jqGrid03.js"type="text/javascript"></mce:script>
- </head>
- <body>
- <h3>
- jqGrid测试03
- </h3>
- <div>
- <tableid="gridTable"></table>
- <divid="gridPager"></div>
- </div>
- <br/>
- <div>
- <buttononclick="openDialog4Adding()">添加联系人</button>
- <buttononclick="openDialog4Updating()">修改联系人</button>
- <buttononclick="openDialog4Deleting()">删除联系人</button>
- </div>
- <divid="consoleDlg">
- <divid="formContainer">
- <formid="consoleForm">
- <inputtype="hidden"id="selectId"/>
- <tableclass="formTable">
- <tr>
- <th>姓:</th>
- <td>
- <inputtype="text"class="textField"id="lastName"name="lastName"/>
- </td>
- </tr>
- <tr>
- <th>名:</th>
- <td>
- <inputtype="text"class="textField"id="firstName"name="firstName"/>
- </td>
- </tr>
- <tr>
- <th>国籍:</th>
- <td>
- <inputtype="text"class="textField"id="nationality"name="nationality"/>
- </td>
- </tr>
- <tr>
- <th>身份证号:</th>
- <td>
- <inputtype="text"class="textField"id="idCardNo"name="idCardNo"/>
- </td>
- </tr>
- <tr>
- <th>电子邮箱:</th>
- <td>
- <inputtype="text"class="textField"id="email"name="email"/>
- </td>
- </tr>
- <tr>
- <th>电话:</th>
- <td>
- <inputtype="text"class="textField"id="telNo"name="telNo"/>
- </td>
- </tr>
- <tr>
- <th>地址:</th>
- <td>
- <inputtype="text"class="textField"id="address"name="address"/>
- </td>
- </tr>
- </table>
- </form>
- </div>
- </div>
- </body>
- </html>
相比较之前的例子,这个例子最重要的变化是添加了一个id为consoleDlg的<div>块。在javascript的页面初始化部分我将使用jQuery UI的API将这个div生成为一个模态对话框,用作编辑数据的界面。
虽然jqGrid也提供了表单格式的编辑数据的界面,但是我个人感觉那个界面太基础,适用于简单的数据编辑情况,对于复杂的情况,可能还是自己写点代码更加灵活。
另一个项目中,我自己实现的相对复杂的表单界面:
回到本例中,上面的“对话框”div中,有一个form,其中有一个<input type="hidden" id="selectId"/>(当准备修改或者删除一行记录的时候,这行的id将被保存在这里,以备后用),以及若干个<input type="text">。
再来看看javascript部分,javascript部分主要功能分成几块:
- 初始化表格;
- 初始化对话框;
- 添加记录时打开对话框;
- 执行添加操作;
- 载入行数据到对话框;
- 修改记录时打开对话框;
- 执行修改操作;
- 删除记录时打开对话框;
- 执行删除操作。
先看一下完整代码,然后逐块分析:
- $(function(){
- //配置jqGrid组件
- $("#gridTable").jqGrid({
- url:"jqGrid03.action",
- datatype:"json",
- mtype:"GET",
- height:350,
- width:600,
- colModel:[
- {name:"id",index:"id",label:"编码",width:40},
- {name:"lastName",index:"lastName",label:"姓",width:80,sortable:false},
- {name:"firstName",index:"firstName",label:"名",width:80,sortable:false},
- {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
- {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
- ],
- viewrecords:true,
- rowNum:15,
- rowList:[15,50,100],
- prmNames:{search:"search"},
- jsonReader:{
- root:"gridModel",
- records:"record",
- repeatitems:false
- },
- pager:"#gridPager",
- caption:"联系人列表",
- hidegrid:false,
- shrikToFit:true
- });
- //配置对话框
- $("#consoleDlg").dialog({
- autoOpen:false,
- modal:true,//设置对话框为模态(modal)对话框
- resizable:true,
- width:480,
- buttons:{//为对话框添加按钮
- "取消":function(){$("#consoleDlg").dialog("close")},
- "创建":addContact,
- "保存":updateContact,
- "删除":deleteContact
- }
- });
- });
- varopenDialog4Adding=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled").val("");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('创建')").show();
- consoleDlg.dialog("option","title","创建新联系人").dialog("open");
- };
- varopenDialog4Updating=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('保存')").show();
- consoleDlg.dialog("option","title","修改联系人信息");
- loadSelectedRowData();
- }
- varopenDialog4Deleting=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").attr("disabled",true);
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('删除')").show();
- consoleDlg.dialog("option","title","删除联系人");
- loadSelectedRowData();
- }
- varloadSelectedRowData=function(){
- varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
- if(!selectedRowId){
- alert("请先选择需要编辑的行!");
- returnfalse;
- }else{
- varparams={
- "contact.id":selectedRowId
- };
- varactionUrl="viewContact.action";
- //从Server读取对应ID的JSON数据
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- //如果读取结果成功,则将信息载入到对话框中
- varrowData=data.contact;
- varconsoleDlg=$("#consoleDlg");
- consoleDlg.find("#selectId").val(rowData.id);
- consoleDlg.find("#lastName").val(rowData.lastName);
- consoleDlg.find("#firstName").val(rowData.firstName);
- consoleDlg.find("#certificateNo").val(rowData.certificateNo);
- consoleDlg.find("#email").val(rowData.email);
- consoleDlg.find("#telNo").val(rowData.telNo);
- consoleDlg.find("#address").val(rowData.address);
- consoleDlg.find("#idCardNo").val(rowData.idCardNo);
- consoleDlg.find("#nationality").val(rowData.nationality);
- //根据新载入的数据将表格中的对应数据行一并更新一下
- vardataRow={
- id:rowData.id,
- lastName:rowData.lastName,
- firstName:rowData.firstName,
- email:rowData.email,
- telNo:rowData.telNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
- //打开对话框
- consoleDlg.dialog("open");
- }
- });
- }
- };
- varaddContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="createContact.action"
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,//从Server端得到系统分配的id
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");
- if(srcrowid){
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);
- }else{
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");
- }
- consoleDlg.dialog("close");
- alert("联系人添加操作成功!");
- }else{
- alert("添加操作失败!");
- }
- }
- });
- };
- varupdateContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.id":pId,
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="updateContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});
- alert("联系人信息更新成功!");
- consoleDlg.dialog("close");
- }else{
- alert("修改操作失败!");
- }
- }
- });
- };
- vardeleteContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varparams={
- "contact.id":pId
- };
- varactionUrl="deleteContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- $("#gridTable").jqGrid("delRowData",pId);
- consoleDlg.dialog("close");
- alert("联系人删除成功!");
- }else{
- alert("删除操作失败!");
- }
- }
- });
- };
1. 初始化Grid表格:
这一部分的代码,和上一篇中的例子完全相同,不再赘述。
2. 初始化对话框:
- $("#consoleDlg").dialog({
- autoOpen:false,
- modal:true,//(1)设置对话框为模态(modal)对话框
- resizable:true,
- width:480,
- buttons:{//(2)为对话框添加按钮
- "取消":function(){$("#consoleDlg").dialog("close")},
- "创建":addContact,
- "保存":updateContact,
- "删除":deleteContact
- }
- });
说明:
(1)处将modal属性设为true,即将对话框设置为“模态”,当对话框打开状态时,下层的Grid表格式不能被编辑的(注意z-Index的值);
(2)处为对话框添加了4个按钮,因为增、删、查都共用一个对话框,所以添加4个按钮是比较方便的,只要控制它们不同状态下的显隐状态就OK了。点击每个按钮都会执行各自对应的函数。
注:jQuery UI的dialog方法可以详细参考jQuery UI的文档。
3. 添加记录时打开对话框:
- varopenDialog4Adding=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");//(1)
- consoleDlg.find("input").removeAttr("disabled").val("");//(2)
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();//(3)
- dialogButtonPanel.find("button:contains('创建')").show();//(4)
- consoleDlg.dialog("option","title","创建新联系人").dialog("open");//(5)
- };
说明:
(1)处先获得对话框按钮的父元素;
(2)将所有的input元素解除disabled状态(在打开删除对话框时,会diable这些input元素);
(3)(4)处调整对话框按钮的显示隐藏状态;
(5)更新对话框标题。
4. 执行添加操作:
- varaddContact=function(){
- varconsoleDlg=$("#consoleDlg");
- //(1)
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="createContact.action"
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){//(2)
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){//(3)
- if(data.ajaxResult=="success"){//(4)
- vardataRow={
- id:data.contact.id,//(5)从Server端得到系统分配的id
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");//(6)
- if(srcrowid){
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);//(7)
- }else{
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");//(8)
- }
- consoleDlg.dialog("close");
- alert("联系人添加操作成功!");
- }else{//(9)
- alert("添加操作失败!");
- }
- }
- });
- };
说明:
(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. 载入行数据到对话框:
当修改或者删除某行数据的时候,通常需要先打开这行记录,让用户看到并确认操作。这就需要将行数据载入到对话框中。
- varloadSelectedRowData=function(){
- varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
- if(!selectedRowId){//(1)
- alert("请先选择需要编辑的行!");
- returnfalse;
- }else{
- varparams={
- "contact.id":selectedRowId
- };
- varactionUrl="viewContact.action";
- //从Server读取对应ID的JSON数据
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- //如果读取结果成功,则将信息载入到对话框中
- varrowData=data.contact;
- varconsoleDlg=$("#consoleDlg");
- //(2)
- consoleDlg.find("#selectId").val(rowData.id);
- consoleDlg.find("#lastName").val(rowData.lastName);
- consoleDlg.find("#firstName").val(rowData.firstName);
- consoleDlg.find("#certificateNo").val(rowData.certificateNo);
- consoleDlg.find("#email").val(rowData.email);
- consoleDlg.find("#telNo").val(rowData.telNo);
- consoleDlg.find("#address").val(rowData.address);
- consoleDlg.find("#idCardNo").val(rowData.idCardNo);
- consoleDlg.find("#nationality").val(rowData.nationality);
- //(3)根据新载入的数据将表格中的对应数据行一并更新一下
- vardataRow={
- id:rowData.id,
- lastName:rowData.lastName,
- firstName:rowData.firstName,
- email:rowData.email,
- telNo:rowData.telNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
- consoleDlg.dialog("open");//(4)
- }
- });
- }
- };
说明:
(1)如果没有行被选中,则提示用户;
(2)如果成功地从Server得到行数据,则将行数据的内容置入对话框表单中;
(3)根据新载入的数据将表格中的对应数据行一并更新一下;
(4)数据载入完毕后,打开对话框。
注:其实(3)是可选的部分,我的考虑是既然已经将最新的数据从Server取回来了,干脆就将Grid表格中的数据也更新一下。不论修改或删除操作是否被用户提交,更新一下数据总是好的,也不太费事。既然用户选择了这行数据,说明这行应该是用户关心的,有可能用户打开Grid页面一段时间了,而这行数据实际已经被其他用户更新了。当前用户通过打开对话框,也能得到最新的数据,即便没有修改或者删除,也不算无“功”而返啊。这主要也是从用户体验的角度出发。
6. 修改记录时打开对话框:
- varopenDialog4Updating=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('保存')").show();
- consoleDlg.dialog("option","title","修改联系人信息");
- loadSelectedRowData();//(1)
- }
说明:
前几行的代码与添加记录是打开对话框时的过程相似,不再赘述;(1)处即在打开对话框之前,将对应行数据载入对话框。
7. 执行修改操作:
- varupdateContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.id":pId,
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="updateContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});//(1)
- alert("联系人信息更新成功!");
- consoleDlg.dialog("close");
- }else{
- alert("修改操作失败!");
- }
- }
- });
- };
说明:参考执行添加操作的说明,这段应该很好理解。(1)处更新Grid中对应行的数据,并添加CSS样式。
8. 删除记录时打开对话框:
- varopenDialog4Deleting=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").attr("disabled",true);//(1)
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('删除')").show();
- consoleDlg.dialog("option","title","删除联系人");
- loadSelectedRowData();
- }
说明:(1)处将所有input全部disable掉,使之不能输入内容。
9. 执行删除操作:
- vardeleteContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varparams={
- "contact.id":pId
- };
- varactionUrl="deleteContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- $("#gridTable").jqGrid("delRowData",pId);
- consoleDlg.dialog("close");
- alert("联系人删除成功!");
- }else{
- alert("删除操作失败!");
- }
- }
- });
- };
以上就是实际应用中,使用自定义表单对话框编辑Grid数据的过程。下一篇说一下排序与搜索。
上一篇中的最后一点提到了,如果在服务器端出现异常,没能完成预期的操作,那么客户端(浏览器)中的jqGrid还继续更新数据吗?
这一篇就来说说服务器端的操作。
首先看一下服务器端的代码,我将查看行数据和操作行数据放在了两个Action类里面:ViewContactAction和ContactConsoleAction。
- packagecn.gengv.struts2ex.jqGrid;
- importjava.util.List;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.model.PatentCase;
- importcom.byzl.hare.service.ContactService;
- importcom.opensymphony.xwork2.ActionSupport;
- @SuppressWarnings("serial")
- publicclassViewContactActionextendsActionSupport{
- privateContactcontact;
- privateList<PatentCase>patentCases;
- privateContactServicecontactService;
- privateStringajaxResult;
- publicStringviewContact(){
- intid=contact.getId();
- contact=contactService.queryById(contact.getId());
- if(contact==null){
- ajaxResult="未能找到ID为"+id+"的联系人";
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- publicContactgetContact(){
- returncontact;
- }
- publicvoidsetContact(Contactcontact){
- this.contact=contact;
- }
- publicStringgetAjaxResult(){
- returnajaxResult;
- }
- publicvoidsetAjaxResult(StringajaxResult){
- this.ajaxResult=ajaxResult;
- }
- publicvoidsetContactService(ContactServicecontactService){
- this.contactService=contactService;
- }
- publicList<PatentCase>getPatentCases(){
- returnpatentCases;
- }
- publicvoidsetPatentCases(List<PatentCase>patentCases){
- this.patentCases=patentCases;
- }
- }
- packagecn.gengv.struts2ex.jqGrid;
- importcom.byzl.hare.model.Contact;
- importcom.byzl.hare.service.ContactService;
- importcom.opensymphony.xwork2.ActionSupport;
- @SuppressWarnings("serial")
- publicclassContactConsoleActionextendsActionSupport{
- privateContactServicecontactService;
- privateContactcontact;
- privateStringajaxResult;
- //创建新的Contact
- publicStringcreateContact(){
- try{
- contact.setId(this.contactService.addNew(contact));
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="创建新联系人失败!"+e.getMessage();
- returnERROR;
- }
- }
- //更新Contact信息
- publicStringupdateContact(){
- try{
- this.contactService.update(contact);
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="更新联系人信息失败!"+e.getMessage();
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- //删除Contact
- publicStringdeleteContact(){
- try{
- this.contactService.delete(contact);
- }catch(Exceptione){
- e.printStackTrace();
- this.addActionError(e.getMessage());
- ajaxResult="删除联系人失败!"+e.getMessage();
- returnERROR;
- }
- ajaxResult=SUCCESS;
- returnSUCCESS;
- }
- publicContactgetContact(){
- returncontact;
- }
- publicvoidsetContact(Contactcontact){
- this.contact=contact;
- }
- publicStringgetAjaxResult(){
- returnajaxResult;
- }
- publicvoidsetAjaxResult(StringajaxResult){
- this.ajaxResult=ajaxResult;
- }
- publicvoidsetContactService(ContactServicecontactService){
- this.contactService=contactService;
- }
- }
说明:
- 因为客户端会和Server进行ajax交互,所以我在类里面加入了一个成员变量ajaxResult,用来保存操作实际的结果。当action产生json类型的result时,这个成员变量也会被串行化进json结果中,发送到客户端。客户端的javascript代码会解析这个值,以执行相应操作。
- 这两个类都是用了Object-backed Action的方式来传递数据(关于Object-backed Action可以参考《Struts2 in Action》一书的3.4节)。
在配置文件中,按如下配置Action:
- <actionname="viewContact"
- class="cn.gengv.struts2ex.jqGrid.ViewContactAction"method="viewContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact.*,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- <paramname="excludeNullProperties">true</param>
- </result>
- </action>
- <actionname="createContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="createContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
- <actionname="updateContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="updateContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
- <actionname="deleteContact"
- class="cn.gengv.struts2ex.jqGrid.ContactConsoleAction"method="deleteContact">
- <resultname="success"type="json">
- <paramname="includeProperties">
- contact/.id,ajaxResult
- </param>
- <paramname="noCache">true</param>
- <paramname="ignoreHierarchy">false</param>
- </result>
- </action>
说明:
- 请注意result的类型为json,而且includeProperties属性中包括ajaxResult这个成员变量名;
- 由于添加contact时,id属性值是由后台自动生成的,因此需要将这个值传回客户端作为Grid的行id值。
服务器端的代码似乎没有什么更多需要说明的地方了,应该一目了然。
下面看看客户端部分,这里面似乎有不少值得说明一下的部分。
首先看一下html的完整代码:
- <!DOCTYPEhtml
- PUBLIC"-//W3C//DTDXHTML1.0Transitional//EN"
- "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
- <htmlxmlns="http://www.w3.org/1999/xhtml"xml:lang="zh-CN"lang="zh-CN">
- <head>
- <title>jqGrid03</title>
- <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"/>
- <linkrel="stylesheet"type="text/css"media="screen"href="../css/themes/aero/ui.jqgrid.custom.css"mce_href="css/themes/aero/ui.jqgrid.custom.css"/>
- <linkhref="../css/genericFormTable.css"mce_href="css/genericFormTable.css"rel="stylesheet"type="text/css"/>
- <mce:scripttype="text/javascript"src="../js/jquery-1.4.2.min.js"mce_src="js/jquery-1.4.2.min.js"></mce:script>
- <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>
- <mce:scriptsrc="../js/i18n/grid.locale-zh-CN.js"mce_src="js/i18n/grid.locale-zh-CN.js"type="text/javascript"></mce:script>
- <mce:scriptsrc="../js/jquery.jqGrid.min.js"mce_src="js/jquery.jqGrid.min.js"type="text/javascript"></mce:script>
- <mce:scriptsrc="js/jqGrid03.js"mce_src="js/jqGrid03.js"type="text/javascript"></mce:script>
- </head>
- <body>
- <h3>
- jqGrid测试03
- </h3>
- <div>
- <tableid="gridTable"></table>
- <divid="gridPager"></div>
- </div>
- <br/>
- <div>
- <buttononclick="openDialog4Adding()">添加联系人</button>
- <buttononclick="openDialog4Updating()">修改联系人</button>
- <buttononclick="openDialog4Deleting()">删除联系人</button>
- </div>
- <divid="consoleDlg">
- <divid="formContainer">
- <formid="consoleForm">
- <inputtype="hidden"id="selectId"/>
- <tableclass="formTable">
- <tr>
- <th>姓:</th>
- <td>
- <inputtype="text"class="textField"id="lastName"name="lastName"/>
- </td>
- </tr>
- <tr>
- <th>名:</th>
- <td>
- <inputtype="text"class="textField"id="firstName"name="firstName"/>
- </td>
- </tr>
- <tr>
- <th>国籍:</th>
- <td>
- <inputtype="text"class="textField"id="nationality"name="nationality"/>
- </td>
- </tr>
- <tr>
- <th>身份证号:</th>
- <td>
- <inputtype="text"class="textField"id="idCardNo"name="idCardNo"/>
- </td>
- </tr>
- <tr>
- <th>电子邮箱:</th>
- <td>
- <inputtype="text"class="textField"id="email"name="email"/>
- </td>
- </tr>
- <tr>
- <th>电话:</th>
- <td>
- <inputtype="text"class="textField"id="telNo"name="telNo"/>
- </td>
- </tr>
- <tr>
- <th>地址:</th>
- <td>
- <inputtype="text"class="textField"id="address"name="address"/>
- </td>
- </tr>
- </table>
- </form>
- </div>
- </div>
- </body>
- </html>
相比较之前的例子,这个例子最重要的变化是添加了一个id为consoleDlg的<div>块。在javascript的页面初始化部分我将使用jQuery UI的API将这个div生成为一个模态对话框,用作编辑数据的界面。
虽然jqGrid也提供了表单格式的编辑数据的界面,但是我个人感觉那个界面太基础,适用于简单的数据编辑情况,对于复杂的情况,可能还是自己写点代码更加灵活。
另一个项目中,我自己实现的相对复杂的表单界面:
回到本例中,上面的“对话框”div中,有一个form,其中有一个<input type="hidden" id="selectId"/>(当准备修改或者删除一行记录的时候,这行的id将被保存在这里,以备后用),以及若干个<input type="text">。
再来看看javascript部分,javascript部分主要功能分成几块:
- 初始化表格;
- 初始化对话框;
- 添加记录时打开对话框;
- 执行添加操作;
- 载入行数据到对话框;
- 修改记录时打开对话框;
- 执行修改操作;
- 删除记录时打开对话框;
- 执行删除操作。
先看一下完整代码,然后逐块分析:
- $(function(){
- //配置jqGrid组件
- $("#gridTable").jqGrid({
- url:"jqGrid03.action",
- datatype:"json",
- mtype:"GET",
- height:350,
- width:600,
- colModel:[
- {name:"id",index:"id",label:"编码",width:40},
- {name:"lastName",index:"lastName",label:"姓",width:80,sortable:false},
- {name:"firstName",index:"firstName",label:"名",width:80,sortable:false},
- {name:"email",index:"email",label:"电子邮箱",width:160,sortable:false},
- {name:"telNo",index:"telNo",label:"电话",width:120,sortable:false}
- ],
- viewrecords:true,
- rowNum:15,
- rowList:[15,50,100],
- prmNames:{search:"search"},
- jsonReader:{
- root:"gridModel",
- records:"record",
- repeatitems:false
- },
- pager:"#gridPager",
- caption:"联系人列表",
- hidegrid:false,
- shrikToFit:true
- });
- //配置对话框
- $("#consoleDlg").dialog({
- autoOpen:false,
- modal:true,//设置对话框为模态(modal)对话框
- resizable:true,
- width:480,
- buttons:{//为对话框添加按钮
- "取消":function(){$("#consoleDlg").dialog("close")},
- "创建":addContact,
- "保存":updateContact,
- "删除":deleteContact
- }
- });
- });
- varopenDialog4Adding=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled").val("");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('创建')").show();
- consoleDlg.dialog("option","title","创建新联系人").dialog("open");
- };
- varopenDialog4Updating=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('保存')").show();
- consoleDlg.dialog("option","title","修改联系人信息");
- loadSelectedRowData();
- }
- varopenDialog4Deleting=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").attr("disabled",true);
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('删除')").show();
- consoleDlg.dialog("option","title","删除联系人");
- loadSelectedRowData();
- }
- varloadSelectedRowData=function(){
- varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
- if(!selectedRowId){
- alert("请先选择需要编辑的行!");
- returnfalse;
- }else{
- varparams={
- "contact.id":selectedRowId
- };
- varactionUrl="viewContact.action";
- //从Server读取对应ID的JSON数据
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- //如果读取结果成功,则将信息载入到对话框中
- varrowData=data.contact;
- varconsoleDlg=$("#consoleDlg");
- consoleDlg.find("#selectId").val(rowData.id);
- consoleDlg.find("#lastName").val(rowData.lastName);
- consoleDlg.find("#firstName").val(rowData.firstName);
- consoleDlg.find("#certificateNo").val(rowData.certificateNo);
- consoleDlg.find("#email").val(rowData.email);
- consoleDlg.find("#telNo").val(rowData.telNo);
- consoleDlg.find("#address").val(rowData.address);
- consoleDlg.find("#idCardNo").val(rowData.idCardNo);
- consoleDlg.find("#nationality").val(rowData.nationality);
- //根据新载入的数据将表格中的对应数据行一并更新一下
- vardataRow={
- id:rowData.id,
- lastName:rowData.lastName,
- firstName:rowData.firstName,
- email:rowData.email,
- telNo:rowData.telNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
- //打开对话框
- consoleDlg.dialog("open");
- }
- });
- }
- };
- varaddContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="createContact.action"
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,//从Server端得到系统分配的id
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");
- if(srcrowid){
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);
- }else{
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");
- }
- consoleDlg.dialog("close");
- alert("联系人添加操作成功!");
- }else{
- alert("添加操作失败!");
- }
- }
- });
- };
- varupdateContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.id":pId,
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="updateContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});
- alert("联系人信息更新成功!");
- consoleDlg.dialog("close");
- }else{
- alert("修改操作失败!");
- }
- }
- });
- };
- vardeleteContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varparams={
- "contact.id":pId
- };
- varactionUrl="deleteContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- $("#gridTable").jqGrid("delRowData",pId);
- consoleDlg.dialog("close");
- alert("联系人删除成功!");
- }else{
- alert("删除操作失败!");
- }
- }
- });
- };
1. 初始化Grid表格:
这一部分的代码,和上一篇中的例子完全相同,不再赘述。
2. 初始化对话框:
- $("#consoleDlg").dialog({
- autoOpen:false,
- modal:true,//(1)设置对话框为模态(modal)对话框
- resizable:true,
- width:480,
- buttons:{//(2)为对话框添加按钮
- "取消":function(){$("#consoleDlg").dialog("close")},
- "创建":addContact,
- "保存":updateContact,
- "删除":deleteContact
- }
- });
说明:
(1)处将modal属性设为true,即将对话框设置为“模态”,当对话框打开状态时,下层的Grid表格式不能被编辑的(注意z-Index的值);
(2)处为对话框添加了4个按钮,因为增、删、查都共用一个对话框,所以添加4个按钮是比较方便的,只要控制它们不同状态下的显隐状态就OK了。点击每个按钮都会执行各自对应的函数。
注:jQuery UI的dialog方法可以详细参考jQuery UI的文档。
3. 添加记录时打开对话框:
- varopenDialog4Adding=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");//(1)
- consoleDlg.find("input").removeAttr("disabled").val("");//(2)
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();//(3)
- dialogButtonPanel.find("button:contains('创建')").show();//(4)
- consoleDlg.dialog("option","title","创建新联系人").dialog("open");//(5)
- };
说明:
(1)处先获得对话框按钮的父元素;
(2)将所有的input元素解除disabled状态(在打开删除对话框时,会diable这些input元素);
(3)(4)处调整对话框按钮的显示隐藏状态;
(5)更新对话框标题。
4. 执行添加操作:
- varaddContact=function(){
- varconsoleDlg=$("#consoleDlg");
- //(1)
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="createContact.action"
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){//(2)
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){//(3)
- if(data.ajaxResult=="success"){//(4)
- vardataRow={
- id:data.contact.id,//(5)从Server端得到系统分配的id
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- varsrcrowid=$("#gridTable").jqGrid("getGridParam","selrow");//(6)
- if(srcrowid){
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"before",srcrowid);//(7)
- }else{
- $("#gridTable").jqGrid("addRowData",data.contact.id,dataRow,"first");//(8)
- }
- consoleDlg.dialog("close");
- alert("联系人添加操作成功!");
- }else{//(9)
- alert("添加操作失败!");
- }
- }
- });
- };
说明:
(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. 载入行数据到对话框:
当修改或者删除某行数据的时候,通常需要先打开这行记录,让用户看到并确认操作。这就需要将行数据载入到对话框中。
- varloadSelectedRowData=function(){
- varselectedRowId=$("#gridTable").jqGrid("getGridParam","selrow");
- if(!selectedRowId){//(1)
- alert("请先选择需要编辑的行!");
- returnfalse;
- }else{
- varparams={
- "contact.id":selectedRowId
- };
- varactionUrl="viewContact.action";
- //从Server读取对应ID的JSON数据
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- //如果读取结果成功,则将信息载入到对话框中
- varrowData=data.contact;
- varconsoleDlg=$("#consoleDlg");
- //(2)
- consoleDlg.find("#selectId").val(rowData.id);
- consoleDlg.find("#lastName").val(rowData.lastName);
- consoleDlg.find("#firstName").val(rowData.firstName);
- consoleDlg.find("#certificateNo").val(rowData.certificateNo);
- consoleDlg.find("#email").val(rowData.email);
- consoleDlg.find("#telNo").val(rowData.telNo);
- consoleDlg.find("#address").val(rowData.address);
- consoleDlg.find("#idCardNo").val(rowData.idCardNo);
- consoleDlg.find("#nationality").val(rowData.nationality);
- //(3)根据新载入的数据将表格中的对应数据行一并更新一下
- vardataRow={
- id:rowData.id,
- lastName:rowData.lastName,
- firstName:rowData.firstName,
- email:rowData.email,
- telNo:rowData.telNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow);
- consoleDlg.dialog("open");//(4)
- }
- });
- }
- };
说明:
(1)如果没有行被选中,则提示用户;
(2)如果成功地从Server得到行数据,则将行数据的内容置入对话框表单中;
(3)根据新载入的数据将表格中的对应数据行一并更新一下;
(4)数据载入完毕后,打开对话框。
注:其实(3)是可选的部分,我的考虑是既然已经将最新的数据从Server取回来了,干脆就将Grid表格中的数据也更新一下。不论修改或删除操作是否被用户提交,更新一下数据总是好的,也不太费事。既然用户选择了这行数据,说明这行应该是用户关心的,有可能用户打开Grid页面一段时间了,而这行数据实际已经被其他用户更新了。当前用户通过打开对话框,也能得到最新的数据,即便没有修改或者删除,也不算无“功”而返啊。这主要也是从用户体验的角度出发。
6. 修改记录时打开对话框:
- varopenDialog4Updating=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").removeAttr("disabled");
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('保存')").show();
- consoleDlg.dialog("option","title","修改联系人信息");
- loadSelectedRowData();//(1)
- }
说明:
前几行的代码与添加记录是打开对话框时的过程相似,不再赘述;(1)处即在打开对话框之前,将对应行数据载入对话框。
7. 执行修改操作:
- varupdateContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varpLastName=$.trim(consoleDlg.find("#lastName").val());
- varpFirstName=$.trim(consoleDlg.find("#firstName").val());
- varpEmail=$.trim(consoleDlg.find("#email").val());
- varpTelNo=$.trim(consoleDlg.find("#telNo").val());
- varpAddress=$.trim(consoleDlg.find("#address").val());
- varpIdCardNo=$.trim(consoleDlg.find("#idCardNo").val());
- varpNationality=$.trim(consoleDlg.find("#nationality").val());
- varparams={
- "contact.id":pId,
- "contact.lastName":pLastName,
- "contact.firstName":pFirstName,
- "contact.email":pEmail,
- "contact.telNo":pTelNo,
- "contact.address":pAddress,
- "contact.idCardNo":pIdCardNo,
- "contact.nationality":pNationality
- };
- varactionUrl="updateContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- vardataRow={
- id:data.contact.id,
- lastName:pLastName,
- firstName:pFirstName,
- email:pEmail,
- telNo:pTelNo
- };
- $("#gridTable").jqGrid("setRowData",data.contact.id,dataRow,{color:"#FF0000"});//(1)
- alert("联系人信息更新成功!");
- consoleDlg.dialog("close");
- }else{
- alert("修改操作失败!");
- }
- }
- });
- };
说明:参考执行添加操作的说明,这段应该很好理解。(1)处更新Grid中对应行的数据,并添加CSS样式。
8. 删除记录时打开对话框:
- varopenDialog4Deleting=function(){
- varconsoleDlg=$("#consoleDlg");
- vardialogButtonPanel=consoleDlg.siblings(".ui-dialog-buttonpane");
- consoleDlg.find("input").attr("disabled",true);//(1)
- dialogButtonPanel.find("button:not(:contains('取消'))").hide();
- dialogButtonPanel.find("button:contains('删除')").show();
- consoleDlg.dialog("option","title","删除联系人");
- loadSelectedRowData();
- }
说明:(1)处将所有input全部disable掉,使之不能输入内容。
9. 执行删除操作:
- vardeleteContact=function(){
- varconsoleDlg=$("#consoleDlg");
- varpId=$.trim(consoleDlg.find("#selectId").val());
- varparams={
- "contact.id":pId
- };
- varactionUrl="deleteContact.action";
- $.ajax({
- url:actionUrl,
- data:params,
- dataType:"json",
- cache:false,
- error:function(textStatus,errorThrown){
- alert("系统ajax交互错误:"+textStatus);
- },
- success:function(data,textStatus){
- if(data.ajaxResult=="success"){
- $("#gridTable").jqGrid("delRowData",pId);
- consoleDlg.dialog("close");
- alert("联系人删除成功!");
- }else{
- alert("删除操作失败!");
- }
- }
- });
- };
以上就是实际应用中,使用自定义表单对话框编辑Grid数据的过程。下一篇说一下排序与搜索。
相关推荐
5. **自定义对话框**:在描述中提到的"使用自定义表单对话框编辑Grid数据",指的是使用jQuery UI或其他工具创建一个弹出窗口,展示一个表单供用户编辑选定行的数据。在提交表单时,jqGrid会通过AJAX调用Struts2 ...
**三、jqGrid与Struts2结合应用** jqGrid与Struts2的结合使用可以实现数据的后台动态加载和前端的交互操作。具体步骤如下: 1. **配置Struts2 Action**:创建一个Action类,负责处理请求并返回数据。例如,可以创建...
Delphi 12.3控件之TraeSetup-stable-1.0.12120.exe
基于GPRS,GPS的电动汽车远程监控系统的设计与实现.pdf
内容概要:本文详细介绍了如何利用MATLAB/Simulink 2018a进行单机无穷大系统的暂态稳定性仿真。主要内容包括搭建同步发电机模型、设置无穷大系统等效电源、配置故障模块及其控制信号、优化求解器设置以及绘制和分析转速波形和摇摆曲线。文中还提供了多个实用脚本,如故障类型切换、摇摆曲线计算和极限切除角的求解方法。此外,作者分享了一些实践经验,如避免常见错误和提高仿真效率的小技巧。 适合人群:从事电力系统研究和仿真的工程师和技术人员,尤其是对MATLAB/Simulink有一定基础的用户。 使用场景及目标:适用于需要进行电力系统暂态稳定性分析的研究项目或工程应用。主要目标是帮助用户掌握单机无穷大系统的建模和仿真方法,理解故障对系统稳定性的影响,并能够通过仿真结果评估系统的性能。 其他说明:文中提到的一些具体操作和脚本代码对于初学者来说可能会有一定的难度,建议结合官方文档或其他教程一起学习。同时,部分技巧和经验来自于作者的实际操作,具有一定的实用性。
KUKA机器人相关资料
基于DLR模型的PM10–能见度–湿度相关性 研究.pdf
内容概要:本文详细介绍了如何使用MATLAB/Simulink进行光伏并网系统的最大功率点跟踪(MPPT)仿真,重点讨论了电导增量法的应用。首先阐述了电导增量法的基本原理,接着展示了如何在Simulink中构建光伏电池模型和MPPT控制系统,包括Boost升压电路的设计和PI控制参数的设定。随后,通过仿真分析了不同光照强度和温度条件对光伏系统性能的影响,验证了电导增量法的有效性,并提出了针对特定工况的优化措施。 适合人群:从事光伏系统研究和技术开发的专业人士,尤其是那些希望通过仿真工具深入理解MPPT控制机制的人群。 使用场景及目标:适用于需要评估和优化光伏并网系统性能的研发项目,旨在提高系统在各种环境条件下的最大功率点跟踪效率。 其他说明:文中提供了详细的代码片段和仿真结果图表,帮助读者更好地理解和复现实验过程。此外,还提到了一些常见的仿真陷阱及解决方案,如变步长求解器的问题和PI参数整定技巧。
KUKA机器人相关文档
内容概要:本文详细探讨了双馈风力发电机(DFIG)在Simulink环境下的建模方法及其在不同风速条件下的电流与电压波形特征。首先介绍了DFIG的基本原理,即定子直接接入电网,转子通过双向变流器连接电网的特点。接着阐述了Simulink模型的具体搭建步骤,包括风力机模型、传动系统模型、DFIG本体模型和变流器模型的建立。文中强调了变流器控制算法的重要性,特别是在应对风速变化时,通过实时调整转子侧的电压和电流,确保电流和电压波形的良好特性。此外,文章还讨论了模型中的关键技术和挑战,如转子电流环控制策略、低电压穿越性能、直流母线电压脉动等问题,并提供了具体的解决方案和技术细节。最终,通过对故障工况的仿真测试,验证了所建模型的有效性和优越性。 适用人群:从事风力发电研究的技术人员、高校相关专业师生、对电力电子控制系统感兴趣的工程技术人员。 使用场景及目标:适用于希望深入了解DFIG工作原理、掌握Simulink建模技能的研究人员;旨在帮助读者理解DFIG在不同风速条件下的动态响应机制,为优化风力发电系统的控制策略提供理论依据和技术支持。 其他说明:文章不仅提供了详细的理论解释,还附有大量Matlab/Simulink代码片段,便于读者进行实践操作。同时,针对一些常见问题给出了实用的调试技巧,有助于提高仿真的准确性和可靠性。
linux之用户管理教程.md
内容概要:本文详细介绍了利用三菱PLC(特别是FX系列)和组态王软件构建3x3书架式堆垛式立体库的方法。首先阐述了IO分配的原则,明确了输入输出信号的功能,如仓位检测、堆垛机运动控制等。接着深入解析了梯形图编程的具体实现,包括基本的左右移动控制、复杂的自动寻址逻辑,以及确保安全性的限位保护措施。还展示了接线图和原理图的作用,强调了正确的电气连接方式。最后讲解了组态王的画面设计技巧,通过图形化界面实现对立体库的操作和监控。 适用人群:从事自动化仓储系统设计、安装、调试的技术人员,尤其是熟悉三菱PLC和组态王的工程师。 使用场景及目标:适用于需要提高仓库空间利用率的小型仓储环境,旨在帮助技术人员掌握从硬件选型、电路设计到软件编程的全流程技能,最终实现高效稳定的自动化仓储管理。 其他说明:文中提供了多个实用的编程技巧和注意事项,如避免常见错误、优化性能参数等,有助于减少实际应用中的故障率并提升系统的可靠性。
基于STM32的循迹避障小车 主控:STM32 显示:OLED 电源模块 舵机云台 超声波测距 红外循迹模块(3个,左中右) 蓝牙模块 按键(6个,模式和手动控制小车状态) TB6612驱动的双电机 功能: 该小车共有3种模式: 自动模式:根据红外循迹和超声波测距模块决定小车的状态 手动模式:根据按键的状态来决定小车的状态 蓝牙模式:根据蓝牙指令来决定小车的状态 自动模式: 自动模式下,检测距离低于5cm小车后退 未检测到任何黑线,小车停止 检测到左边或左边+中间黑线,小车左转 检测到右边或右边+中间黑线,小车右转 检测到中边或左边+中间+右边黑线,小车前进 手动模式:根据按键的状态来决定小车的状态 蓝牙模式: //需切换为蓝牙模式才能指令控制 *StatusX X取值为0-4 0:小车停止 1:小车前进 2:小车后退 3:小车左转 4:小车右转
矢量边界,行政区域边界,精确到乡镇街道,可直接导入arcgis使用
内容概要:本文探讨了基于IEEE33节点的主动配电网优化方法,旨在通过合理的调度模型降低配电网的总运行成本。文中详细介绍了模型的构建,包括风光发电、储能装置、柴油发电机和燃气轮机等多种分布式电源的集成。为了实现这一目标,作者提出了具体的约束条件,如储能充放电功率限制和潮流约束,并采用了粒子群算法进行求解。通过一系列实验验证,最终得到了优化的分布式电源运行计划,显著降低了总成本并提高了系统的稳定性。 适合人群:从事电力系统优化、智能电网研究的专业人士和技术爱好者。 使用场景及目标:适用于需要优化配电网运行成本的研究机构和企业。主要目标是在满足各种约束条件下,通过合理的调度策略使配电网更加经济高效地运行。 其他说明:文章不仅提供了详细的理论推导和算法实现,还分享了许多实用的经验技巧,如储能充放电策略、粒子群算法参数选择等。此外,通过具体案例展示了不同电源之间的协同作用及其经济效益。
KUKA机器人相关文档
内容概要:本文详细介绍了将光热电站(CSP)和有机朗肯循环(ORC)集成到综合能源系统中的优化建模方法。主要内容涵盖系统的目标函数设计、关键设备的约束条件(如CSP储热罐、ORC热电耦合)、以及具体实现的技术细节。文中通过MATLAB和YALMIP工具进行建模,采用CPLEX求解器解决混合整数规划问题,确保系统在经济性和环境效益方面的最优表现。此外,文章还讨论了碳排放惩罚机制、风光弃能处理等实际应用场景中的挑战及其解决方案。 适合人群:从事综合能源系统研究的专业人士,尤其是对光热发电、余热利用感兴趣的科研工作者和技术开发者。 使用场景及目标:适用于需要评估和优化包含多种能源形式(如光伏、风电、燃气锅炉等)在内的复杂能源系统的项目。目标是在满足供电供热需求的同时,最小化运行成本并减少碳排放。 其他说明:文中提供了大量具体的MATLAB代码片段作为实例,帮助读者更好地理解和复现所提出的优化模型。对于初学者而言,建议从简单的确定性模型入手,逐渐过渡到更复杂的随机规划和鲁棒优化。
网站设计与管理作业一.ppt
内容概要:本文详细介绍了如何使用MATLAB搭建双闭环Buck电路的仿真模型。首先定义了主电路的关键参数,如输入电压、电感、电容等,并解释了这些参数的选择依据。接着分别对电压外环和电流内环进行了PI控制器的设计,强调了电流环响应速度需要显著高于电压环以确保系统的稳定性。文中还讨论了仿真过程中的一些关键技术细节,如PWM死区时间的设置、低通滤波器的应用以及参数调整的方法。通过对比单闭环和双闭环系统的性能,展示了双闭环方案在应对负载突变时的优势。最后分享了一些调试经验和常见问题的解决方案。 适合人群:从事电力电子、电源设计领域的工程师和技术人员,尤其是有一定MATLAB基础的读者。 使用场景及目标:适用于需要进行电源管理芯片设计验证、电源系统性能评估的研究人员和工程师。主要目标是提高电源系统的稳定性和响应速度,特别是在负载变化剧烈的情况下。 其他说明:文章不仅提供了详细的理论分析,还包括了大量的代码片段和具体的调试步骤,帮助读者更好地理解和应用所学知识。同时提醒读者注意仿真与实际情况之间的差异,鼓励在实践中不断探索和改进。
内容概要:本文详细探讨了MATLAB环境下冷热电气多能互补微能源网的鲁棒优化调度模型。首先介绍了多能耦合元件(如风电、光伏、P2G、燃气轮机等)的运行特性模型,展示了如何通过MATLAB代码模拟这些元件的实际运行情况。接着阐述了电、热、冷、气四者的稳态能流模型及其相互关系,特别是热电联产过程中能流的转换和流动。然后重点讨论了考虑经济成本和碳排放最优的优化调度模型,利用MATLAB优化工具箱求解多目标优化问题,确保各能源设备在合理范围内运行并保持能流平衡。最后分享了一些实际应用中的经验和技巧,如处理风光出力预测误差、非线性约束、多能流耦合等。 适合人群:从事能源系统研究、优化调度、MATLAB编程的专业人士和技术爱好者。 使用场景及目标:适用于希望深入了解综合能源系统优化调度的研究人员和工程师。目标是掌握如何在MATLAB中构建和求解复杂的多能互补优化调度模型,提高能源利用效率,降低碳排放。 其他说明:文中提供了大量MATLAB代码片段,帮助读者更好地理解和实践所介绍的内容。此外,还提及了一些有趣的发现和挑战,如多能流耦合的复杂性、鲁棒优化的应用等。