SSH框架中使用jquery-ingrid实现翻页+筛选

最近项目中有一个地方需要将数据进行列表展示,并提供筛选功能,虽说不是很复杂的功能,但是在使用jquery-ingird插件实现时,还是费了一番周折的,在此进行记录下实现过程,并作为自己在博客园的第一篇博客。

首先说一下ingrid插件,ingrid插件是一个很轻量级的插件,可以帮你快速美观的实现表格的翻页、拉伸等功能,关于ingrid,感觉网上并没有太多的资料,只找到一个比较权威的Demo:http://reconstrukt.com/ingrid/src/example1.html,幸好插件不是很复杂,源码比较好理解,因此在修改上比较方便。本项目使用的是jquery.ingrid-0.9.9-min.js插件。

在最开始先展示一下实现后的样子:

初始界面是这样子的:

在下面可以进行翻页:

上面可以进行筛选:

现在说明一下进行开发的过程。

首先分析后台逻辑。

在后台中,可以用action中的一个函数来实现展示、翻页和筛选这三个功能,核心代码为:

 1 //首先获取所有的数据
 2 List<Channel> channelList = service.getAllChannelList();
 3 //......
 4 //如果需要筛选,则进行筛选
 5 Iterator<Channel> iterator = channelList.iterator();
 6         while (iterator.hasNext()) {
 7             Channel channel = iterator.next();
 8             Model parentModel = service.getParentModel(channel.getId());
 9             if (model.getId() != 0 && !model.equals(parentModel)) {
10                 //针对型号进行筛选
11                 iterator.remove();
12                 continue;
13             }
14             //...
15             modelList.add(parentModel);
16             //...
17         }
18 //记录住最大长度,并进行翻页。
19 maxCount = modelList.size();
20 modelList = commonService.getBetween((page - 1) * countPerPage, countPerPage, modelList);
21 //...

整体逻辑比较简单,采用的是软筛选和翻页的方式:首先从数据库中取出所有记录,然后看是否需要筛选(判断model的id是否为0),如果需要筛选的话,进行筛选,筛选完毕后,再进行分页。

然后分析前台页面。

前台页面在初始展示时,使用struts标签即可。

 1 <div>
 2     <table id="channelListTable">
 3         <thead>
 4         <tr>
 5             <th>序号</th>
 6             <th><select id="modelSelect" class="STYLE10" onchange="mpsChange()">
 7                 <option value="0">型号名称</option>
 8                 <s:iterator value="totalModels" id="ite1">
 9                     <option value=‘<s:property value="id"/>‘>
10                         <s:property value="name"/>
11                     </option>
12                 </s:iterator>
13             </select></th>
14             <th><select id="periodSelect" class="STYLE10" onchange="mpsChange()">
15                 <option value="0">阶段名称</option>
16                 <s:iterator value="totalPeriods" id="ite2">
17                     <option value=‘<s:property value="id"/>‘>
18                         <s:property value="name"/>
19                     </option>
20                 </s:iterator>
21             </select></th>
22             <th><select id="statusSelect" class="STYLE10" onchange="mpsChange()">
23                 <option value="-1">状态名称</option>
24                 <s:iterator value="totalStatuss" id="ite3">
25                     <option value=‘<s:property value="id"/>‘>
26                         <s:property value="name"/>
27                     </option>
28                 </s:iterator>
29             </select></th>
30             <th>通道名称</th>
31             <th>基本操作</th>
32         </tr>
33         </thead>
34         <tbody id="channelListTbody">
35         <s:set name="startNumber" value="(#request.page-1)*#request.countPerPage"></s:set>
36         <s:iterator value="modelList" status="status">
37             <tr>
38                 <td height="20" bgcolor="#FFFFFF" class="STYLE6">
39                     <div align="center">
40                         <span class="STYLE19"><s:property value="#status.count + #startNumber"/> </span>
41                     </div>
42                 </td>
43                 <td height="20" bgcolor="#FFFFFF" class="STYLE19">
44                     <div align="center">
45                         <s:property value="modelList[#status.count - 1].name"/>
46                     </div>
47                 </td>
48                 <td height="20" bgcolor="#FFFFFF" class="STYLE19">
49                     <div align="center">
50                         <s:property value="periodList[#status.count - 1].name"/>
51                     </div>
52                 </td>
53                 <td height="20" bgcolor="#FFFFFF" class="STYLE19">
54                     <div align="center">
55                         <s:property value="statusList[#status.count - 1].name"/>
56                     </div>
57                 </td>
58                 <td height="20" bgcolor="#FFFFFF" class="STYLE19">
59                     <div align="center">
60                         <s:property value="environment0List[#status.count - 1].name"/>
61                     </div>
62                 </td>
63                 <td height="20" bgcolor="#FFFFFF">
64                     <div align="center"
65                          class="STYLE21">
66                         <a href="javascript:edit()">编辑</a>&nbsp;|&nbsp;<a
67                             href="javascript:deleteEnvironment0()">删除</a>
68                     </div>
69                 </td>
70             </tr>
71         </s:iterator>
72         <s:hidden name="totalRecords" value="%{#request.maxCount}"></s:hidden>
73         </tbody>
74     </table>
75     <s:hidden name="recordsPerPage" value="%{#request.countPerPage}"></s:hidden>
76 </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>&nbsp;|&nbsp;<a
                    href="javascript:deleteEnvironment0()">删除</a>
            </div>
        </td>
    </tr>
</s:iterator>
<s:hidden name="totalRecords" value="%{#request.maxCount}"></s:hidden>
</tbody>

最后开始分析js代码。

js代码中需要分析的有这么几个函数。

1 使用ingrid修饰。

 1 //对表格进行初始话,使用ingrid控件
 2 function ingridTable(params) {
 3     var recordsPerPageValue = $("#recordsPerPage").val();
 4     var totalRecordsValue = $("#totalRecords").val();
 5     var pageWidth = document.body.offsetWidth - 20;
 6     $("#channelListTable").ingrid({
 7         url: ‘queryListChannel.action‘,
 8         //先设置成全部不能排序再说
 9         unsortableCols: [ 0, 1, 2, 3, 4, 5 ],
10         colWidths: [ pageWidth * 0.05, pageWidth * 0.2, pageWidth * 0.15, pageWidth * 0.2, pageWidth * 0.2, pageWidth * 0.2 ],
11         recordsPerPage: recordsPerPageValue,
12         totalRecords: totalRecordsValue,
13         extraParams: params
14     });
15 }

这个函数比较简单,直接调用ingrid方法即可。在页面加载成功时,只用无参调用此方法即可:ingridTable()。params这个参数在进行筛选时会用到,后面会进行讲解。

2 筛选函数。

 1 //进行筛选
 2 function mpsChange() {
 3     var modelId = $("#modelSelect").val();
 4     var periodId = $("#periodSelect").val();
 5     var statusId = $("#statusSelect").val();
 6     var params = {
 7         "model.id": modelId,
 8         "period.id": periodId,
 9         "status.id": statusId
10     };
11     $.ajax({
12         url: "queryListChannel.action",
13         data: params,
14         type: "post",
15         dataType: "text",
16         success: function (result) {
17             $("#channelListTbody").replaceWith(result);
18             ingridTable(params);
19         }
20     });
21 }

这个函数有2点需要注意:

1 获取页面之后,应该使用replaceWith函数而非html函数。

2 获取完页面后需要再调用一次ingridTable函数,并将筛选的参数传递给该函数,下次翻页中则会用到。

就这样,整个翻页加筛选流程就结束了!

是这样吗?

让我们再看一下此时的情况。

初始页面如下:

然后进行翻页:

然后此时我们进行筛选:

发现问题了吧???

好吧,放大看看。。

    

看出来了吧?从翻页结果中,我们可以看出型号为LL的只有5组数据,最多不过2页,但是我们在筛选完之后,会发现竟然还有9组数据,还有3页。

这时候我们去“审查元素”,

发现什么嘛,ingrid竟然再底部拼出来一个翻页条,我还一直以为它是属于底部的一部分呢。因此我们虽然在筛选后替换的tbody,但是最下面那条翻页条确实没有刷新的。

发现问题了就比较好解决了(呵呵),将ingrid源代码中的对应地方修改为:

 1  //孙庚泽,修改于2014年12月10日 15:19:02,保证了table的id不被变动,下次还可以获取,但是也就取消掉该控件对多个表使用的功能。
 2         //var g_id = cfg.ingridIDPrefix + ‘_‘ + jQuery(this).attr(‘id‘) + ‘_‘ + tblIter;
 3         var g_id = jQuery(this).attr(‘id‘);
 4         g.attr(‘id‘, g_id);
 5         var ok = jQuery("<div />").append(g[0]);
 6         var pageBarId = g_id + ‘_‘ + cfg.pageBarIdSuffix;
 7         var isFirst = !$(‘#‘ + pageBarId);
 8         if (cfg.paging && cfg.p_id == null) {
 9             if (!isFirst) {
10                 $(‘#‘ + pageBarId).remove();
11             }
12             p.attr(‘id‘, pageBarId);
13             ok.append(p);
14         }

还有:

1 var isFirst = !hClass || hClass.indexOf(cfg.headerClass) == -1;//孙庚泽,修改于2014年12月10日 15:19:02,防止出现多次表头。
2     if (isFirst) {
3         h.height(cfg.headerHeight).addClass(cfg.headerClass).height(cfg.headerHeight).extend({cols: cols});
4       //.....
5     }

ok,这样就可以了!

注:ingrid控件貌似有一个小Bug,当进行翻页时,访问翻页连接的次数会随着翻页次数的增多呈指数级上涨,即在第一页点击下一页,会访问一次page=2的连接,然后此时再点击下一页,则会访问2次page=3的连接,此时如果再点击下一页,则会访问4次page=4的连接,以此类推。这样会给服务器带来很大的负荷。针对这种情况,将如下代码注释掉即可。

if (cfg.paging) {
    pv.updateViewInfo(totr, data.page);
    pb3.click(nextPage);
}
时间: 2024-11-03 03:28:33

SSH框架中使用jquery-ingrid实现翻页+筛选的相关文章

spring在SSH框架中的作用

从网上了搜了下sring 在ssh中起的作用,在百度知道上看到下面的回答,觉得简单移动,记录下来备查,原文地址: http://zhidao.baidu.com/link?url=JiONrax-Flkpi5hqs_g1HQOrMm1Dk8U1WT88l5T0Gg01bm3M8fMcjUCpqastVxQTd63gxUl5NLyHUQPdq6E-OK 在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行

在SSH框架中,如何得到POST请求的URL和参数列表

在做项目的API通知接口的时候,发现在SSH框架中无法获取到对方服务器发来的异步通知信息.最后排查到的原因可能是struts2对HttpServletRequest进行了二次处理,那么该如何拿到post的请求数据呢,方法很多,下面只给出一种方式. 在servlet中GET请求可以通过HttpServletRequest的getRequestURL方法和getQueryString()得到完 整的请求路径和请求所有参数列表, POST的需要getParameterMap()方法遍历得到,不论GET

ssh框架中.xml文件小技巧分离xml

struts.xml文件 struts.xml文件里的action可以分离出来,如: <!-- 预警信息监测 --> <include file="config/struts/warningInformAtion-struts.xml"></include> 注: include是放在</struts>标签的前面 在src下面新建 package 名为:config.struts,再新建xml文件为warningInformAtion-s

在SSH框架中使用Spring的好处(转)

以下是我总结下今天笔试中SSh中的总结: 在SSH框架中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句.Struts是用来做应用层的,他它负责调用业务逻辑serivce层.所以SSH框架的流程大致是:Jsp页面----Struts------Service(业务逻辑处理类)---Hibernate(左到右)    struts负责控制Service(业务逻辑处理类),从而控制了

SSH框架中hibernate 出现 user is not mapped 问题

SSH框架中hibernate 出现 user is not mapped 问题 在做SSH框架整合时,在进行DAO操作时.这里就只调用了chekUser()方法.运行时报  user is not mapped 错误 :  chekUser()方法如下:  public boolean chekUser(User user){           String hql="from user u where u.id=? and u.name=?";        Query quer

SSH框架中session问题

使用SSH框架做项目的时候避免不了使用session,有时候使用session会很方便,但是有时候也是个很麻烦的事情,我今天就遇到一个这样的情况,搞的我很不爽,还是记录一下吧. 首先是登录的时候,如果用户名密码正确就把该用户的信息存到session中去, //登录成功后将用户信息保存到session中 SessionUtils.setSysUserToSession(request, sysUser); /** * 保存当前登录用户的信息到session中去 * @param request *

SSH框架中Spring框架搭建的初步理解(一)

接手基于SSH框架的web项目已经一个月有余了.早有听说javaweb三大框架,第一次接触,先来说下感受. 我感觉SSH框架最明显的优点有如下: 采用MVC模式,层次结构清晰,使程序员只需关注业务逻辑的实现. 通过配置文件,就可以掌握整个系统各个部分之间的关系. 通过AOP,可以实现事务管理和日志管理. 其中Spring框架能使你通过最简单可行的方法来解决问题,这是非常高效的.但是它的搭建也略微复杂,尤其是对于我这样的新手来说,所以开此篇记录一下SPring框架的搭建: 创建web项目,导入SS

SSH框架中spring的原理

在ssh项目中,是有明确分工的,spring的作用就相当于将struts和hibernate连接起来,是将两个没有关系的框架的特性,方法,action都放在spring的配置文件中使他们建立关系.取他门各自所长.而这些做法他们自己不知道,他们是听命于spring调度的,他的的任务只是做好自己的事情.    这样做的好处就是任务结构分明,struts只管理显示与做什么,hibernate只关心怎么做,而spring就相当于领导,所以一切的类都要交给spring的工厂创建,这是一种良好的开发模式,体

在SSH框架中使用Spring的好处

在SSH框假中spring充当了管理容器的角色.我们都知道Hibernate用来做持久层,因为它将JDBC做了一个良好的封装,程序员在与数据库进行交互时可以不用书写大量的SQL语句.Struts是用来做应用层的,他它负责调用业务逻辑serivce层.所以SSH框架的流程大致是:Jsp页面----Struts------Service(业务逻辑处理类)---Hibernate(左到右)   struts负责控制Service(业务逻辑处理类),从而控制了Service的生命周期,这样层与层之间的依