• jQuery网格插件 jqGrid


    jqGrid 是一个用来显示网格数据的jQuery插件,文档比较全面,附带中文版本。

    jqGrid

    下载地址:http://www.trirand.com/blog/?page_id=6

    下载之后修改自己写的jsp文件中的引用语句

    <script src="../js/i18n/grid.locale-en.js" type="text/javascript"></script>
    修改为
    <script src="../js/i18n/grid.locale-cn.js" type="text/javascript"></script>

    再打开运行tomcat来看,果然变成中文的了。哈哈!爽!

    不过有一点需要注意,如果你是狂热爱好者,在jsp中直接引用src目录下的原始包(这样可以调试jqGrid的源代码),那么除了上面我们说的jsp文件中需要修改之外,还有一个js文件需要修改,那就是:src/grid.loader.js中

    var modules = [ { include: true, incfile:'i18n/grid.locale-en.js'}, // jqGrid translation
    需要修改为
    var modules = [ { include: true, incfile:'i18n/grid.locale-cn.js'}, // jqGrid translation

    这样就好了!

    使用jqGrid修改数据

    jqGrid可以有三种方式,让我们来修改显示在jqGrid中的数据。这三种方式分别是:

    Cell Editing——只允许修改某一个单元格内容.
    Inline Editing——允许在jqGrid中直接修改某一行的数据
    Form Editing——弹出一个新的编辑窗口进行编辑和新增

    暂时先不管这三种方式,我们来看看如何让一个jqGrid的数据能够进行编辑呢?
    其实很简单,就是在jqGrid的colModel属性中,设置几个属性:
    editable
        可选值是true或者false,默认是false。用来说明这个列的数据是否可编辑。特别要注意的是,jqGrid的隐藏字段就算设置了这个属性为true,一样不能被编辑。在Cell Editing以及Inline Editing模式下,只能通过把这些字段设置为可见来修改。在Form Editing模式下,可以通过editoptions参数来设置是否可以修改隐藏列。
    edittype
        可选的值是'text', 'textarea', 'select', 'checkbox', 'password', 'button', 'image', 'file'以及'custom'。默认值是text。
        根据名字就可以看出来,这个属性是设置编辑框的HTML样式的。比如,设置为text值,并且可以在editoptions中设置size以及maxlength等属性。这样生成的HTML样式有点类似<input type="text" size="10" maxlength="15"/>这样。
        其中有几个要注意:
        设置checkbox的时候,需要在editoptions中指定value值,第一个值应该是checked的时候的值。比如editoptions:{value:"Yes:No"}会设定这个checkbox编辑框,选中的时候,值是Yes,没选中的时候值是No。建议最好都设定一下这个值。
        设置select的时候,editoptions中需要设定select下拉框的值。
            一种方式是用字符串设置editoptions的value属性,像这样editoption: { value: “FE:FedEx; IN:InTime; TN:TNT” },这就为下拉框设置了三个可选值。注意,冒号前面的代表的是值,冒号后面代表的是显示值。
            第二种方式是用对象来设置editoptions的value属性,这个时候,value值要用{}包括起来,像这样: editoptions:{value:{1:'One',2:'Two'}}。
            第三种方式,是为editoptions设置dataUrl参数。意思就是select的值,是通过一个URL来获取的,比如一个Ajax请求的返回值。特别需要注意的是,在这种情况下,URL的返回值必须是包括select以及option这些HTML标签的。就像这样:<select><option value="1">One</option><option value="2">Two</option></select>.这种情况下,还可以在editoptions中设置是否允许多选,size等等。
        设置image的时候,editoptions的src属性用来指定图片的地址。
        custom类型就是通过一个函数来指定需要编辑的元素,并返回需要提交的值。
            函数的定义在editoptions中说明,分别是custom_element用来指定哪一个函数用来创建编辑框,注意这里函数必须返回一个新的DOM元素,函数的参数一个是值Value,另外一个是colModel的editoptions值。
            另外一个是custom_value,这个函数用来在编辑完成之后返回本编辑框的值,这个函数的参数是元素对象。大概的调用格式如下:
            <script>
                //创建一个input输入框
                function myelem (value, options) {
                  var el = document.createElement("input");
                  el.type="text";
                  el.value = value;
                  return el;
                }
                
                //获取值
                function myvalue(elem) {
                  return $(elem).val();
                }
                jQuery("#grid_id").jqGrid({
                ...
                   colModel: [
                      ...
                      {name:'price', ..., editable:true, edittype:'custom', editoptions:{custom_element: myelem, custom_value:myvalue} },
                      ...
                   ]
                ...
                });
            </script>

    editoptions
        除了上面介绍的editoptions选项外,我们还可以设置defaultValue等等,更复杂的东西,比如dataEvents就不介绍了。
    editrules
        editrules是用来设置一些可用于可编辑列的colModel的额外属性的。大多数的时候是用来在提交到服务器之前验证用户的输入合法性的。比如editrules:{edithidden:true, required:true....}。
        可选的属性包括:
        edithidden:只在Form Editing模式下有效,设置为true,就可以让隐藏字段也可以修改。
        required:设置编辑的时候是否可以为空(是否是必须的)。
        number:设置为true,如果输入值不是数字或者为空,则会报错。
        integer:
        minValue:
        maxValue:
        email:
        url:检查是不是合法的URL地址。
        date:
        time:
        custom:设置为true,则会通过一个自定义的js函数来验证。函数定义在custom_func中。
        custom_func:传递给函数的值一个是需要验证value,另一个是定义在colModel中的name属性值。函数必须返回一个数组,一个是验证的结果,true或者false,另外一个是验证错误时候的提示字符串。形如[false,”Please enter valid value”]这样。
        自定义验证的例子:
        <script>
            function mypricecheck(value, colname) {
            if (value < 0 && value >20)
               return [false,"Please enter value between 0 and 20"];
            else
               return [true,""];
            }

            jQuery("#grid_id").jqGrid({
            ...
               colModel: [
                  ...
                  {name:'price', ..., editrules:{custom:true, custom_func:mypricecheck....}, editable:true },
                  ...
               ]
            ...
            });
        </script>  
    formoptions(只在Form Editing方式下有效),他的主要作用是用来重新排序Form中的编辑元素,同时可以在编辑元素前或者编辑元素后增加一些信息(比如,一些提示信息,或者一个红色的*表示必须要填写等等)。
        可选的属性如下:
        elmprefix:字符串值,如果设置了,则会在编辑框之后出现一些内容(可能是HTML的内容)
        elmsuffix:字符串值,如果设置了,则会在编辑框之前出现一些内容(可能是HTML的内容)
        label:字符串值,如果设置了,则这个值会替换掉colNames中的值出现作为该编辑框的标签显示
        rowpos:数字值,决定元素行在Form中的位置(相对于文本标签again with the text-label)
        colpos:数字值,决定元素列在Form中的位置(相对于标签again with the label)
        两个编辑框可以有相同的rowpos值,但是colpos值不同,这会把这两个编辑框放到Form的同一行中。
        特别注意:如果设置了rowpos以及colpos的值,强烈推荐为所有的其他编辑元素都设置这些值。

    ----本文只是doc文档的解释,没有太多自己的东西。接下来我会做一个Form Editing的例子,肉戏即将登场......

    我们讲了一下jqGrid编辑的基础知识。下面我们基于Form Editing的编辑模式详细举例讲解一下。

    Form Editing编辑模式主要的方法有几个,分别是editGridRow——用来修改记录,editGridRow函数,传递一个'new'的参数就表示新增记录;viewGridRow查看记录详情;delGridRow删除记录。

    这几个方法的调用方式,和jqGrid的其它函数调用方式一样。(可以采用new API的调用方式,把函数名称作为第一个参数来调用)需要注意的地方是,各个函数调用内容的options参数有一些差异,具体可以参考文档;另外就是,各个函数提交到服务端的数据和格式有所差异。这里以editGridRow为例来说明一下。

    editGridRow的调用方式如下:

    jQuery("#grid_id").editGridRow( rowid, properties ); 或者是如下的方式 jQuery("#grid_id").jqGrid('editGridRow', rowid, properties );
    其中rowid指定是编辑那一行,properties是一个包含各种属性以及事件的数组。(具体的属性和事件,请参考文档,这里就不翻译了。)调用之后,提交到服务器上去的数据都是一些什么数据呢?

    提交的数据主要包括:

    1.各个编辑"字段:值"的对。这个不好理解,其实的意思就是,相当于用POST的方式提交一些数据,数据的名称就是我们定义在colModel中的name属性,值就是我们在弹出窗口录入的值。(当然,这就要求我们在Server端的Action定义这些变量并封装到Pojo对象中去进行处理。)

    2.包含一个"id:rowid"的值,用来表明是哪一个id关键字的记录被修改(新增记录的时候,id=_empty);

    3.包含一个"oper:edit"的值,用来指示是编辑还是新增记录(新增记录的时候,oper=add)

    4.其它高级情况,比如使用了editData对象或者实现了onclickSubmit事件之后的处理。比较复杂,暂时没有详细研究这种情况下提交数据的格式。

    如果是要新增记录,那么editGridRow的调用方式如下:

    jQuery("#grid_id").editGridRow( "new", properties );

    好了,接下来我们来看看我们在jsp文件中是如何实现的吧。

    首先说明一下,这个例子和前一篇文章中的例子有很多变化。主要包括,在jqGrid中新增了一个列,用来作为操作列,同时增加了两个操作:编辑和删除。增加了一个导出查询结果为csv的按钮(自定义按钮),但是具体的后台服务器功能没有实现;把查询和新增功能单独作为一个按钮显示在jqGrid的后面。具体的差异,大家可以看看本人另外一篇文章《jqGrid的多字段查询》中的例子。

        $().ready(function(){
            $("#grid").jqGrid({       
                url:'queryAllBrand.action',
                datatype: "json",
                mtype: 'POST',
                colNames:['操作','品牌ID','品牌代码', '品牌名称', '是否可用','最后修改时间'],
                colModel:[
                    {name:'act',index:'act',width:110,search:false,sortable:false,editable:false},
                    {name:'brandId',index:'brandId', width:90,editable:false},
                    {name:'code',index:'code', width:110,
                        editable:true,
                        edittype:'text',
                        editoptions:{size:10,maxlength:15},
                        editrules:{required:true},
                        formoptions:{elmprefix:'(*)'}
                    },
                    {name:'brandName',index:'brandName', width:100,
                        editable:true,
                        edittype:'text',
                        editoptions:{size:10,maxlength:15},
                        editrules:{required:true},
                        formoptions:{elmprefix:'(*)'}
                    },
                    {name:'status',index:'status', width:80,
                        editable:true,
                        edittype:'checkbox',
                        editoptions:{value:"1:0"},
                        editrules:{required:true},
                        formoptions:{elmprefix:'(*)'}
                    },
                    {name:'lastModifiedDatetime',index:'lastModifiedDatetime', width:100,editable:false}
                ],
                rowNum:3

     

    在实际的修改、新增保存中,会看到如下的错误提示:error Status:"OK".Error code: 900。实际上,修改(新增)的记录已经正确的保存到数据库中了。

    这是为什么呢?一直为这个问题头痛苦恼了好几天。仔细阅读了jqGrid wiki上的文档,也google了许多的文章,仍然找不到相应的说明或者解决办法。

    后来研究了一下jqGrid的源代码。src/grid.formedit.js文件,发现其中有一个函数postIt,其中有如下的代码:

    if(Status != "success") { ret[0] = false; if ($.isFunction(rp_ge.errorTextFormat)) { ret[1] = rp_ge.errorTextFormat(data); } else { ret[1] = Status + " Status: '" + data.statusText + "'. Error code: " + data.status; } } else { // data is posted successful // execute aftersubmit with the returned data from server if( $.isFunction(rp_ge.afterSubmit) ) { ret = rp_ge.afterSubmit(data,postdata); } }

    看来问题是在这个地方。由此猜想jqGrid的增删改操作是要求服务器返回内容的。

    我猜测,jqGrid要求服务器返回包含成功与否的status内容。所以我修改了一下Action的类方法的返回值:如下:

    public String modifyBrand() {
        String result = "success";
        try {
            MProductBrand mpb = new MProductBrand();
            mpb.setBrandName(brandName);
            mpb.setCode(code);
            mpb.setStatus(status);
            mpb.setLastModifiedDatetime(new Timestamp(System.currentTimeMillis()));
            if(oper != null && oper.equals("edit")){
                //编辑
                mpb.setBrandId(new Integer(id));
                this.brandService.modifyBrand(mpb);
            } else if (oper != null && oper.equals("add")){
                //新增
                MProductBrand mproductbrand1 = this.brandService.locateByBrandcode(mpb .getCode().toString().trim().toUpperCase());
                MProductBrand mproductbrand2 = this.brandService.locateByBrandName(mpb .getBrandName().toString().trim());
                if (mproductbrand1.getBrandId() == null && mproductbrand2.getBrandId() == null) //检查是否存在
                {
                    this.brandService.addBrand(mpb); } else { log.warn("品牌代码或品牌名称已经存在");
                    result = "error";
                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            log.warn("修改失败");
            result = "error";
        }
        HttpServletResponse response = ServletActionContext.getResponse();
        response.setContentType("text/json; charset=UTF-8");
        try{
            PrintWriter out = response.getWriter();
            JSONObject json = new JSONObject();
            json.put("status", result);
            out.print(json.toString());
        } catch(Exception e){
            e.printStackTrace();
            log.error("Error:Cannot create PrintWriter Object !");
        }
        return null;
    }

    再次执行,发现保存成功之后,编辑窗口自动关闭,页面自动重新加载。很好!

    不过我一直在疑惑,到底服务器要怎么返回呢???仔细看了看jqGrid的Demo,想通过研究php文件来看看例子中是如何做的,也没有找到。并且,jqGrid Demo的编辑例子,是不实际向服务器提交修改内容的。说是为了安全原因......

    点击次数   官方主页【官方主页】   下载地址【下载地址】

    网友留言/评论

    我要留言/评论

    相关开源项目

    Flexigrid:Flexigrid是一个类似于Ext Gird,但基于jQuery开发的Grid。它具有的功能包括:可以调整列宽,合并列标题,分页,排序,显示/隐藏表格等。Flexigrid显示的数据能够通过Ajax获取或者从一个普通的表格转换。
    SortableTable:基于Mootools开发,具有排序与过滤功能的Table。
    dhtmlxGrid:dhtmlxGrid是一个Ajax-enabled JavaScript Grid。支持多种数据源包括:XML,JSON,CSV,JS数组和HTML表格。提供的功能有: 列宽大小调整,排序,拖动列,过滤,搜索,分组,分页等。
    Seamless Responsive Photo Grid:  
    假设用户想同时展示很多图片,而且要求图片间无缝连接。Seamless可以轻松满足你当需求。 
    Sigma Grid:Sigma Grid是一个采用纯javascript开发的Ajax数据表格。特性包括:
    1.基于CSS控制外观,内置Classic、Vista、Mac、XP四种风格。
    2.提供单元格直接编辑功能,可以自定义编辑器,为单元格设置数学计算公式,自定义单元格表现方式。
    3.提供灵活的表头控制功能比如:锁定表头,排序,拖动调整列宽。
    4.支持分页,数据过滤,根据数据生成柱状图,饼状图,曲线图。
    5.支持从多种数据源加载数据: JSON、XML、CSV等。
    6.支持多种浏览器:IE6.0+\FireFox2.0+\Safari3.0+\Opera9.0+。
    JavaScript Table Sorter:这是一个能够将标准Table转换成可排序Grid的JavaScript程序。它能够自动识别每列的数据类型,指定需要排序的列。
    GT-Grid:GT-Grid 一个功能丰富,简单易用的列表组件. 它可能不是最好的,但也许是你最需要的。
    tablesorter:tablesorter这个jQuery插件能够将带THEAD与TBODY标签的标准HTML Table转换成一个可排序的表格。tablesorter能够排序多种数据类型包括Text、URIs、integers、currency、floats、IP地址、日期、时间和自定义的数据类型。支持拥有复杂表头表格的排序,支持二级隐藏排序,支持多种浏览器:IE6.0+、FF2+、Safari2.0+、Opera9.0+。

    Ingrid:这个jQuery DataGrid提供的功能有:可以拖动调整列宽,分页,排序,设置行/列样式等。
    JQuery.Resizer:一个轻量级jQuery插件用于创建可以拖动调整行高与列宽的表格。