dojo DataGrid实现表格数据编辑的解决方案 - 博闻强记

时间:2024-03-04 18:25:39

dojo DataGrid实现表格数据编辑的解决方案

在官网上看见的DataGrid编辑非常简单,但我实现的时候总是出现问题。经过N久的摸索,终于搞定了,期间出现了多处困难,下面说些解决办法的流程。

 

我实现的表格在页面加载时是不显示数据,只有通过表单像服务器提交查询数据后才刷新表格。

首先新建DataGrid:

                gridLayout =[{    
                        defaultCell: {  editable: true, type: cells._Widget, styles: \'text-align: center;\'  },                         
                        cells: [ 
                                    { name: "WBS", field: "wbs", width: "60px"},
                                    /*  { name: "ID", field: "configId", width: "240px",editable:false},  */
                                    { name:"系统/设备/部件",field:"equipName",width:"120px"},
                                    { name: "配置项名称", field: "configName", width: "100px" },
                                    { name: "位置名称", field: "locationName", width: "80px" },
                                    { name: "设备所属部门", field: "deptName", width: "120px" },
                                    { name: "状态", field: "status", width: "40px" },
                                    { name: "删除", field: "inc_number", width:"60px",formatter: getDeleteButton },
                                    { name: "保存", field: "saveButton", width:"60px",formatter: getSaveButton },
                                    { name: "详细", field:"updateLink", width:"60px",formatter:getUpdateLink}
                                ]
                        }];                        

                    grid = new DataGrid({                        
                        structure: gridLayout,                        
                        "class": "grid",
                        escapeHTMLInData: false,
                        noDataMessage: "没有配置数据"                
                     }, "gridDiv"
                    );    
                    grid.startup();

然后为提交按钮添加事件处理程序,向服务器端发送请求

                    //查询按钮的点击事件处理程序
                    var queryButton=dom.byId("queryButton");
                    on(queryButton, "click",
                        function(evt){                        
                        equipName = dom.byId("equipName").value;
                         wbsId = dom.byId("wbsId").value;
                         populateDataGrid(equipName,wbsId);                        
                    });
                    
                    //通过设备名和wbs向服务器段查询数据后填充grid表格
                    function populateDataGrid(equipName,wbsId)
                    {
                        if((equipName=="")&&(wbsId==""))
                            return;
                        request.get("configurationMaintainingQueryAction.action?configurationMaintaining.equipName="+equipName+"&configurationMaintaining.wbsId="+wbsId,{handleAs : "json"})
                               .then(function(data) 
                                     {
                                        store = new Memory({data : data , idProperty: "configId" });
                                        dataStore = new ObjectStore({objectStore : store});
                                        grid.store = dataStore;
                                        grid._refresh();
                                     });
                    }

显示数据没问题的,但是就是不能编辑。网上查到的资料也少。感觉用DOJO的远没有JQUERY的多,至少查中文资料是这样的。

后来发现是在DataGrid新建时,必须有store属性才能EDIT。但是我在页面初始加载时,并不希望表格显示数据,所以给DataGrid设置一个空的ObjectStore就可以,修改新建表格代码:

                    store=new Memory();
                    dataStore=new ObjectStore({objectStore : store});
                    grid = new DataGrid({                        
                        structure: gridLayout,        
                        store:dataStore,
                        "class": "grid",
                        escapeHTMLInData: false,
                        noDataMessage: "没有配置数据"                
                     }, "gridDiv"
                    );    
                    grid.startup(); 

 

 

这步完成了,表格就可以编辑了。但是发现和官网上的例子不同的时,此时表格的数据编辑之后在客户端就无法保存,会出现空白的显示情况。

解决办法是实现编辑完成的事件处理程序:

                    var configIds=new Array();
                    
                    grid.on("ApplyEdit",function(rowIndex)
                                        {                                            
                                            grid.update();                    
                                            var rowdata = grid.getItem(rowIndex);
                                            var configId = rowdata["configId"];
                                            for(i=0;i<configIds.length;i++)
                                            {
                                                if(configIds[i].rowIndex==rowIndex)
                                                    return;                                                
                                            }
                                            configIds.push({rowIndex:rowIndex,configId:configId});                                            
                                        });

添加grid.update()既可以解决问题,同时可以在这里获取表格编辑数据准备下一步向服务器端发送。

到这里在客户端网页已经能够实现表格数据的编辑了,和官网的例子一样。

 

下一步实现真正的服务器端数据修改,这里的思路是收集所有编辑过的单元行数据,然后一起POST到服务器端。代码如下:

                    function getSaveButton(col, rowIndex) {
                        var new_button = new dijit.form.Button(
                                {
                                    label : \'保存\',
                                    showLabel : false,
                                    iconClass : "dijitEditorIcon dijitEditorIconSave",
                                    \'class\' : \'gridButton\',
                                    onClick : saveClick
                                });

                        function saveClick(evt) {//删除按钮的删除事件处理程序                            
                            
                            if (confirm("确定保存修改?"))
                            {    
                                                            
                                
                                 evt.stopPropagation();
                                evt.preventDefault(); 
                                
                                var configurationMaintainings=[];
                                for(i=0;i<configIds.length;i++)
                                {
                                    var rowdata = grid.getItem(configIds[i].rowIndex);
                                    
                                    var temp=new Object();                                    
                                    temp.configId=rowdata["configId"];
                                    temp.wbs=rowdata["wbs"];
                                    temp.equipName=rowdata["equipName"];
                                    temp.configName=rowdata["configName"];
                                    temp.locationName=rowdata["locationName"];
                                    temp.deptName=rowdata["deptName"];                                    
                                    
                                    configurationMaintainings.push(temp);        
                                }                                                    
                                                                
                                request.post("configurationMaintainingAction.action?mode=update",{data : jsonString});//先服务器提交删除参数        
                            
                                populateDataGrid(equipName,wbsId);//刷新DataGrid
                                configIds=new Array();//清空
                            }
                        }
                        new_button._destroyOnRemove = true;
                        return new_button;
                    }

但是这是发现在服务器端无法接受到request的数据。后来在CHROME调试中发现在Network面板中观察到提交的数据是[[object Object],[object Object],[object Object]]这样的形式。也没有太在意(实际上是不懂)。

网上说数据也弄成JSON就可以了,我一直以为自己提交的就是JSON,总以为是服务器端的事情。后来看了别人的例子才知道在JS中必须要做这样的转换,还好DOJO提供了JSON类,加一句代码就可以。将request.post语句修改如下:

                                var jsonString = JSON.stringify(configurationMaintainings);                                
                                request.post("configurationMaintainingAction.action?mode=update",{data : jsonString});//先服务器提交删除参数    

顺便说一句,CHROME真心好用。

然后在服务器端接受就可以,这里用了谷歌的GSON包。非常简单,部分代码如下:

            cms.clear();
            ActionContext ac=ActionContext.getContext();
            Map<String, Object> map=ac.getParameters();
            String jsonStr="";            
            
            for(Map.Entry<String, Object> entry:map.entrySet()){    
                 System.out.println(entry.getKey()+"--->"+entry.getValue());
                 jsonStr=entry.getKey();
                 break;
            }   
            
            //创建一个Gson对象
            Gson gson = new Gson();    
            //创建一个JsonParser
            JsonParser parser = new JsonParser();
            //通过JsonParser对象可以把json格式的字符串解析成一个JsonElement对象
            JsonElement el = parser.parse(jsonStr);
            //把JsonElement对象转换成JsonObject
            JsonObject jsonObj = null;
            if(el.isJsonObject()){
                jsonObj = el.getAsJsonObject();  
            }

            //把JsonElement对象转换成JsonArray
            JsonArray jsonArray = null;
            if(el.isJsonArray()){
                jsonArray = el.getAsJsonArray();
            }

            ConfigurationMaintaining cm=new ConfigurationMaintaining();
            Iterator it = jsonArray.iterator();
            while(it.hasNext()){
                JsonElement e = (JsonElement)it.next();
                //JsonElement转换为JavaBean对象
                cm=gson.fromJson(e, ConfigurationMaintaining.class);
                cms.add(cm);            
            }
            
            configurationMaintaining.update(cms);

到这里工作基本完了,但是运行后又发现一个问题

即表格编辑后,去点击保存按钮,最后一个编辑的cell,系统不是默认为ApplyEdit状态,所以该单元格数据不会被修改。

本来想在saveButton的事件处理程序中,添加grid的update方法,但是也不起作用。

后来发现,当saveButton的事件处理程序调用完了,依然会除非该单元格的ApplyCellEdit。所以只要在这个事件中加点代码就可以,为了避免每一次ApplyCellEdit事件都触发代码,设置一个isSaveButtonClicked布尔量,在saveButton中打开,在ApplyCellEdit中判断并关闭。代码如下:

    grid.on("ApplyCellEdit",function(cell,rowIndex)
                                            {
                                                 if(isSaveButtonClicked==true)
                                                 {
                                                     
                                                     var rowdata=grid.getItem(rowIndex);
                                                     var configurationMaintainings=[];
                                                    var temp=new Object();                                    
                                                    temp.configId=rowdata["configId"];
                                                    temp.wbs=rowdata["wbs"];
                                                    temp.equipName=rowdata["equipName"];
                                                    temp.configName=rowdata["configName"];
                                                    temp.locationName=rowdata["locationName"];
                                                    temp.deptName=rowdata["deptName"];                                                    
                                                    configurationMaintainings.push(temp);
                                                    var jsonString = JSON.stringify(configurationMaintainings);
                                                    request.post("configurationMaintainingAction.action?mode=update",{data : jsonString});//先服务器提交删除参数
                                                    
                                                    
                                                    configIds=new Array();//清空
                                                    isSaveButtonClicked=false;
                                                    grid.update();
                                                    populateDataGrid(equipName,wbsId);//刷新DataGrid
                                                    alert("配置修改项成功!");
                                                 }
                                                     
                                            });  

到这里问题完全解决。

 

JSP页面完整代码:

<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@ taglib prefix="s" uri="/struts-tags" %>

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN">
<html>
  <head>          
    <title>My JSP \'configurationMaintaining.jsp\' starting page</title>    
    <meta http-equiv="pragma" content="no-cache">
    <meta http-equiv="cache-control" content="no-cache">
    <meta http-equiv="expires" content="0">    
    <meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
    <meta http-equiv="description" content="This is my page">    
    
    <link rel="stylesheet" href="/lss/css/lssCss.css" />
    <link rel="stylesheet" href="/lss/dojoroot/dijit/themes/claro/claro.css" />
    <link rel="stylesheet" href="/lss/dojoroot/dojox/grid/resources/Grid.css" />    
    <link rel="stylesheet" href="/lss/dojoroot/dojox/grid/resources/claroGrid.css" />    
    
    <script src="/lss/dojoroot/dojo/dojo.js" ></script>

    <script>    
        var equipName,wbsId;
        var grid, dataStore, store;
        require(["dojox/grid/DataGrid", 
                 "dojox/grid/cells",
                 "dojox/grid/cells/dijit",
                 "dojo/dom", 
                 "dojo/on", 
                 "dojo/request", 
                 "dojo/store/Memory",
                 "dojo/data/ObjectStore",  
                 "dojo/json",
                 "dijit/form/Button",                         
                 "dojo/domReady!"],
                 function(DataGrid,cells,cellsDijit,dom,on,request,Memory,ObjectStore,JSON){                    
                    gridLayout =[{    
                        defaultCell: {  editable: true, type: cells._Widget, styles: \'text-align: center;\'  },                         
                        cells: [ 
                                    { name: "WBS", field: "wbs", width: "60px"},                                    
                                    { name:"系统/设备/部件",field:"equipName",width:"120px"},
                                    { name: "配置项名称", field: "configName", width: "100px" },
                                    { name: "位置名称", field: "locationName", width: "80px" },
                                    { name: "设备所属部门", field: "deptName", width: "120px" },
                                    { name: "状态", field: "status", width: "40px" },
                                    { name: "删除",editable:false,field: "deleteButton", width:"60px",formatter: getDeleteButton },
                                    { name: "保存", editable:false,field: "saveButton", width:"60px",formatter: getSaveButton },
                                    { name: "详细",editable:false, field:"updateLink", width:"60px",formatter:getUpdateLink}
                                ]
                        }];    
                    
                    store=new Memory();
                    dataStore=new ObjectStore({objectStore : store});
                    grid = new DataGrid({                        
                        structure: gridLayout,        
                        store:dataStore,
                        "class": "grid",
                        escapeHTMLInData: false,
                        noDataMessage: "没有配置数据"                
                     }, "gridDiv"
                    );    
                    grid.startup();             
                    
                    //查询按钮的点击事件处理程序
                    var queryButton=dom.byId("queryButton");
                    on(queryButton, "click",
                        function(evt){                        
                        equipName = dom.byId("equipName").value;
                         wbsId = dom.byId("wbsId").value;
                         populateDataGrid(equipName,wbsId);                        
                    });
                    
                    //通过设备名和wbs向服务器段查询数据后填充grid表格
                    function populateDataGrid(equipName,wbsId)
                    {
                        if((equipName=="")&&(wbsId==""))
                            return;
                        request.get("configurationMaintainingQueryAction.action?configurationMaintaining.equipName="+equipName+"&configurationMaintaining.wbsId="+wbsId,{handleAs : "json"})
                               .then(function(data) 
                                     {
                                        store = new Memory({data : data , idProperty: "configId" });
                                        dataStore = new ObjectStore({objectStore : store});
                                        grid.store = dataStore;
                                        grid._refresh();
                                     });
                    }    
                    
                    //获得DataGrid表格的更新按钮
                    function getUpdateLink(col, rowIndex){
                        var rowdata=grid.getItem(rowIndex);
                        var configId=rowdata["configId"];
                        return ("<a href=configurationInputAction.action?mode=detail&configurationInput.configId="+configId+">详细 </a>");
                    }

                    //获得DataGrid表格的删除按钮
                    function getDeleteButton(col, rowIndex) {
                        var new_button = new dijit.form.Button(
                                {
                                    label : \'删除\',
                                    showLabel : false,
                                    iconClass : "dijitEditorIcon dijitEditorIconRemoveFormat",
                                    \'class\' : \'gridButton\',
                                    onClick : deleteClick
                                });

                        function deleteClick(evt) {//删除按钮的删除事件处理程序
                            if (confirm("确定删除该配置项吗?")) {
                                var rowdata = grid.getItem(rowIndex);
                                var configId = rowdata["configId"];
                            /*     evt.stopPropagation();
                                evt.preventDefault(); */                                
                                request.get("configurationMaintainingAction.action?mode=delete&configurationMaintaining.configId="+configId);//先服务器提交删除参数
                                populateDataGrid(equipName,wbsId);//刷新DataGrid
                                alert("删除配置项成功!");
                            }
                        }
                        new_button._destroyOnRemove = true;
                        return new_button;
                    }                        
                    
                    var configIds=new Array();//存放编辑过的数据行id
                    var isSaveButtonClicked=false;//保存按钮是否点击过
                    
                    //编辑完成事件处理
                    grid.on("ApplyEdit",function(rowIndex)
                                        {                                            
                                            grid.update();                    
                                            var rowdata = grid.getItem(rowIndex);
                                            var configId = rowdata["configId"];
                                            for(i=0;i<configIds.length;i++)
                                            {
                                                if(configIds[i].rowIndex==rowIndex)
                                                    return;                                                
                                            }
                                            configIds.push({rowIndex:rowIndex,configId:configId});                                            
                                        });
                     
                    //单元格编辑完成事件处理,在保存按钮后的事件处理程序跑完后会触发该事件
                    grid.on("ApplyCellEdit",function(cell,rowIndex)
                                            {
                                                 if(isSaveButtonClicked==true)
                                                 {                                                     
                                                     var rowdata=grid.getItem(rowIndex);
                                                     var configurationMaintainings=[];
                                                    var temp=new Object();                                    
                                                    temp.configId=rowdata["configId"];
                                                    temp.wbs=rowdata["wbs"];
                                                    temp.equipName=rowdata["equipName"];
                                                    temp.configName=rowdata["configName"];
                                                    temp.locationName=rowdata["locationName"];
                                                    temp.deptName=rowdata["deptName"];                                                    
                                                    configurationMaintainings.push(temp);
                                                    var jsonString = JSON.stringify(configurationMaintainings);
                                                    request.post("configurationMaintainingAction.action?mode=update",{data : jsonString});//先服务器提交删除参数
                                                    
                                                    
                                                    configIds=new Array();//清空
                                                    isSaveButtonClicked=false;
                                                    grid.update();
                                                    populateDataGrid(equipName,wbsId);//刷新DataGrid
                                                    alert("配置修改项成功!");
                                                 }                                                     
                                            });                  
                    
                    
                    //获得DataGrid表格的保存按钮
                    function getSaveButton(col, rowIndex) {
                        var new_button = new dijit.form.Button(
                                {
                                    label : \'保存\',
                                    showLabel : false,
                                    iconClass : "dijitEditorIcon dijitEditorIconSave",
                                    \'class\' : \'gridButton\',
                                    onClick : saveClick
                                });

                        function saveClick(evt) {//删除按钮的删除事件处理程序                                    
                            if (confirm("确定保存修改?"))
                            {    
                                isSaveButtonClicked=true;    
                                 evt.stopPropagation();
                                evt.preventDefault(); 
                                var configurationMaintainings=[];
                                for(i=0;i<configIds.length;i++)
                                {
                                    var rowdata = grid.getItem(configIds[i].rowIndex);
                                    var temp=new Object();                                    
                                    temp.configId=rowdata["configId"];
                                    temp.wbs=rowdata["wbs"];
                                    temp.equipName=rowdata["equipName"];
                                    temp.configName=rowdata["configName"];
                                    temp.locationName=rowdata["locationName"];
                                    temp.deptName=rowdata["deptName"];        
                                    configurationMaintainings.push(temp);        
                                }    
                                
                                var jsonString = JSON.stringify(configurationMaintainings);                                
                                request.post("configurationMaintainingAction.action?mode=update",{data : jsonString});//先服务器提交删除参数    
                                populateDataGrid(equipName,wbsId);//刷新DataGrid
                                configIds=new Array();//清空
                            }
                        }
                        new_button._destroyOnRemove = true;
                        return new_button;
                    }    
                    
                });
    </script>

  </head>
  
  <body bgcolor="#bae87c" class="claro">     
      <br />
    <table width="800px" align="center">
        <tr><td>    
                <!-- <form id="formNode"> -->
                <fieldset >
                    <legend><font color="red"><b>查询</b></font></legend>  
                    <table  width="100%">
                        <tr><td align="right">系统/设备/部件 </td><td align="left"><input type="text" name="configurationMaintaining.equipName" id="equipName"/></td>
                            <td align="right">WBS</td><td align="left"><table class="selectTable"><s:select list="configurationMaintaining.wbses" listValue="wbs" listKey="wbsId" name="configurationMaintaining.wbsId" id="wbsId"/></table></td>
                        </tr>
                        <tr><td colspan="3"></td><td align="center"><input type="button" id="queryButton" value="查询"></td></tr>
                    </table>                    
                </fieldset>
            <!-- </form> -->
            <br />            
            <form>
                <fieldset >
                    <legend><font color="red"><b>配置信息</b></font></legend>                     
                     <div id="gridDiv" style="width:100%;height: 200px;" >
                    </div>                    
                </fieldset>
            </form>  
        </td></tr>
    </table>         
      
  </body>
</html>