其实本来是看到ejb之类的控件做起来页面很漂亮,再看普通的jsp中的table那么难看,就想着搜索一下有什么好看的jquery插件,就看到了jqgrid。感觉还行,就拿来学了1天,差不多能够简单应用了,当然没有将全部的功能都撸一遍。
下面就正式开始了,从简单到复杂一点点,然后再说说怎么使用高级应用。
一、下载准备jqgrid
官方下载点:http://www.jqgrid.com,最新的版本应该是4.8;
jqgrid使用的ui是jquery-ui,如果觉得自带的太丑了,可以下载一个喜欢的jquery-ui;
地址:http://jqueryui.com/themeroller/,默认的ui是灰色,如果希望其他的,在左侧选择:
二、demo参考
第一次拿到jqgrid的时候,不知道从什么地方入手,那么就看看官网的demo:
英文版:http://www.trirand.com/blog/jqgrid/jqgrid.html
中文版:http://blog.mn886.net/jqGrid/
建议看英文版的demo,因为英文版的demo,在样例中可以查看整个页面的源码,而中文版的没有;
三、实例
3.1 页面引入jqgrid和jquery-ui
下载的jqgrid目录结构如下:
其中css是jqgrid的样式,用到文件ui.jqgrid.css
js中用到的:jquery.jqGrid.min.js
如果不想下载jquery,可以直接用里面的:jquery-1.11.0.min.js
i18n是国际化,主要是jqgrid的标签国际化:i18n/grid.locale-cn.js
【这里用到中文的话其实有点问题,不过解决方法很简单,后面会讲解】
jquery-ui:
引入:jquery-ui.css,其他的目录文件不变,直接引入工程
3.2 新建工程[web工程]
工程的目录结构就不截图了
3.3 构建测试数据
这里可以自己新建map作为测试数据,或者使用数据库,我这里使用的是mysql数据;
新建user表,字段为了测试有timestamp;
3.4 新建测试页面index.jsp
引入外部css和js:
<link rel="stylesheet" media="screen" type="text/css" href="<%=path%>/js/jquery-ui/jquery-ui.css"/> <link rel="stylesheet" media="screen" type="text/css" href="<%=path%>/js/css/ui.jqgrid.css"/> <script type="text/javascript" src="<%=path%>/js//jquery-1.11.0.min.js"></script> <script type="text/javascript" src="<%=path%>/js/i18n/grid.locale-cn.js"></script> <script type="text/javascript" src="<%=path%>/js/jquery.jqGrid.min.js"></script>
页面中body部分:
<body> <table id="list"></table> <div id="pager"></div> </body>
其中table是数据显示位置,div是分页栏;
脚本:
<script type="text/javascript"> $(function(){ var rando = <%=new java.util.Random().nextInt() %>; $("#list").jqGrid({ url:'userInfoServlet.do?rand=' + rando,// 获取数据的url,action datatype: "json",//后台返回的数据格式 mtype:"get",//提交的方式,默认是get height:400,//高度,表格高度。可为数值、百分比或'auto' //width:1024,//这个宽度不能为百分比, autowidth:true,//自动宽 colNames:['登陆名', '密码', '中文名称','英文名称','email','qq','座机号','手机号','最后登录时间','是否锁定'], colModel:[ {name:'loginName',index:'loginName', editable:true,sortable:true}, {name:'loginPass',index:'loginPass', width:100,editable:true}, {name:'name',index:'name', align:"center",editable:true}, {name:'ename',index:'ename', align:"center",editable:true}, {name:'email',index:'email', sortable:false,editable:true}, {name:'qq',index:'qq', sortable:false,editable:true}, {name:'tel',index:'tel', sortable:false,editable:true}, {name:'phone',index:'phone', sortable:false,editable:true}, {name:'lastLoginTime',index:'lastLoinTime', sortable:false,editable:true,formatter:'date',formatoptions: {srcformat:'Y-m-d H:i:s',newformat:'Y-m-d H:i:s'}}, {name:'islock',index:'islock', align:"center",formatter:function(cellvalue, options, rowObject){if(cellvalue=="00"){return "未锁定";} else if(cellvalue=="11"){return "锁定";} else {return "剩余1次";}}} ], postData:{page:1,hahah:123},//此参数用来向后台提交数据*****可以自己添加需要的参数 caption:"用户管理-增删改",//表名称 multiselect: true,//开启多选 rowNum:10,//每页显示的条数,此参数会被传递到后台 rowList:[10,20,30,50],//定义每页显示的条数下拉框选择,会覆盖rowNum viewrecords: true,//定义是否显示总的数据条数 pager: '#pager',//定义翻页用的导航栏,必须是有效的html元素,可以放在任意位置 rownumbers:true//添加左侧行号 }); $("#list").jqGrid('navGrid','#pager', {edit:true,add:true,del:true,search:true,refresh:true,addtext:'添加'}); }); </script>
各参数说明:
3.4.1 高度和宽度,注意不能加px,只写数值就可以了,也可以依据自己情况传入参数;
3.4.2 列表项
colNames
这个参数是定义结果记录的表头,有多少项就写多少个参数:
3.4.3 列表项格式
colModel
name:当前列的标识,可以理解成对应表字段名
index:传到后台的,用于排序的标识,
editable:true,是否允许编辑,这个一般是在编辑行数据的时候用到
sortable:true,是否允许排序,点击标题排序
align:"center",内容位置,left,center,right
postData:自定义参数,默认jqgrid会传入后台一些数据,也可以用这个参数来自定义一些想要传入的参数;
其他的参数可以搜索网上的说明,有很多,这里不做过多介绍。
如果数据有日期格式的,那么可以参看上面的lastLoginTime格式化日期,
下面的islock参数其实后台传入的是字符串,但是也可以依据自己的需求显示中文,常用的如性别之类的;
3.5 后台数据处理
新建简单的servlet,在web中配置好,
UserInfoServlet重写goGet方法:
@Override protected void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException { //打印页面传递来的所有参数 Enumeration enu=req.getParameterNames(); while(enu.hasMoreElements()){ String paraName=(String)enu.nextElement(); System.out.println(paraName+": "+req.getParameter(paraName)); } //存储数据,转为json后传回页面 Map<String, Object> map = new HashMap<String, Object>(); map = buildReturn(map,req); // 使用json工具将map转化为json数据 JsonConfig jsonConfig = new JsonConfig(); jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT); //自动为我排除circle。 //重写JsonValueProcessor,格式化date,默认的date格式没有带时分秒 jsonConfig.registerJsonValueProcessor(Timestamp.class, new DateJsonValueProcessor()); JSONObject json = JSONObject.fromObject(map,jsonConfig); resp.getWriter().write(json.toString()); } private Map<String, Object> buildReturn(Map<String, Object> map,HttpServletRequest req) { // 从req中获取需要的参数 Integer page = Integer.parseInt(req.getParameter("page"));// 当前的页数 Integer rows = Integer.parseInt(req.getParameter("rows"));// 每页显示数据条数 String sidx = req.getParameter("sidx");// 点击项目的id,依据这个进行排序,默认是空不是null String sord = req.getParameter("sord");// 排序的规则:asc / desc // 搜索 String searchField = req.getParameter("searchField"); //搜索的字段名称 loginName String searchString = req.getParameter("searchString");// 输入的搜索条件 lo String searchOper = req.getParameter("searchOper");// 搜索条件 bw List<User> list = new ArrayList<User>(); String sql = "select * from user where 1=1 limit 0,10 "; // 依据查询条件进行查询. if("".equals(sidx) || null == sidx){ // 默认第一次加载的时候显示的数据 sql = " select * from user where 1=1 limit " + (page -1 ) * rows + "," + rows + ""; list = JDBCutils.getUsers(JDBCutils.getConnection(), sql); }else { sidx = StringUtils.lowerCase(sidx); sql = " select * from user where 1=1 order by "+ sidx + " " + sord +" limit " + (page -1 ) * rows + "," + rows + ""; list = JDBCutils.getUsers(JDBCutils.getConnection(), sql); } //构建参数 int countTotal = JDBCutils.exeSQL(JDBCutils.getConnection(), "select count(0) from user"); int totalPageNum = (countTotal + (rows - 1)) / rows;// 总的页数 if (totalPageNum < page) {// page = totalPageNum; } map.put("total", totalPageNum); map.put("page", page); map.put("records", countTotal); map.put("rows", list); return map; }
其中重写的DateJsonValueProcessor.java
public class DateJsonValueProcessor implements JsonValueProcessor { public static final String DEFAULT_DATE_PATTERN = "yyyy-MM-dd HH:mm:ss"; private DateFormat dateFormat; public DateJsonValueProcessor() { this(DEFAULT_DATE_PATTERN); } public DateJsonValueProcessor(String datePattern) { try { dateFormat = new SimpleDateFormat(datePattern); } catch (Exception ex) { dateFormat = new SimpleDateFormat(DEFAULT_DATE_PATTERN); } } public Object processArrayValue(Object value, JsonConfig jsonConfig) { return process(value); } public Object processObjectValue(String key, Object value, JsonConfig jsonConfig) { return process(value); } /** * 这里对json的数值进行格式化处理 */ private Object process(Object value) { if (value instanceof Timestamp) return dateFormat.format((Timestamp) value); else if (value instanceof Date) return dateFormat.format((Date) value); else if (value == null) return ""; else return value.toString(); } }
3.6 处理国际化时出现的问题
如果引入国际化的js:grid.locale-cn.js
会出现这样的情况:无论有没有数据,表格中间一直显示undefined,很多人说是因为加入了分页,要注释掉jqgrid中的pager:'#pager'这个行,其实不对,要么是没有引入国际化文件,要么就是中文国际化的问题。
解决:
第一种情况,只需要引入国际化文件grid.locale-en.js即可
第二种情况,就是中文导致错误,一般理解是文件编码异常,但是我检查了所有文件都是utf-8的,在servlet中加入编码转换也不行。最后没办法我就对比2个locale文件,发现区别就是标签不同其他都一样,我就直接修改en.js里面的的标签改为中文,然后就正常了......