浏览 7085 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
|
|
---|---|
作者 | 正文 |
发表时间:2011-06-07
最后修改:2011-06-07
和排序都在服务器端实现,现总结如下: 操作页面是这样的: 用户输入查询信息,按“检索”按钮,返回查询结果,表格可以翻页,排序。 当把jqGrid的属性datatype定义为function时,表格需要获取数据时(翻页,排序等),jqGrid就会调用 这个function,通过这种机制,就可以实现服务器端分页、排序。需要注意的是,这个function需要读取 数据并显式地调用addJSONData,addXMLData等去刷新表格,详情可以参看: http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#function 这个函数有一个参数,关于参数的定义我没有找到,但用firebug之类的工具可以看出包括如下的属性: _search : (不清楚) nd : (不清楚) page : 当前页 rows : 每页记录数 sidx : sort index,排序字段名 sord : sort direction,排序方式:asc, desc 这样一来,我们就可以把这些数据发送到服务器端进行分页和排序。 以下是页面的html代码: <table width="95%"> <tr> <td> <table> <tr> <td> <form id="frmSearchCustomer"> <table> <tr> <td> 名称:<input type="text" name="name" /> アドレス:<input type="text" name="addr" /> </td> </tr> <tr> <td> 担当者:<input type="text" name="dandang" /> </td> </tr> </table> </form> </td> </tr> <tr> <td> <button id="search">检索</button> <button id="clear">清除条件</button> </td> </tr> </table> </td> </tr> <tr> <td> <table id="list"></table> <div id="pager"></div> </td> </tr> </table> 以下是jqGrid初始化的代码: $("#list").jqGrid({ datatype : function(postdata) { postdata = mergeObject(jsonCondition, postdata); jQuery.ajax({ type : 'POST', contentType : 'application/json', url : ROOT_PATH + '/customer/search.do', data : JSON.stringify(postdata), dataType : 'json', success : function(resp) { if (resp.successed) { var thegrid = jQuery("#list")[0]; thegrid.addJSONData(resp.returnObject); } else { alert(resp.errors[0].message); } }, error : ajaxFailed }); }, height : '100%', rowNum : '10', jsonReader : { repeatitems: false }, colNames : ['顧客番号', '名称', 'アドレス', '担当者', '携帯', '電話①', '電話②'], colModel : [ {name:'id', index:'id', width:80}, {name:'name', index:'name', width:256}, {name:'addr', index:'addr', width:256}, {name:'dandang', index:'dandang', width:64}, {name:'mobile', index:'mobile', width:128}, {name:'phone1', index:'phone1', width:128}, {name:'phone2', index:'phone2', width:128}, ], pager : '#pager' }); 其中关键就是datatype为一function,在这个function中通过jQuery.ajax发送一个请求,获取数据,然后通过 addJSONData刷新表格数据。发送的数据包括postdata和用户输入的查询条件,其中postdata是jqGrid传递过来 的包含分页、排序信息的对象,jsonCondition是“检索”按钮中生成的包含查询条件的对象。 检索按钮中的处理如下: var jsonCondition = {}; function search() { jsonCondition = array2Json(jQuery("#frmSearchCustomer").serializeArray()); jQuery("#list").trigger("reloadGrid"); } 其中array2Json是从网上找来的把jQuery的serializeArray生成的数组转成json的函数,我以前的文章里有,这里 就不重复了。 mergeObject是一个我自己写的拷贝一个对象的属性到另一对象的函数: function mergeObject(src, dest) { var i; for(i in src) { dest[i]=src[i]; } return dest; } 下面说下服务器端。 我用的spring的controller是直接接受json数据并以json格式返回数据的,这部分是延续以前的做法的,可以参见 我以前的文章: jquery(1.3.2)<--json-->spring(3.0) jquery<--json-->spring(3.0)之后台校验 我定义了一个对应jqGrid的postdata的类: public class JQGridRequest { private String _search; private String nd; private int page; private int rows; private String sidx; private String sord; ... } 对于不同的查询页面,可以扩展这个类,定义包含该页面查询条件的类,本例中我定义了这样的类: public class CustomerSearchInfo extends JQGridRequest { private String name; private String addr; private String dandang; ... } Controller的定义如下,其中接受的参数就是上面所说的CustomerSearchInfo这个类: @Controller @RequestMapping("/customer") public class CustomerController extends JSONController { private CustomerService customerService; ... @RequestMapping(value = "/search", method = RequestMethod.POST) @ResponseBody public JSONResponse search(@RequestBody CustomerSearchInfo searchInfo) { JQGridResponse data = customerService.search(searchInfo); return this.successed(data); } } jqGrid对于json数据是有格式要求的(这个格式可以自定义),详情可以参见 http://www.trirand.com/jqgridwiki/doku.php?id=wiki:retrieving_data#json_data 当repeatitems为false时默认是这样的: { "total": "xxx", //总页数 "page": "yyy", //当前页 "records": "zzz", //本次查询的记录数 "rows" : [ {"id" :"1", "name" : "xxxx", "addr" : "xxxx", ...}, {"id" :"2", "name" : "xxxx", "addr" : "xxxx", ...}, ... ] } 所以我还为服务器端的返回数据定义了一个类: public class JQGridResponse { private int total; //total pages private int page; //current page private int records; //total records private ArrayList<Object> rows; ... } customerService.search(searchInfo)返回的就是这样一个类。service的代码如下: 其中计算了总页数,当前页,记录数,同时通过相应的setter方法进行赋值。 @Override @Transactional public JQGridResponse search(CustomerSearchInfo searchInfo) { JQGridResponse response = new JQGridResponse(); int count = baseInfoDao.count(searchInfo); double dCount = (double)count; double dRows = (double)searchInfo.getRows(); int total = (int)Math.ceil(dCount / dRows); //total page response.setTotal(total); int curPage = Math.min(total, searchInfo.getPage()); //current page response.setPage(curPage); searchInfo.setPage(curPage); //这是为了在dao中查询用的 ArrayList<Object> customers = new ArrayList<Object>(); //检索符合条件的数据(略) ... response.setRecords(customers.size()); response.setRows(customers); return response; } 在dao层,就是利用hibernate的setFirstResult和setMaxResults读取当前页的记录,需要注意 的是,对于符合条件的总记录数需要使用Projections.rowCount()获得,所以我做了两个方法 search和count,前者是取得本次查询当前页的数据,后者是本次查询的记录总数,这两者的 查询条件是一样的,但前者需要加上排序信息,并且指定仅返回当前页的记录数,后者仅获取 记录条数(其实就是select count(*)),代码片段如下: public class CustomerBaseInfoDaoImpl implements CustomerBaseInfoDao { private SessionFactory sessionFactory; public void setSessionFactory(SessionFactory sessionFactory) { this.sessionFactory = sessionFactory; } ... @Override public List<CustomerBaseInfo> search(CustomerSearchInfo searchInfo) { Session session = sessionFactory.getCurrentSession(); Criteria c = getSearchCriteria(session, searchInfo); //排序 String sortIdx = searchInfo.getSidx(); if (sortIdx.length() > 0) { if ("asc".equalsIgnoreCase(searchInfo.getSord())) { c.addOrder(Order.asc(sortIdx)); } else { c.addOrder(Order.desc(sortIdx)); } } c.setFirstResult((searchInfo.getPage() - 1) * searchInfo.getRows()); c.setMaxResults(searchInfo.getRows()); return (List<CustomerBaseInfo>)c.list(); } @Override public int count(CustomerSearchInfo searchInfo) { Session session = sessionFactory.getCurrentSession(); Criteria c = getSearchCriteria(session, searchInfo); c.setProjection(Projections.rowCount()); return ((Integer)c.list().get(0)).intValue(); } private Criteria getSearchCriteria(Session session, CustomerSearchInfo searchInfo) { Criteria c = session.createCriteria(CustomerBaseInfo.class); //检索条件 String name = searchInfo.getName(); if (name != null && name.trim().length() > 0) { c.add(Restrictions.ilike("name", "%" + name + "%")); } String addr = searchInfo.getAddr(); if (addr != null && addr.trim().length() > 0) { c.add(Restrictions.ilike("addr", "%" + addr + "%")); } String dandang = searchInfo.getDandang(); if (dandang != null && dandang.trim().length() > 0) { c.add(Restrictions.ilike("dandang", "%" + dandang + "%")); } return c; } } 声明:ITeye文章版权属于作者,受法律保护。没有作者书面许可不得转载。
推荐链接
|
|
返回顶楼 | |
发表时间:2011-07-25
怎么没人顶啊,
|
|
返回顶楼 | |
发表时间:2011-08-01
顶楼主,求demo源码,楼主能提供下载么...
|
|
返回顶楼 | |
发表时间:2011-08-02
最后修改:2011-08-02
dong706gmail 写道 顶楼主,求demo源码,楼主能提供下载么...
源码在这里 |
|
返回顶楼 | |