SSH框架中使用jquery-ingrid实现翻页+筛选
2014-12-22 22:15
302 查看
最近项目中有一个地方需要将数据进行列表展示,并提供筛选功能,虽说不是很复杂的功能,但是在使用jquery-ingird插件实现时,还是费了一番周折的,在此进行记录下实现过程,并作为自己在博客园的第一篇博客。
首先说一下ingrid插件,ingrid插件是一个很轻量级的插件,可以帮你快速美观的实现表格的翻页、拉伸等功能,关于ingrid,感觉网上并没有太多的资料,只找到一个比较权威的Demo:http://reconstrukt.com/ingrid/src/example1.html,幸好插件不是很复杂,源码比较好理解,因此在修改上比较方便。本项目使用的是jquery.ingrid-0.9.9-min.js插件。
在最开始先展示一下实现后的样子:
初始界面是这样子的:
在下面可以进行翻页:
上面可以进行筛选:
现在说明一下进行开发的过程。
首先分析后台逻辑。
在后台中,可以用action中的一个函数来实现展示、翻页和筛选这三个功能,核心代码为:
整体逻辑比较简单,采用的是软筛选和翻页的方式:首先从数据库中取出所有记录,然后看是否需要筛选(判断model的id是否为0),如果需要筛选的话,进行筛选,筛选完毕后,再进行分页。
然后分析前台页面。
前台页面在初始展示时,使用struts标签即可。
这里需要注意的有2点:
1 对三个下拉列表change事件的绑定,并没有使用javasript动态绑定,而是直接采用onchange,这是因为当使用ingrid将表格修饰之后,每个单元格都变成unselectable="on"了,绑定的事件就无效了。
2 总记录条数(totalRecords)和每页记录数(recordsPerPage)这两个hidden,一个位于tbody里面,一个位于tbody外面,这是因为tbody中的内容经常(翻页或者筛选时)要变动,希望tbody中的内容越少越好(可以减小数据传输量),因此将在程序运行时基本不变的每页记录数放在了tbody外,而总记录数是有可能变化的(进行筛选的情况下),只能放在tbody中。
除了需要初始页面之外,还需要一个“小”页面,用于传递每次更新的数据。通过读取ingrid源码可知,ingrid在获取到更新后的页面后,是通过获取其中的tbody标签来进行页面刷新的,因此小页面只取初始页面中tbody的部分即可。
最后开始分析js代码。
js代码中需要分析的有这么几个函数。
1 使用ingrid修饰。
这个函数比较简单,直接调用ingrid方法即可。在页面加载成功时,只用无参调用此方法即可:ingridTable()。params这个参数在进行筛选时会用到,后面会进行讲解。
2 筛选函数。
这个函数有2点需要注意:
1 获取页面之后,应该使用replaceWith函数而非html函数。
2 获取完页面后需要再调用一次ingridTable函数,并将筛选的参数传递给该函数,下次翻页中则会用到。
就这样,整个翻页加筛选流程就结束了!
是这样吗?
让我们再看一下此时的情况。
初始页面如下:
然后进行翻页:
然后此时我们进行筛选:
发现问题了吧???
好吧,放大看看。。
看出来了吧?从翻页结果中,我们可以看出型号为LL的只有5组数据,最多不过2页,但是我们在筛选完之后,会发现竟然还有9组数据,还有3页。
这时候我们去“审查元素”,
发现什么嘛,ingrid竟然再底部拼出来一个翻页条,我还一直以为它是属于底部的一部分呢。因此我们虽然在筛选后替换的tbody,但是最下面那条翻页条确实没有刷新的。
发现问题了就比较好解决了(呵呵),将ingrid源代码中的对应地方修改为:
还有:
ok,这样就可以了!
注:ingrid控件貌似有一个小Bug,当进行翻页时,访问翻页连接的次数会随着翻页次数的增多呈指数级上涨,即在第一页点击下一页,会访问一次page=2的连接,然后此时再点击下一页,则会访问2次page=3的连接,此时如果再点击下一页,则会访问4次page=4的连接,以此类推。这样会给服务器带来很大的负荷。针对这种情况,将如下代码注释掉即可。
首先说一下ingrid插件,ingrid插件是一个很轻量级的插件,可以帮你快速美观的实现表格的翻页、拉伸等功能,关于ingrid,感觉网上并没有太多的资料,只找到一个比较权威的Demo:http://reconstrukt.com/ingrid/src/example1.html,幸好插件不是很复杂,源码比较好理解,因此在修改上比较方便。本项目使用的是jquery.ingrid-0.9.9-min.js插件。
在最开始先展示一下实现后的样子:
初始界面是这样子的:
在下面可以进行翻页:
上面可以进行筛选:
现在说明一下进行开发的过程。
首先分析后台逻辑。
在后台中,可以用action中的一个函数来实现展示、翻页和筛选这三个功能,核心代码为:
//首先获取所有的数据 List<Channel> channelList = service.getAllChannelList(); //...... //如果需要筛选,则进行筛选 Iterator<Channel> iterator = channelList.iterator(); while (iterator.hasNext()) { Channel channel = iterator.next(); Model parentModel = service.getParentModel(channel.getId()); if (model.getId() != 0 && !model.equals(parentModel)) { //针对型号进行筛选 iterator.remove(); continue; } //... modelList.add(parentModel); //... } //记录住最大长度,并进行翻页。 maxCount = modelList.size(); modelList = commonService.getBetween((page - 1) * countPerPage, countPerPage, modelList); //...
整体逻辑比较简单,采用的是软筛选和翻页的方式:首先从数据库中取出所有记录,然后看是否需要筛选(判断model的id是否为0),如果需要筛选的话,进行筛选,筛选完毕后,再进行分页。
然后分析前台页面。
前台页面在初始展示时,使用struts标签即可。
<div> <table id="channelListTable"> <thead> <tr> <th>序号</th> <th><select id="modelSelect" class="STYLE10" onchange="mpsChange()"> <option value="0">型号名称</option> <s:iterator value="totalModels" id="ite1"> <option value='<s:property value="id"/>'> <s:property value="name"/> </option> </s:iterator> </select></th> <th><select id="periodSelect" class="STYLE10" onchange="mpsChange()"> <option value="0">阶段名称</option> <s:iterator value="totalPeriods" id="ite2"> <option value='<s:property value="id"/>'> <s:property value="name"/> </option> </s:iterator> </select></th> <th><select id="statusSelect" class="STYLE10" onchange="mpsChange()"> <option value="-1">状态名称</option> <s:iterator value="totalStatuss" id="ite3"> <option value='<s:property value="id"/>'> <s:property value="name"/> </option> </s:iterator> </select></th> <th>通道名称</th> <th>基本操作</th> </tr> </thead> <tbody id="channelListTbody"> <s:set name="startNumber" value="(#request.page-1)*#request.countPerPage"></s:set> <s:iterator value="modelList" status="status"> <tr> <td height="20" bgcolor="#FFFFFF" class="STYLE6"> <div align="center"> <span class="STYLE19"><s:property value="#status.count + #startNumber"/> </span> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="modelList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="periodList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="statusList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="environment0List[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF"> <div align="center" class="STYLE21"> <a href="javascript:edit()">编辑</a> | <a href="javascript:deleteEnvironment0()">删除</a> </div> </td> </tr> </s:iterator> <s:hidden name="totalRecords" value="%{#request.maxCount}"></s:hidden> </tbody> </table> <s:hidden name="recordsPerPage" value="%{#request.countPerPage}"></s:hidden> </div>
这里需要注意的有2点:
1 对三个下拉列表change事件的绑定,并没有使用javasript动态绑定,而是直接采用onchange,这是因为当使用ingrid将表格修饰之后,每个单元格都变成unselectable="on"了,绑定的事件就无效了。
2 总记录条数(totalRecords)和每页记录数(recordsPerPage)这两个hidden,一个位于tbody里面,一个位于tbody外面,这是因为tbody中的内容经常(翻页或者筛选时)要变动,希望tbody中的内容越少越好(可以减小数据传输量),因此将在程序运行时基本不变的每页记录数放在了tbody外,而总记录数是有可能变化的(进行筛选的情况下),只能放在tbody中。
除了需要初始页面之外,还需要一个“小”页面,用于传递每次更新的数据。通过读取ingrid源码可知,ingrid在获取到更新后的页面后,是通过获取其中的tbody标签来进行页面刷新的,因此小页面只取初始页面中tbody的部分即可。
<tbody id="channelListTbody"> <s:set name="startNumber" value="(#request.page-1)*#request.countPerPage"></s:set> <s:iterator value="modelList" status="status"> <tr> <td height="20" bgcolor="#FFFFFF" class="STYLE6"> <div align="center"> <span class="STYLE19"><s:property value="#status.count + #startNumber"/> </span> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="modelList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="periodList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="statusList[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF" class="STYLE19"> <div align="center"> <s:property value="environment0List[#status.count - 1].name"/> </div> </td> <td height="20" bgcolor="#FFFFFF"> <div align="center" class="STYLE21"> <a href="javascript:edit()">编辑</a> | <a href="javascript:deleteEnvironment0()">删除</a> </div> </td> </tr> </s:iterator> <s:hidden name="totalRecords" value="%{#request.maxCount}"></s:hidden> </tbody>
最后开始分析js代码。
js代码中需要分析的有这么几个函数。
1 使用ingrid修饰。
//对表格进行初始话,使用ingrid控件 function ingridTable(params) { var recordsPerPageValue = $("#recordsPerPage").val(); var totalRecordsValue = $("#totalRecords").val(); var pageWidth = document.body.offsetWidth - 20; $("#channelListTable").ingrid({ url: 'queryListChannel.action', //先设置成全部不能排序再说 unsortableCols: [ 0, 1, 2, 3, 4, 5 ], colWidths: [ pageWidth * 0.05, pageWidth * 0.2, pageWidth * 0.15, pageWidth * 0.2, pageWidth * 0.2, pageWidth * 0.2 ], recordsPerPage: recordsPerPageValue, totalRecords: totalRecordsValue, extraParams: params }); }
这个函数比较简单,直接调用ingrid方法即可。在页面加载成功时,只用无参调用此方法即可:ingridTable()。params这个参数在进行筛选时会用到,后面会进行讲解。
2 筛选函数。
//进行筛选 function mpsChange() { var modelId = $("#modelSelect").val(); var periodId = $("#periodSelect").val(); var statusId = $("#statusSelect").val(); var params = { "model.id": modelId, "period.id": periodId, "status.id": statusId }; $.ajax({ url: "queryListChannel.action", data: params, type: "post", dataType: "text", success: function (result) { $("#channelListTbody").replaceWith(result); ingridTable(params); } }); }
这个函数有2点需要注意:
1 获取页面之后,应该使用replaceWith函数而非html函数。
2 获取完页面后需要再调用一次ingridTable函数,并将筛选的参数传递给该函数,下次翻页中则会用到。
就这样,整个翻页加筛选流程就结束了!
是这样吗?
让我们再看一下此时的情况。
初始页面如下:
然后进行翻页:
然后此时我们进行筛选:
发现问题了吧???
好吧,放大看看。。
看出来了吧?从翻页结果中,我们可以看出型号为LL的只有5组数据,最多不过2页,但是我们在筛选完之后,会发现竟然还有9组数据,还有3页。
这时候我们去“审查元素”,
发现什么嘛,ingrid竟然再底部拼出来一个翻页条,我还一直以为它是属于底部的一部分呢。因此我们虽然在筛选后替换的tbody,但是最下面那条翻页条确实没有刷新的。
发现问题了就比较好解决了(呵呵),将ingrid源代码中的对应地方修改为:
//孙庚泽,修改于2014年12月10日 15:19:02,保证了table的id不被变动,下次还可以获取,但是也就取消掉该控件对多个表使用的功能。 //var g_id = cfg.ingridIDPrefix + '_' + jQuery(this).attr('id') + '_' + tblIter; var g_id = jQuery(this).attr('id'); g.attr('id', g_id); var ok = jQuery("<div />").append(g[0]); var pageBarId = g_id + '_' + cfg.pageBarIdSuffix; var isFirst = !$('#' + pageBarId); if (cfg.paging && cfg.p_id == null) { if (!isFirst) { $('#' + pageBarId).remove(); } p.attr('id', pageBarId); ok.append(p); }
还有:
var isFirst = !hClass || hClass.indexOf(cfg.headerClass) == -1;//孙庚泽,修改于2014年12月10日 15:19:02,防止出现多次表头。 if (isFirst) { h.height(cfg.headerHeight).addClass(cfg.headerClass).height(cfg.headerHeight).extend({cols: cols}); //..... }
ok,这样就可以了!
注:ingrid控件貌似有一个小Bug,当进行翻页时,访问翻页连接的次数会随着翻页次数的增多呈指数级上涨,即在第一页点击下一页,会访问一次page=2的连接,然后此时再点击下一页,则会访问2次page=3的连接,此时如果再点击下一页,则会访问4次page=4的连接,以此类推。这样会给服务器带来很大的负荷。针对这种情况,将如下代码注释掉即可。
if (cfg.paging) { pv.updateViewInfo(totr, data.page); pb3.click(nextPage); }
相关文章推荐
- 使用pager-taglib插件实现SSH框架的分页显示功能,只翻页三出错
- C#使用WebService结合jQuery实现无刷新翻页的方法
- 使用jQuery加DIV实现可以动态添加的金字塔结构
- JQuery.js学习(1)使用JQuery实现全选和反选
- jQuery教程(九)使用java script(jQuery)实现圆角边框
- 使用ASP.NET AJAX 和JQuery一起解决翻页选择的问题
- 使用jQuery进行客户端无刷新的翻页且可以每页显示记录条数
- 使用JQuery快速实现Tab的AJAX动态载入
- 在asp.net中使用JQuery的SlideViewer插件实现图片的滚动效果
- Asp.net使用jQuery实现数据绑定与分页
- 在rails中使用jquery实现Ajax 推荐
- jquery imgareaselect 使用利用js与程序结合实现图片剪切
- struts2中使用自定义标签实现翻页功能
- 学习新事物:使用jquery+xml实现ajax简单实例
- .NET2005中使用GridView实现不刷新页面翻页
- 使用jQuery实现DIV弹出效果
- 使用JQuery.js实现全选和反选
- 使用RedControls控件RadAjaxPanel、AjaxLoadingPanel实现GridView无刷新翻页和排序
- 使用Jquery+CSS实现的表格隔行凸显和当前行高亮效果
- jQuery教程(十二)使用不苛刻的java script代码实现多文件上传