(一)首先介绍一下需要导入的包,如下所示:
需要导入两个css文件,一个是jquery-ui-1.9.2.custom.min.css,另一个是css/ui.jqgrid.css。需要导入四个js文件,分别是:jquery-3.1.1.min.js,jquery-ui-1.9.2.custom.min.js,grid.locale-en.js,jquery.jqGrid.min.js。这些文件建议下载最新版。其中jquery-3.1.1.min.js是要使用jquery需要导入的包;jquery-ui-1.9.2.custom.min.css和jqgrid/jquery-ui-1.9.2.custom.min.js是使用jquery-ui需要的包,因为jqgird中调用了很多jquery-ui,所以需要导入这两个包。剩下的样式表和js文件就是jqgrid需要的包。点击下载,可以跳到jquery-ui的下载界面;点击下载,可以跳到jqgrid下载界面。(二)下面我将一步一步展示如何使用jqgrid。
1.首先编写前台的简单页面index.jsp,代码如下:
<html>
<head>
<base href="<%=basePath%>">
<title>My JSP 'index.jsp' starting page</title>
<link rel="stylesheet" type="text/css" href="css/jquery-ui-1.9.2.custom.min.css">
<link rel="stylesheet" type="text/css" media="screen" href="css/ui.jqgrid.css">
<script type="text/javascript" src="js/jquery-3.1.1.min.js"></script>
<script type="text/javascript" src="js/jqgrid/jquery-ui-1.9.2.custom.min.js"></script>
<script type="text/javascript" src="js/jqgrid/grid.locale-en.js"></script>
<script type="text/javascript" src="js/jqgrid/jquery.jqGrid.min.js"></script>
<script type="text/javascript">
$(document).ready(function(){
jQuery("#jqGrid").jqGrid({
url:'demo/jqgridtest.action',
datatype: "json",
colNames:['ID','NAME'],
colModel:[
{name:'id',index:'id', width:90},
{name:'name',index:'name asc, invdate', width:100},
],
rowNum:3,
pager: '#jqGridPage',
sortname: 'id',
viewrecords: true,
sortorder: "desc",
jsonReader: {
root:"jsonArray",
repeatitems : false
},
caption: "成功",
autowidth: true,
shrinkToFit: true,
}).navGrid('#jqGridPage',{edit:false,add:false,del:false});
});
</script>
</head>
在body中定义了两个元素,一个table和一个div。jqrid的本质就是动态的为table添加<tr>和<td>子元素,所以我们需要一个 table来给jqrid操作,便于显示数据。在jqrid表格中,下面一排按钮,如比查询按钮,刷新按钮,跳转页按钮,这些按钮需要存放在一个div中,所以需要一个div来作为容器装载这些按钮元素。按钮如下图所示:
在head中定义了一个页面加载完即开始执行的js代码段,主要就是为body中定义的table配置jqgrid函数中的参数。我只解释
一些常用的参数。
在head中定义了一个页面加载完即开始执行的js代码段,主要就是为body中定义的table配置jqgrid函数中的参数。我只解释一些常用的参数。
url :jqGrid控件通过这个参数得到需要显示的数据,具体的返回值可以使XML也可以是Json。
datatype :这个参数用于设定将要得到的数据类型。我最常用的是“json”,其余的类型还包括:xml、xmlstring、local、javascript、function。
mtype : 定义使用哪种方法发起请求,GET或者POST。
height :Grid的高度,可以接受数字、%值、auto,默认值为150。
width :Grid的宽度,如果未设置,则宽度应为所有列宽的之和;如果设置了宽度,则每列的宽度将会根据shrinkToFit选项的设置,进行设置。
shrinkToFit :此选项用于根据width计算每列宽度的算法。默认值为true。如果shrinkToFit为true且设置了width值,则每列宽度会根据width
成比例缩放;如果shrinkToFit为false且设置了width值,则每列的宽度不会成比例缩放,而是保持原有设置,而Grid将会有水平滚动条。
autowidth :默认值为false。如果设为true,则Grid的宽度会根据父容器的宽度自动重算。重算仅发生在Grid初始化的阶段;如果当父容器尺
寸变化了,同时也需要变化Grid的尺寸的话,则需要在自己的代码中调用setGridWidth方法来完成。
pager :定义页码控制条Page Bar,一般是body中定义的那个div的ID值
sortname :指定默认的排序列,可以是列名也可以是数字。此参数会在被传递到Server端。
viewrecords :设置是否在Pager Bar显示所有记录的总数。
caption :设置Grid表格的标题,如果未设置,则标题区域不显示。
caption :Grid的标题。如果设置了,则将显示在Grid的Header层。
rowNum :用于设置Grid中一次显示的行数,默认值为20。正是这个选项将参数rows(prmNames中设置的)通过url选项设置的链接传递到Server。
注意如果Server返回的数据行数超过了rowNum的设定,则Grid也只显示rowNum设定的行数。
rowList :一个数组,用于设置Grid可以接受的rowNum值。例如[10,20,30]。
colNames :字符串数组,用于指定各列的题头文本,与列的顺序是对应的。
colModel :最重要的数组之一,用于设定各列的参数。(稍后详述)
prmNames :这是一个数组,用于设置jqGrid将要向Server传递的参数名称。(稍后详述)
jsonReader :这又是一个数组,用来设定如何解析从Server端发回来的json数据。(稍后详述)
prmNames选项:
prmNames是jqGrid的一个重要选项,用于设置jqGrid将要向Server传递的参数名称。其默认值为:
prmNames : {
page:"page", // 表示请求页码的参数名称
rows:"rows", // 表示请求行数的参数名称
sort: "sidx", // 表示用于排序的列名的参数名称
order: "sord", // 表示采用的排序方式的参数名称
search:"_search", // 表示是否是搜索请求的参数名称
nd:"nd", // 表示已经发送请求的次数的参数名称
id:"id", // 表示当在编辑数据模块中发送数据时,使用的id的名称
oper:"oper", // operation参数名称(我暂时还没用到)
editoper:"edit", // 当在edit模式中提交数据时,操作的名称
addoper:"add", // 当在add模式中提交数据时,操作的名称
deloper:"del", // 当在delete模式中提交数据时,操作的名称
subgridid:"id", // 当点击以载入数据到子表时,传递的数据名称
npage: null,
totalrows:"totalrows" // 表示需从Server得到总共多少行数据的参数名称,参见jqGrid选项中的rowTotal
}
除非你要修改传递的参数的名称,否则不用指定这些参数,因为这些数据默认都会发送到服务器端,比如我们可以在服务器端
来获得page的值来实现分页技术。如果要修改参数的名称的话,则需重写preNames,比如我要将_search改为search便于后台
写getter和setter函数,则可以改为:
preName:{
search:"search"
}
其他参数名称仍然是按照默认值的。
jsonReader选项:
jsonReader是jqGrid的一个重要选项,用于设置如何解析从Server端发回来的json数据。其默认值为:
jsonReader : {
root: "rows", // json中代表实际模型数据的入口
page: "page", // json中代表当前页码的数据
total: "total", // json中代表页码总数的数据
records: "records", // json中代表数据行总数的数据
repeatitems: true, // 如果设为false,则jqGrid在解析json时,会根据name来搜索对应的数据元素(即可以json中元素可以不按顺序)
//;而所使用的name是来自于colModel中的name设定。
cell: "cell",
id: "id",
userdata: "userdata",
subgrid: {
root:"rows",
repeatitems: true,
cell:"cell"
}
}
r
oot用于指定传过来的json数组数据,page表示当前页面数,total表示总共有多少页,records表示总的记录条数。repeatitems
允许重复。jsonReader参数我们一般只需要设置repeatitems,其他几个值不用修改,只要我们在后台设置json数组数据时的key值
严格按照rows,page,total等默认参数名来设置,就不需要在jsonReader中指定相应的值。但也是可以修改的。比如我们在后台
传过来的json数组名值对中key为datas,则我们需要在jsonReader中相应的做如下设置:
jsonReader:{
root:"datas",
repeatitems:"true"
}
其他值的key如果是严格按照默认值来的,则不需要改变。
colModel的选项:
和jqGrid一样colModel也有许多非常重要的选项,在使用搜索、排序等方面都会用到。这里先只说说最基本的。
name :为Grid中的每个列设置唯一的名称,这是一个必需选项,其中保留字包括subgrid、cb、rn。
index :设置排序时所使用的索引名称,这个index名称会作为sidx参数(prmNames中设置的)传递到Server。
label :当jqGrid的colNames选项数组为空时,为各列指定题头。如果colNames和此项都为空时,则name选项值会成为题头。
width :设置列的宽度,目前只能接受以px为单位的数值,默认为150。
sortable :设置该列是否可以排序,默认为true。
search :设置该列是否可以被列为搜索条件,默认为true。
resizable :设置列是否可以变更尺寸,默认为true。
hidden :设置此列初始化时是否为隐藏状态,默认为false。
formatter :预设类型或用来格式化该列的自定义函数名。常用预设格式有:integer、date、currency、number等(具体参见文档 )。
head中的js代码块中,最下面那段代码是设置页码控制条(也就是div中的那一组按钮)哪些是可用,哪些不可用。有search,
refresh,add,del,edit等一组按钮。
2.struts2及json相关配置
首先我们需要下载struts2的相关jar包放到lib中,然后去配置web.xml文件,配置struts2的监听器,配置代码如下:
<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.5"
xmlns="http://java.sun.com/xml/ns/javaee"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee
http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd">
<filter>
<filter-name>struts2</filter-name>
<filter-class>org.apache.struts2.dispatcher.ng.filter.StrutsPrepareAndExecuteFilter</filter-class>
</filter>
<filter-mapping>
<filter-name>struts2</filter-name>
<url-pattern>*.action</url-pattern>
<dispatcher>REQUEST</dispatcher> <!-- dispatch标签表示这个监听器会处理哪种类型的request -->
<dispatcher>FORWARD</dispatcher> <!-- 参考 http://blog.csdn.net/jethai/article/details/52345135 -->
</filter-mapping>
</web-app>
然后我们得去struts.xml文件中配置action,我们加入配置的action名字为jqgridtest,其配置如下:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE struts PUBLIC
"-//Apache Software Foundation//DTD Struts Configuration 2.3//EN"
"http://struts.apache.org/dtds/struts-2.3.dtd">
<struts>
<package name="police.run.dw.dimension" namespace="/demo" extends="json-default">
<action name="jqgridtest" class="controller.JqgridTest" method="doTest">
<result type="json">
<param name="root">resObj</param>
</result>
</action>
</package>
</struts>
在struts.xml中,我们配置extends="json-default",这个是很重要的,表明action的处理结果是返回json数据,在上面的配置
中,返回的是一个json数据对象resObj。我们还得导入一个工具包,就是操作json的包,名为json-lib,大家可以点击这里下载。
3.编写后台action类:
action类代码如下:
package controller;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JqgridTest extends ActionSupport{
private JSONObject resObj;
private int rows = 0; //设置的每一页多少条记录
private int page = 0; //当前页数,从1开始
private int total = 0; //总页数
private int record = 0; //总记录条数
private String sord;
private String sidx;
private String search;
/*
* 事件响应函数,返回json对象数据
*/
public String doTest(){
resObj=new JSONObject(); //需要返回的json对象
JSONArray datas=new JSONArray();
JSONObject cell1=new JSONObject();
cell1.put("id", 1);
cell1.put("name", "刘伟");
datas.add(cell1);
JSONObject cell2=new JSONObject();
cell2.put("id", 2);
cell2.put("name", "张斌");
datas.add(cell2);
JSONObject cell3=new JSONObject();
cell3.put("id", 3);
cell3.put("name", "刘伟");
datas.add(cell3);
JSONObject cell4=new JSONObject();
cell4.put("id", 4);
cell4.put("name", "张斌");
datas.add(cell4);
JSONObject cell5=new JSONObject();
cell5.put("id", 5);
cell5.put("name", "刘伟");
datas.add(cell5);
JSONObject cell6=new JSONObject();
cell6.put("id", 6);
cell6.put("name", "张斌");
datas.add(cell6);
JSONObject cell7=new JSONObject();
cell7.put("id", 7);
cell7.put("name", "刘伟");
datas.add(cell7);
JSONObject cell8=new JSONObject();
cell8.put("id", 8);
cell8.put("name", "张斌");
datas.add(cell8);
record=8;
total=3;
resObj=new JSONObject();
resObj.put("page", page); //返回当前页面,名称和jsonReader默认值一样
resObj.put("records", record);
resObj.put("total", total);
resObj.put("jsonArray", datas); //将json对象数组添加到json对象中
return SUCCESS;
}
public JSONObject getResObj() {
return resObj;
}
public void setResObj(JSONObject resObj) {
this.resObj = resObj;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getRecord() {
return record;
}
public void setRecord(int record) {
this.record = record;
}
public String getSord() {
return sord;
}
public void setSord(String sord) {
this.sord = sord;
}
public String getSidx() {
return sidx;
}
public void setSidx(String sidx) {
this.sidx = sidx;
}
public String getSearch() {
return search;
}
public void setSearch(String search) {
this.search = search;
}
}
我们在这里设置了total,records,page等值返回给前台对象,并且添加了9个json数据返回。其前台显示结果如下图所示:
4.分页显示:
我们会发现,上面的显示并不能实现分页。因为上面的代码中,不管page是何值,后台总是将所有的数据返回给前台对象,
但是前台对象每一页又只能显示3个值,所以虽然传回了所有的数据,但是却不能实现分页的效果,因为每一页显示的数据量有限,
后面的数据得不到显示。每次我们点击下一页按钮时,都会触发一次table向后台请求数据的事件,并且会附带上希望请求的page
值。我们则可以根据传来的page值,相应的返回该页面原本应该显示的数据,而不是返回所有的数据,这样便能实现分页的效果,
后台代码如下:
package controller;
import com.opensymphony.xwork2.ActionSupport;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
public class JqgridTest extends ActionSupport{
private JSONObject resObj;
private int rows = 0; //设置的每一页多少条记录
private int page = 0; //当前页数,从1开始
private int total = 0; //总页数
private int record = 0; //总记录条数
private String sord;
private String sidx;
private String search;
/*
* 事件响应函数,返回json对象数据
*/
public String doTest(){
resObj=new JSONObject(); //需要返回的json对象
JSONArray datas=new JSONArray();
if(page==1){ //第一页要显示的
JSONObject cell1=new JSONObject();
cell1.put("id", 1);
cell1.put("name", "刘伟");
datas.add(cell1);
JSONObject cell2=new JSONObject();
cell2.put("id", 2);
cell2.put("name", "张斌");
datas.add(cell2);
JSONObject cell3=new JSONObject();
cell3.put("id", 3);
cell3.put("name", "刘伟");
datas.add(cell3);
}
else if(page==2){ //第二页要显示的
JSONObject cell4=new JSONObject();
cell4.put("id", 4);
cell4.put("name", "张斌");
datas.add(cell4);
JSONObject cell5=new JSONObject();
cell5.put("id", 5);
cell5.put("name", "刘伟");
datas.add(cell5);
JSONObject cell6=new JSONObject();
cell6.put("id", 6);
cell6.put("name", "张斌");
datas.add(cell6);
}
else if(page==3){ //第三页要显示的
JSONObject cell7=new JSONObject();
cell7.put("id", 7);
cell7.put("name", "刘伟");
datas.add(cell7);
JSONObject cell8=new JSONObject();
cell8.put("id", 8);
cell8.put("name", "张斌");
datas.add(cell8);
JSONObject cell9=new JSONObject();
cell9.put("id", 9);
cell9.put("name", "刘伟");
datas.add(cell9);
}
record=9;
total=3;
resObj=new JSONObject();
resObj.put("page", page); //返回当前页面,名称和jsonReader默认值一样
resObj.put("records", record);
resObj.put("total", total);
resObj.put("jsonArray", datas); //将json对象数组添加到json对象中
return SUCCESS;
}
public JSONObject getResObj() {
return resObj;
}
public void setResObj(JSONObject resObj) {
this.resObj = resObj;
}
public int getRows() {
return rows;
}
public void setRows(int rows) {
this.rows = rows;
}
public int getPage() {
return page;
}
public void setPage(int page) {
this.page = page;
}
public int getTotal() {
return total;
}
public void setTotal(int total) {
this.total = total;
}
public int getRecord() {
return record;
}
public void setRecord(int record) {
this.record = record;
}
public String getSord() {
return sord;
}
public void setSord(String sord) {
this.sord = sord;
}
public String getSidx() {
return sidx;
}
public void setSidx(String sidx) {
this.sidx = sidx;
}
public String getSearch() {
return search;
}
public void setSearch(String search) {
this.search = search;
}
}
前台效果如下:
当然,这仅仅是一个demo,说明分页的原理,大家可以按照自己实际的需要去实现逻辑。
至此,大家应该对jqgrid有了一个基本的了解,应该都差不多都能够实现基本的功能了!
5.常见的错误:
有时我们会发现下面的那一组按钮显示不出来,分页的按钮也显示不出来。网上说是因为css相互有所覆盖导致的,其实这是错误的。本人看了jqgrid.css发现,下面的那一组按钮都是有固定的width值,比如说分页按钮那一组大小好像为400px,所以按钮显示不出来的原因很可能是因为jqgrid的宽度设置的太小。我们可以autowidth=true来避免这种情况,或者将width设置的大一些。
参考链接:http://blog.mn886.net/jqGrid/