freemaker分页备忘
思路:定义一个freemaker宏,接收参数。然后在freemaker页面上import这个文件,把参数传进来在server端渲染。
分页标签:pager.ftl
<#-- 自定义的分页指令。 属性说明: pageNo 当前页号(int类型) pageSize 每页要显示的记录数(int类型) toURL 点击分页标签时要跳转到的目标URL(string类型) pageCount 总页码数(int类型) method 查询方法的类型(GET/POST) recordCount 总记录数(int类型) 使用方式: <#if recordCount??> <#import "/pager.ftl" as p> <@p.pager pageNo=1 pageSize=10 recordCount=13 pageCount=2 toURL="xxxxx/queryXXX" method="get"/> </#if> --> <#macro pager pageNo pageSize recordCount pageCount toURL method> <#-- 定义局部变量pageCount保存总页数 --> <#if recordCount==0><#return/></#if> <#-- 输出分页样式 --> <style type="text/css"> .pagination {padding: 5px;float:right;font-size:12px;} .pagination a, .pagination a:link, .pagination a:visited {padding:2px 5px;margin:2px;border:1px solid #aaaadd;text-decoration:none;color:#006699;} .pagination a:hover, .pagination a:active {border: 1px solid #ff0000;color: #000;text-decoration: none;} .pagination span.current {padding: 2px 5px;margin: 2px;border: 1px solid #ff0000;font-weight: bold;background-color: #ff0000;color: #FFF;} .pagination span.disabled {padding: 2px 5px;margin: 2px;border: 1px solid #eee; color: #ddd;} </style> <#-- 页号越界处理 --> <#if (pageNo > pageCount)> <#assign pageNo=pageCount> </#if> <#if (pageNo < 1)> <#assign pageNo=1> </#if> <#-- 输出分页表单 --> <div class="pagination"> <form method="${method}" action="" name="qPagerForm"> <#-- 把请求中的所有参数当作隐藏表单域(无法解决一个参数对应多个值的情况) --> <#list RequestParameters?keys as key> <#if (key!="page" && RequestParameters[key]??)> <input type="hidden" name="${key}" value="${RequestParameters[key]}"/> </#if> </#list> <input type="hidden" name="page" value="${pageNo}"/> <span>共${recordCount}条记录,</span> <span>当前第<b>${pageNo}/${pageCount}</b>页</span> <#-- 上一页处理 --> <#if (pageNo == 1)> <span class="disabled">« 上一页</span> <#else> <a href="javascript:void(0)" onclick="turnOverPage(${pageNo - 1})">« 上一页</a> </#if> <#-- 如果前面页数过多,显示... --> <#assign start=1> <#if (pageNo > 4)> <#assign start=(pageNo - 1)> <a href="javascript:void(0)" onclick="turnOverPage(1)">1</a> <a href="javascript:void(0)" onclick="turnOverPage(2)">2</a>… </#if> <#-- 显示当前页号和它附近的页号 --> <#assign end=(pageNo + 1)> <#if (end > pageCount)> <#assign end=pageCount> </#if> <#list start..end as i> <#if (pageNo==i)> <span class="current">${i}</span> <#else> <a href="javascript:void(0)" onclick="turnOverPage(${i})">${i}</a> </#if> </#list> <#-- 如果后面页数过多,显示... --> <#if (end < pageCount - 2)> … </#if> <#if (end < pageCount - 1)> <a href="javascript:void(0)" onclick="turnOverPage(${pageCount - 1})">${pageCount-1}</a> </#if> <#if (end < pageCount)> <a href="javascript:void(0)" onclick="turnOverPage(${pageCount})">${pageCount}</a> </#if> <#-- 下一页处理 --> <#if (pageNo == pageCount)> <span class="disabled">下一页 »</span> <#else> <a href="javascript:void(0)" onclick="turnOverPage(${pageNo + 1})">下一页 »</a> </#if> </form> <script language="javascript"> function turnOverPage(no){ var qForm=document.qPagerForm; if(no>${pageCount}){no=${pageCount};} if(no<1){no=1;} qForm.page.value=no; qForm.action="${toURL}"; qForm.submit(); } </script> </div> </#macro>
使用示例:user.ftl
在这个freemaker页面上引入分页标签,后台查询一个pageBean,pageBean里面有页码信息、pageBean.result放着用户列表。
<html> <head> <title>FreeMarker自定义分页标签使用示例</title> <meta http-equiv="content-type" content="text/html; charset=utf-8" /> </head> <body> 你好, <b>${message}</b><br/> <hr/><br/> <table width="100%" border="1"> <tr> <td width="50%">用户代码</td> <td width="50%">用户姓名</td> </tr> <#list pageBean.result as eachUser> <tr> <td width="50%"><#if eachUser.idNumber ??>${eachUser.idNumber}</#if></td> <td width="50%"><#if eachUser.nickName ??>${eachUser.nickName}</#if></td> </tr> </#list> </table> <div id="pager"> <#import "/pager.ftl" as p> <!--#if recordCount??--> <@p.pager pageNo=pageBean.pageNo pageSize=pageBean.pageSize recordCount=pageBean.totalCount pageCount=pageBean.maxPage toURL="xxxx/queryUser" method="get"/> <!--/#if--> </div> </body> </html>
pageBean对象:
1 package com.hjb.platform.base.model; 2 3 import java.util.HashMap; 4 import java.util.List; 5 import java.util.Map; 6 7 public class Page { 8 //页面大小 9 private Integer pageSize; 10 //当前页码 11 private Integer pageNo; 12 //查询开始条数 13 private Integer minRows; 14 //查询截至条数 15 private Integer maxRows; 16 //最大页码数 17 private Integer maxPage; 18 //总记录数 19 private int totalCount; 20 //所有记录 21 private List<?> result; 22 //页面上的查询条件 23 private Map<String,Object> parm = new HashMap<String,Object>(); 24 25 public Page() { 26 } 27 28 public void calculateRows() { 29 if (pageSize == null || pageSize == 0) { 30 this.pageSize = 10; 31 } 32 if (pageNo == null || pageNo == 0) { 33 this.pageNo = 1; 34 } 35 this.minRows = (pageNo - 1) * pageSize; 36 this.maxRows = pageNo * pageSize; 37 if (this.totalCount % this.pageSize == 0) { 38 this.maxPage = this.totalCount / this.pageSize; 39 } else { 40 this.maxPage = (this.totalCount / this.pageSize) + 1; 41 } 42 43 } 44 45 public Map<String,Object> getAllParms(){ 46 this.parm.put("minRows", minRows); 47 this.parm.put("maxRows", maxRows); 48 return this.parm; 49 } 50 51 //getter setter 52 53 }
前台表单参数都放到parm这个Map中,在service中调用calculateRows()方法,会自动计算本次查询的开始、截至条数。然后把这个pageBean.getAllParms()这个map传给mybatis去查询分页。查到一个list,把list塞到pageBean的result里。然后把这个查询到的pageBean放到modelAndView中,view名字就是user.ftl,最后controller返回就行。
当然,我们项目中最后没有采用这种方法。主要是使用起来比较麻烦。
最终我们使用了javascript的分页标签。(如smartpaginator.js等一些优秀的分页标签很容易使用,当然,如果前端功力深厚可以自己写一个js的分页标签)