jqGrid的使用

本文深入探讨了jqGrid的使用,包括环境搭建、基础结构、初始化参数和colModel参数设置。讲解了如何格式化日期、创建编辑时的固定与动态下拉列表、处理图片显示与编辑、以及二级表格的实现。同时,文章还涉及了jqGrid的其他实用功能,如.navGrid方法、表头居中和模态框控制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

1. 环境搭建

    <!--引入样式文件-->
    <link rel="stylesheet" href="${pageContext.request.contextPath}/statics/boot/css/bootstrap.css" type="text/css">
    <link rel="stylesheet" href="${pageContext.request.contextPath}/statics/jqgrid/css/trirand/ui.jqgrid-bootstrap.css" type="text/css">
    <!--引入js功能文件-->
    <script src="${pageContext.request.contextPath}/statics/boot/js/jquery-2.2.1.min.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/boot/js/bootstrap.min.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/i18n/grid.locale-cn.js" type="text/javascript"></script>
    <script src="${pageContext.request.contextPath}/statics/jqgrid/js/trirand/jquery.jqGrid.min.js" type="text/javascript"></script>

2. 基础结构

<table id="user-table"></table>
<div id="user-pager"></div>
<script>
    $(function () {
        //展示供应商信息
        $("#user-table").jqGrid({
            // 整合使用bootstrap样式的属性
            styleUI:'Bootstrap',
            url:'${pageContext.request.contextPath}/user/findUserByPage',
            editurl:'${pageContext.request.contextPath}/user/operUser',
            caption : "用户详细信息",
            datatype:'json',
            colNames:['姓名','性别','年龄'],
            // 开启表格编辑模式
            cellEdit:true,
            colModel:[
                {name:'username',align:'center',editable:true},
                {name:'sex',align:'center',editable:true},
                {name:'age',align:'center',editable:true}
            ],
            //添加分页
            //使用分页工具栏
            pager:'#user-pager',
            rowList:[5,10,15],
            rowNum:10,
            page:1,
        }).navGrid('#user-pager',{edit : true,add : true,del : true,search:true});
    })
</script>

3. 常用初始化参数

参数(带常用值)作用
url:‘项目名/user/findUserByPage’获取数据的地址
editurl:‘项目名/user/operUser’对数据进行增删改时的请求路径
styleUI:‘Bootstrap’整合使用bootstrap样式的属性
caption : “用户详细信息”表格标题
datatype:‘json’从服务器端返回的数据类型
colNames:[‘姓名’,‘性别’,‘年龄’]表头的列名
colModel:[{name:‘username’},{name:‘sex’},{name:‘age’}]每列各单元格名(下文详细介绍)
cellEdit:true开启表格编辑模式(允许进行增删改查
autowidth:true数据表格是否自适应父容器的大小宽度
rownumbers:true显示行号
multiselect:true在第一列前加入复选框
multiselectWidth:20当multiselect为true时设置multiselect列宽度
height:400设置表格整体高度
pager:’#user-pager’使用分页工具栏,写入指定div的id
rowList:[5,10,15]设置每页显示条数的选项
rowNum:10设置每页显示条数,必须从rowList中选择
page:1设置初始的页码
viewrecords:true是否显示总条数

4. 常用colModel参数

参数(带常用值)作用
name:‘username’表格的列名
align:‘center’设置表格内容居中显示
editable:true单元格是否可编辑
edittype:‘file’单元格编辑时的类型,这里一般用作文件上传
edittype:‘select’设置单元格编辑时为下拉列表(数据获取以下两种方式)
editoptions:{value:“正常:正常;冻结:冻结”}设置下拉列表选项
editoptions:{dataUrl:‘项目名/guru/findAll’}动态从服务器端获取数据,如果为下拉列表,返回值为拼接的select、option字符串
hidden:true设置此列是否隐藏
editrules:{edithidden:true}该字段隐藏时, 此属性可以控制是否可编辑
formatter设置此列的最终展示结果

colModel的实际使用

a. 格式化日期
	{
		name:'createDate',
		align:'center',
		formatter:"date",
		//srcformat为标准格式,newformat为最终显示格式
		formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
	}
b. 编辑时固定的下拉列表
	{
		name:'status',
		align:'center',
		edittype:"select",
		//value中前者为发送至后台的数据,后者为前台展示的数据
		editoptions:{value:"正常:正常;冻结:冻结"},
		editable:true
	}
c. 编辑时动态获取的的下拉列表(并设置表格显示内容)
{
     name:'deptId',
     align:'center',
     editable:true,
     edittype:'select',
     editoptions:{dataUrl:'${pageContext.request.contextPath}/dept/findAll'},
     formatter:function (value,options,row) {
         /**
          * value: 第一次(url)加载到的数据(deptId)
          * options: 略
          * row: 当前行(url)的所有数据
          */
         return row.deptName;
     }
 }

editoptions:{dataUrl:‘项目名/dept/findAll’}:发送请求到后台,返回拼接的select、option字符串
formatter:设置初始化时该列的显示内容,function中有三个参数

  • value: 第一次(url)加载到的数据(deptId),即与name对应的数据
  • row: 当前行(url)的所有数据

前台返回的数据中有deptName属性,所以直接return row.deptName;即可

一定注意editoptions与formatter两者互不影响。editoptions设置编辑时 该列的展示形式与数据,formatter设置初始化后该列最终展示的数据!!!
d. 图片相关的展示与编辑
	{
		name:'cover',
		align:'center',
		editable:true,
		edittype:'file',
		formatter:function(value,options,row){
			return '<img src="${pageContext.request.contextPath}/view/banner/image/'+row.cover+'"  width="150px" height="60px"/>';
		},
	}
  • edittype:‘file’ :设置该列编辑时类型,方便上传图片
  • formatter中后台拿到的数据中cover为文件名,这里在src中手动拼接了一下文件路径,便于展示。

注:关于jqGrid的文件上传是使用ajaxfileupload.js插件用异步上传的方式实现的,具体内容见我的另一篇博文ajaxfileupload+Jqgrid实现异步文件上传

e. 隐藏该列,编辑时展示
	{
		name:'password',
		align:'center',
		editable:true,
		hidden:true,                  //隐藏此列
		editrules:{edithidden:true}   //editrules:设置编辑字段的控件的规则
		               				  //edithidden:	该字段隐藏时, 此属性可以控制是否可编辑
	}

5. 二级表格的使用

a. 效果展示


这里使用的是在当前行前加一个按钮,通过按钮来控制子表的展示与隐藏。

b. 使用步骤
  1. 使用二级表格首先要在初始化参数中开启subGrid :true
  2. 之后再使用subGridRowExpanded : function(subgrid_id, row_id) {}
    function中的两个参数:
    subgrid_id: 当前行子表的id
    row_id: 父表当前行的id
    之后的编码都在{}内完成
  3. 动态生成存放子表的table,存放子表工具栏的div并赋予id
	//subgrid_id 子表id      row_id父表当前行id
	var subgrid_table_id, pager_id;
	subgrid_table_id = subgrid_id + "_t"; //生成存放子表表格<table>的id
	pager_id = "p_" + subgrid_table_id;   //生成存放子表工具栏div的id
	
	//生成table  div
	$("#" + subgrid_id).html(
	    "<table id='" + subgrid_table_id
	    + "' class='scroll'></table><div id='"
	    + pager_id + "' class='scroll'></div>");
  1. 获取该子表格table标签与工具栏div标签填充相应数据,与普通jqdrid填充数据相同。
c. 具体编码
   subGrid : true,
   subGridRowExpanded : function(subgrid_id, row_id) {
       //subgrid_id 子表id      row_id父表当前行id
       var subgrid_table_id, pager_id;
       subgrid_table_id = subgrid_id + "_t"; //生成存放子表表格<table>的id
       pager_id = "p_" + subgrid_table_id;   //生成存放子表工具栏div的id

       //生成table  div
       $("#" + subgrid_id).html(
           "<table id='" + subgrid_table_id
           + "' class='scroll'></table><div id='"
           + pager_id + "' class='scroll'></div>");

       //填充内容
       $("#" + subgrid_table_id).jqGrid(
           {

               // 整合使用bootstrap样式的属性
               styleUI:'Bootstrap',
               url:'${pageContext.request.contextPath}/chapter/findChapterByPage?aid='+row_id,
               editurl:'${pageContext.request.contextPath}/chapter/operChapter?aid='+row_id,
               caption : "章节详细信息",
               datatype:'json',
               colNames:['名称','大小(单位:M)','时长','创建时间','操作'],
               // 开启表格编辑模式
               cellEdit:true,
               colModel:[
                   {name:'title',align:'center',editable:true},
                   {name:'size',align:'center'},
                   {name:'duration',align:'center'},
                   {
                       name:'createDate',
                       align:'center',
                       formatter:"date",
                       formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
                   },
                   {
                       name:'audio',
                       width:350,
                       formatter:function(value,options,row){
                           return '<audio controls loop>' +
                               '<source src="${pageContext.request.contextPath}/view/album/mp3/'+row.audio+'" type="audio/mpeg"/>' +
                               '</audio>';
                       },

                       align:'center',
                       editable:true,
                       edittype:'file',

                   },

               ],
               //数据表格是否自适应父容器的大小宽度
               autowidth:true,
               //显示行号
               rownumbers:true,
               //在第一列前加入复选框
               multiselect:true,
               multiselectWidth:20,
               //设置高度
               height:200,
               //添加分页
               //使用分页工具栏
               pager:"#"+pager_id,
               rowList:[5,10,15],
               rowNum:10,
               page:1,
               //显示总记录数
               viewrecords:true
           }).navGrid("#"+pager_id,{edit : true,add : true,del : true,search:true});
   },

6. 关于jqGrid的一些其他实际应用

a. jqgrid的.navGrid()方法(执行完增删改后的一些操作);

.navGrid方法可对工具栏和编辑事件做一些设置。比如控制工具栏增、删、改、查操作是否显示。对修改、添加、删除操作做一些控制。
但注意它的顺序有严格要求。
.navGrid(“工具栏id”,{工具栏显示内容},{修改操作},{添加操作}),{删除操作}
示例:

.navGrid("#pager_id",{edit : true,add : true,del : true,search:true},
   //=====控制修改操作=========
    {
        //修改后关闭
        closeAfterEdit: true,
        //提交后:
        afterSubmit:function (response) {
         	//response为修改操作访问controller的返回值
         	//map集合可通过response.responseJSON.key取值
        }
    },

    //=====控制添加操作=========
    {
        //添加后关闭
        closeAfterAdd: true,
        //提交后:
        afterSubmit:function (response) {
			//response为添加操作访问controller的返回值
         	//map集合可通过response.responseJSON.key取值
        }
    },
    {
        //控制删除操作 删除操作里没有afterSubmit
        afterComplete: function () {
            //在完成删除操作后可执行
        }
    }
);
b. 设置表头也居中(记得复选框)

在colMode中设置align:'center’可控制该列内容居中,但该表格的表头(第一行)还是靠左显示,这里可以通过css样式设置表头居中。对th标签进行控制。

	<style>
        th{
           text-align:center;
        }
    </style>

注意:如果第一列加入了复选框,则该列复选框仍会有问题。没有找到很好的解决方法。这里选择使用设置复选框大小维持视觉上的居中。
jqGrid初始化参数中设置:

	//在第一列前加入复选框
	multiselect:true,
	//当multiselect为true时设置multiselect列宽度
	multiselectWidth:20,
c. 修改或添加后关闭模态框

在.navGrid方法中找到对应修改或添加操作的位置,加入:
修改:

		//修改后关闭
       closeAfterEdit: true,

添加:

		//修改后关闭
       closeAfterAdd: true,

删除的模态框执行操作后会自动关闭。
具体实例与代码参照上述 a

7. 一个带有二级表格完整代码

前台代码:

<%@page contentType="text/html; UTF-8" isELIgnored="false" pageEncoding="UTF-8"%>
<%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<!--相关js文件在主页面已经引入->
<c:set value="${pageContext.request.contextPath}" var="app"/>
<ul class="nav nav-tabs">
    <li role="presentation" class="active"><a href="#">专辑详情</a></li>
    <li role="presentation"><a href="${app}/album/download">导出专辑信息</a></li>
</ul>
<table id="album-table"></table>
<div id="album-pager"></div>
<script>
$(function () {
    //展示专辑信息
    $("#album-table").jqGrid({
        // 整合使用bootstrap样式的属性
        styleUI:'Bootstrap',
        url:'${app}/album/findAlbumByPage',
        editurl:'${app}/album/operAlbum',
        datatype:'json',
        colNames:['名称','封面','作者','简介','播音','集数','上架时间','分数'],
        // 开启表格编辑模式
        cellEdit:true,
        colModel:[
            {name:'title',align:'center',editable:true},
            {
                name:'cover',
                formatter:function(value,options,row){
                    return '<img src="${app}/view/album/image/'+row.cover+'"  width="150px" height="60px"/>';
                },
                align:'center',
                editable:true,
                edittype:'file',

            },
            {name:'author',align:'center',editable:true},
            {name:'detail',align:'center',editable:true},
            {name:'broadcast',align:'center',editable:true},
            {name:'count',align:'center'},
            {
                name:'createDate',
                align:'center',
                formatter:"date",
                formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
            },
            {
                name:'score',
                align:'center',
                edittype:"select",
                editoptions:{value:"1:1;2:2;3:3;4:4;5:5"},
                editable:true
            },
        ],

        //二级表格开始=========================================================
        subGrid : true,
        subGridRowExpanded : function(subgrid_id, row_id) {
            //subgrid_id 子表id      row_id父表当前行id
            var subgrid_table_id, pager_id;
            subgrid_table_id = subgrid_id + "_t"; //生成存放子表表格<table>的id
            pager_id = "p_" + subgrid_table_id;   //生成存放子表工具栏div的id

            //生成table  div
            $("#" + subgrid_id).html(
                "<table id='" + subgrid_table_id
                + "' class='scroll'></table><div id='"
                + pager_id + "' class='scroll'></div>");

            //填充内容
            $("#" + subgrid_table_id).jqGrid(
                {

                    // 整合使用bootstrap样式的属性
                    styleUI:'Bootstrap',
                    url:'${app}/chapter/findChapterByPage?aid='+row_id,
                    editurl:'${app}/chapter/operChapter?aid='+row_id,
                    caption : "章节详细信息",
                    datatype:'json',
                    colNames:['名称','大小(单位:M)','时长','创建时间','操作'],
                    // 开启表格编辑模式
                    cellEdit:true,
                    colModel:[
                        {name:'title',align:'center',editable:true},
                        {name:'size',align:'center'},
                        {name:'duration',align:'center'},
                        {
                            name:'createDate',
                            align:'center',
                            formatter:"date",
                            formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d'}
                        },
                        {
                            name:'audio',
                            width:350,
                            formatter:function(value,options,row){
                                return '<audio controls loop>' +
                                    '<source src="${app}/view/album/mp3/'+row.audio+'" type="audio/mpeg"/>' +
                                    '</audio>';
                            },

                            align:'center',
                            editable:true,
                            edittype:'file',

                        },

                    ],
                    //数据表格是否自适应父容器的大小宽度
                    autowidth:true,
                    //显示行号
                    rownumbers:true,
                    //在第一列前加入复选框
                    multiselect:true,
                    multiselectWidth:20,
                    //设置高度
                    height:200,
                    //添加分页
                    //使用分页工具栏
                    pager:"#"+pager_id,
                    rowList:[5,10,15],
                    rowNum:10,
                    page:1,
                    //显示总记录数
                    viewrecords:true

                }).navGrid("#"+pager_id,{edit : true,add : true,del : true,search:true},

                    //=====二级表格控制修改操作=========
                    {
                        //修改后关闭
                        closeAfterEdit: true,
                        //提交后:
                        afterSubmit:function (response) {
                            var id = response.responseJSON.data;   //返回的id
                            var code = response.responseJSON.code; //返回的状态码

                            if(code==200) {
                                $.ajaxFileUpload({
                                    fileElementId: "audio",    //需要上传的文件域的ID,即<input type="file">的ID。
                                    url: "${app}/chapter/upload",     //后台方法的路径
                                    type: 'post',              //当要提交自定义参数时,这个参数要设置成post
                                    data: {id: id},              //发送请求时传递的参数(数据)
                                   // dataType: 'json',          //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
                                    //   secureuri: false,        //是否启用安全提交,默认为false。
                                    //   async : true,            //是否是异步
                                    success:function() {
                                        $("#album-table").trigger("reloadGrid");
                                    }
                                })
                                return "true";
                            }

                        }
                    },

                    //=====二级表格控制添加操作=========
                    {
                        //添加后关闭
                        closeAfterAdd: true,
                        //提交后:
                        afterSubmit:function (response) {
                            var id = response.responseJSON.data;   //返回的id
                            var code = response.responseJSON.code; //返回的状态码

                            if(code==200) {
                                $.ajaxFileUpload({
                                    fileElementId: "audio",    //需要上传的文件域的ID,即<input type="file">的ID。
                                    url: "${app}/chapter/upload",     //后台方法的路径
                                    type: 'post',              //当要提交自定义参数时,这个参数要设置成post
                                    data: {id: id},              //发送请求时传递的参数(数据)
                                    success:function() {
                                        $("#album-table").trigger("reloadGrid");
                                    }
                                })
                                return "true";
                            }

                        }
                    },
                    {
                        //控制删除操作 添加操作里没有afterSubmit
                        afterComplete: function () {
                            //刷新父表(集数)
                            $("#album-table").trigger("reloadGrid");
                        }
                    }



                );

        },

        //二级表格结束=========================================================

        //数据表格是否自适应父容器的大小宽度
        autowidth:true,
        //显示行号
        rownumbers:true,
        //在第一列前加入复选框
        multiselect:true,
        multiselectWidth:20,
        //设置高度
        height:500,
        //添加分页
        //使用分页工具栏
        pager:'#album-pager',
        rowList:[5,10,15],
        rowNum:10,
        page:1,
        //显示总记录数
        viewrecords:true
    }).navGrid('#album-pager',{edit : true,add : true,del : true,search:true},
        //.navGrid("工具栏id",{显示内容},{修改操作},{添加操作}),{删除操作}


        //=====控制修改操作====================================================================
        {
            //修改后关闭
            closeAfterEdit:true,
            //提交后:
            afterSubmit:function (response) {
                var id = response.responseJSON.data;   //返回的id
                var code = response.responseJSON.code; //返回的状态码

                if(code==200) {
                    $.ajaxFileUpload({
                        fileElementId: "cover",    //需要上传的文件域的ID,即<input type="file">的ID。
                        url: "${app}/album/upload",     //后台方法的路径
                        type: 'post',              //当要提交自定义参数时,这个参数要设置成post
                        data: {id: id},              //发送请求时传递的参数(数据)
                       // dataType: 'json',          //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
                        //   secureuri: false,        //是否启用安全提交,默认为false。
                        //   async : true,            //是否是异步
                        success:function() {
                            $("#album-table").trigger("reloadGrid");
                        }
                    })
                    return "true";
                }

            }
        },


        //=====控制添加操作====================================================================
        {
            //添加后关闭
            closeAfterAdd: true,
            //提交后:
            afterSubmit:function (response) {
                var id = response.responseJSON.data;   //返回的id
                var code = response.responseJSON.code; //返回的状态码

                if(code==200) {
                    $.ajaxFileUpload({
                        fileElementId: "cover",    //需要上传的文件域的ID,即<input type="file">的ID。
                        url: "${app}/album/upload",     //后台方法的路径
                        type: 'post',              //当要提交自定义参数时,这个参数要设置成post
                        data: {id: id},              //发送请求时传递的参数(数据)
                        //dataType: 'json',          //服务器返回的数据类型。可以为xml,script,json,html。如果不填写,jQuery会自动判断。
                        //   secureuri: false,        //是否启用安全提交,默认为false。
                        //   async : true,            //是否是异步
                        success:function() {
                            $("#album-table").trigger("reloadGrid");
                        }
                    })
                    return "true";
                }

            }
        }

    );

})

</script>

后台代码:

@RequestMapping("album")
@RestController
public class AlbumController extends BaseApiService{

    @Autowired
    private AlbumService albumService;
    @Autowired
    private AlbumDAO albumDAO;
    @Autowired
    private ChapterDAO chapterDAO;

    @RequestMapping("findAlbumByPage")
    /**
     * page:查询页数
     * rows:每页显示条数
     * searchField: 查询条件
     * searchString: 查询内容
     * 加入分页工具栏后,远程响应json数据格式为:
     * {"rows":[当前页结果(list)],"page":"当前页","total":"总页数","records":"总条数"}
     */
    public Map<String,Object> findAlbumByPage(Integer page, Integer rows,
                                               String searchField, String searchString){
        //创建结果集
        List<Album> albumList = null;
        Integer records = 0;
        HashMap<String, Object> map = new HashMap<>();
        Integer total = 0;


        //判断是否为模糊查询
        if(searchField==null){
            //查询集合
            albumList = albumService.findAllByPage(page, rows);
            //查询总条数
            records = albumService.getCount();
            //计算总页数
            total = records%rows==0?records/rows:records/rows+1;
        }else {
            //查询集合
            albumList = albumService.findAllByPageBySearch(page, rows,searchField,searchString);
            //查询总条数
            records = albumService.getCountBySearch(searchField,searchString);
            //计算总页数
            total = records%rows==0?records/rows:records/rows+1;
        }


        return setPageMap(albumList,page,total,records);

    }

    @RequestMapping("operAlbum")
    public Map<String,Object> operAlbum(Album album,MultipartFile cover,String id,String oper) {
        //添加
        if("add".equals(oper)){
            String i = albumService.add(album);
            return setResultSuccessData(i);
        }

        //修改
        if("edit".equals(oper)){

            String i = albumService.update(album);
            return setResultSuccessData(i);
        }

        //删除
        if("del".equals(oper)){
            String[] ids = id.split(",");
            for (String i : ids) {
                albumService.delete(i);
            }
        }

        return null;

    }

    @RequestMapping("upload")
    public String upload(MultipartFile cover, String id, HttpSession session) throws IOException {

        System.out.println("id===="+id);
        System.out.println("cover===="+cover.getOriginalFilename());
        if ("".equals(cover.getOriginalFilename())) return null;
        //获取文件上传路径
        String realPath = session.getServletContext().getRealPath("/view/album/image");
        //文件上传
        cover.transferTo(new File(realPath,cover.getOriginalFilename()));

        //修改数据库图片中的路径
        Album album = new Album();
        album.setId(id).setCover(cover.getOriginalFilename());
        albumService.update(album);

        return "success";
    }
}

说明:

  • BaseApiService:自己定义的一个工具类,更方便的设置返回值(map)
  • return setResultSuccessData(i); 对应map数据:{“code”:200,“data”:i}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值