JSP自定义标签开发(八)—— xx.tag自定义标签开发之分页标签(jquery + div +css 美化)
来源:互联网 发布:Js代码高亮 编辑:程序博客网 时间:2024/05/17 23:33
去年刚出从学校里走出来,由于大学教育理论与实际的脱节,我也不例外成了其牺牲品之一。在上一家公司的时候看到他们将分页 和 用户权限限制 这样的常用的功能封装成 标签,使用起来十分的方便。虽然实际的开发中,像我们这种刚进去的小罗罗只需要会调用就好了,但是自己的好奇心使然,总是想如果我要自己大件框架要自己实现这这些功能的封装,我要怎么办呢?所以,我必须去把它们学会。由于公司的那套框架封装的东西很多,层层叠叠的,每次去深究都看得我头昏脑胀的,其实主要还是自己以前在学校贪玩好耍,学艺不精,呵呵呵!这样反反复复的,第一年过去了,我还是没有真正的弄懂它们,真的是说来惭愧得很啦!
由于一遍一遍的看,在加上网上的资料实在少得可怜,没有哪个 好心人愿意分享一些正儿八经的正餐,通常大多是一些残羹冷炙的边角料。一遍一遍的看,再加上网上资料的搜索,终于是看懂了公司的那个分页标签的实现原理与细节。
原来的公司,用的是SSM (struts2.X + spring3.X + myBatis)的封装框架。所以那个分页标签就是实用的struts2的标签开发。xx.tld的标签类继承的是struts2 的标签类 而不是我们 通常直接看到的 TagSupport 或BodyTagSupport .标签页面的美化展现就使用 freemarker 的技术,在freemarker中使用css、jquery 那是一件多么幸福的事情啊。个人觉得这样才是所谓的mvc的开发思想嘛。类里面写逻辑,封装Pager 常用分页信息到 request 或 parameter 中去,再在 freemarker 中做 “首页” “尾页” 以及 页码数字 和 它们的样式美化的展现。到此,我想要看到的结果似乎已经看到了,所谓的分页技术我似乎就已经学会了。
然而,我是否真的学会了这个功能呢?假如,我用的不是 struts2 来做控制层又该怎么解决呢?比如现在比较流行好用的 spring mvc 也是很好的控制层啊。
随着这问题的抛出,我的思绪似乎又回到了零起点。我在网上寻寻觅觅,寻寻觅觅,可就是看不到我想要的mvc模式的分页标签功能实现。搜到的资料几乎都是在 xx.tld 对应的标签类中 既书写逻辑,又做 页码数字 与 样式的打印,一大堆的 双引号的 转义字符……,要在java类中实现 css 样式定位 与 javascript 的动作控制,那是一件多么痛苦的事情啊。简直忍无可忍。(给个例子瞧瞧)
public class PagerTag extends TagSupport { private String value = "pb";// 存放数据实体的名字 public void setValue(String value) { this.value = value; } @Override public int doStartTag() throws JspException { JspWriter out = pageContext.getOut(); String outStr = makeString(); try { out.write(outStr); } catch (IOException e) { e.printStackTrace(); } return SKIP_BODY; } private String makeString() { // 获取到存放在request中的数据实体 Object p = pageContext.getRequest().getAttribute( value); PageBean pageBean = (PageBean) pageContext.getRequest().getAttribute(value); StringBuffer sb = new StringBuffer(); if (pageBean != null && pageBean.getItems() != null && pageBean.getItems().size() > 0) { sb.append("共" + pageBean.getCurPage() + " / " + pageBean.getPageNum() + "页"); //首页 上一页 if (pageBean.getCurPage() > 1) { sb.append("<a href='?page=1'>首页</a>"); sb.append("<a href='?page=" + (pageBean.getCurPage()-1) + "'>上一页</a>"); } //循环显示中间页码,这里也可控制最大只显示多少页码 for (int i = 1; i < pageBean.getPageNum() + 1; i++) { if (i == pageBean.getCurPage()) { sb.append(" " + i + " "); } else { sb.append("<a href='?page=" + i + "'> " + i + " </a>"); } } //下一页 末页 if(pageBean.getCurPage() != pageBean.getPageNum()){ sb.append("<a href='?page=" + (pageBean.getCurPage() + 1) + "'>下一页</a>"); sb.append("<a href='?page=" + pageBean.getPageNum() + "'>末页</a>"); } } return sb.toString(); } }看着都痛苦,简直要吐血的节奏啊,反正我是忍受不了这样的开发的,而且做出来的标签展现很丑的。
在没有看到它的日子里,我的生命里暗淡无光,总以为自己再也迈不开这个坎儿了。就在我几竟绝望的时候,我在自己买的那本spring企业开发实战一书中的一个例子中得到了灵感,找到了答案。从此这个分页功能实现的难度,在我面前变得荡然无存。哈哈哈,那一刻我心里简直爆发着灿烂的原子弹是的喜悦巨浪。那种喜悦与成就干难以被抑制啊。
下面进入正题!
对于jsp自定义标签的实现,大多数人知道xx.tld这种方法,其实还有一种方法的 xx.tag 实现。即:
1.xx.tld + 标签类 来实现;
2.xx.tag 文件来实现。
这两种方式都有各自的优缺点。第一种方法中因为有java类,任何复杂的逻辑,对它而言都是小儿科;第二种方法中,因为xx.tag文件就像jsp 中的include的使用,所以在xx.tag中就可以像实用jsp那样,可以写html 、css 、jquery,所以对于任何 酷炫的前端展现对它而言都是庖丁解牛的游刃有余。
分析一下便知道,分页标签重在于前端数字展现的人性化,复杂的逻辑也是集中在前端展现的逻辑,这完全可以用jquery 来轻轻松松地搞定的嘛。所以,就我个人而言,分页标签的实现最好的方法应该是 采用 xx.tag 的方式来实现,最最重要的事情是,这种方法是通用的,他不依赖于任何框架技术(如,常用的 struts2 和 spring). 有了它,分页标签的实现从此将变得是一次幸福愉快的开发之旅;有了它,分页标签的开发才真正是 美观、简单、快速高效 的代名词。
下面进入 xx.tag 分页标签开发的实际开发步骤!
xx.tag标签的开发只需要两个步骤:
1、pageBar.tag展示文件的创建与编辑;(放置路径:WEB-INF/tags/ )
2、使用标签页面的实用。(这里用的是usrListPaged.jsp)
下面贴出具体代码:
1、pageBar.tag
<%@ tag pageEncoding="utf-8" %><!-- 声明JSTL标签,以便在本标签中使用 --><%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %><!-- 定义了两个标签属性 --><%@ attribute name="formID" required="true" rtexprvalue="true" description="搜索条件提交的表单ID" %><%@ attribute name="isShowTotalPages" required="false" rtexprvalue="true" type="java.lang.Boolean" description="是否显示总页数" %><%@ attribute name="isShowJumpToButton" required="false" rtexprvalue="true" type="java.lang.Boolean" description="是否显示跳转按钮" %><div id="div_pager"><a onclick="getLink(1)">首页</a><a onclick="getLink(${customPage.currentPage -1})"><<上一页</a><%-- <c:forEach var="pageNo" begin="1" end="${customPage.totalPages}" step="1"><c:choose><c:when test="${pageNo == customPage.currentPage }"> <span class="curr"><c:out value="${pageNo }"></c:out></span></c:when><c:otherwise><a onclick="getLink(${pageNo })"><c:out value="${pageNo }"></c:out></a></c:otherwise></c:choose></c:forEach> --%><label id="pagerNO"></label><a onclick="getLink(${customPage.currentPage +1})">下一页>></a><a onclick="getLink(${customPage.totalPages})">尾页</a><c:if test="${isShowTotalPages == null || isShowTotalPages != false }"><label id="totalPage">共${customPage.totalPages}页</label><label id="totalRecords">/${customPage.totalRows}条数据</label></c:if><c:if test="${isShowJumpToButton == null || isShowJumpToButton != false }"><label id="go_page_wrap" class="normalsize">转到<span style="margin:0px 1px;padding:0px;"><input type="text" id="btn_go_input" maxlength="5" value="${customPage.currentPage}" /><input type="button" id="btn_go" value="确定"/></span>页</label></c:if></div><script type="text/javascript">$(function(){ //当前页码 var currentPage = ${customPage.currentPage}; //总页码 var totalPages = ${customPage.totalPages}; //总数据条数 var totalRows = ${customPage.totalRows}; var pageHtml = ''; var dot = '<span style="FONT-WEIGHT: normal;">...</span>'; //--------function in input text to jump into the page-------------// $("#btn_go_input").focus(function(){ var $btn_go = $("#btn_go"); $btn_go.css("display","inline"); }); $("#btn_go_input").blur(function(){ validateInputPageNO() }); $("#btn_go").click(function(){validateInputPageNO(); }); //----------------------------// // 1.总页数不足9页,就全部显示 if(totalPages < 9){ for(var i=1; i<totalPages; i++){ if(currentPage == i){ pageHtml += '<span class="curr">'+ i +'</span>'; }else{ pageHtml += '<a onClick="getLink('+ i +')" title="第'+ i +'页">'+ i +'</a>'; } }// end for loop }else{ //2.总页数 9页及以上 if(currentPage <= 5){ // 2.1 当前页码小于 6, 1到7页全显示,最后面用 '...' 代替 for(var i=1; i<=7; i++){ if(currentPage == i){ pageHtml += '<span class="curr">'+ i +'</span>'; }else{ pageHtml += '<a onClick="getLink('+ i +')" title="第'+ i +'页">'+ i +'</a>'; } }// end for loop pageHtml += dot; }else{ // 2.2当前页码为6及以上 pageHtml += '<a onClick="getLink(1)" title="第1页">1</a>'; pageHtml += '<a onClick="getLink(2)" title="第2页">2</a>'; pageHtml += dot; var begin = currentPage - 2; var end = currentPage + 2; if(end > totalPages){// 计算出来的end页码超过总页数,end取尾页 end = totalPages; begin = end -4; if(currentPage - begin < 2){ begin = begin - 1; } }else if(end + 1 == totalPages){ end = totalPages; }//end else if for(var i=begin; i<=end; i++){ if(currentPage == i){ pageHtml += '<span class="curr">'+ i +'</span>'; }else{ pageHtml += '<a onClick="getLink('+ i +')" title="第'+ i +'页">'+ i +'</a>'; } }// end for loop if(end != totalPages){ pageHtml += dot; }//end if }//end else 2.2当前页码为6及以上 }//end more than 8 pages $("#pagerNO").html(pageHtml); });// jump to the pagefunction getLink(n){var $form = $("#${formID}");var jdf_currentPage = '<input type="hidden" name="jdf_currentPage" value="'+n+'"/>';$form.append(jdf_currentPage);$form.submit();}// validdate the page .NO in input function validateInputPageNO(){var str_page = $("#btn_go_input").val(); if(isNaN(str_page)){ $("#btn_go_input").val(1); return; } var n = parseInt(str_page); // jump to the pagegetLink(n);}</script><style><!--#div_pager{ clear:both; height:30px; line-height:30px; margin-top:20px; color:black; font-size:12px;} #div_pager a{ padding:4px 8px; margin:10px 3px; border:1px solid #FF6600; background-color:#FFF; color:#FF6600; text-decoration:none; FONT-WEIGHT: bold; } #div_pager span{ padding:4px 8px; margin:10px 3px; font-size:14px; FONT-WEIGHT: bold;} #div_pager span.disabled{ padding:4px 8px; margin:10px 3px; border:1px solid #DFDFDF; background-color:#FFF; color:#DFDFDF; } #div_pager span.curr{ padding:4px 8px; margin:10px 3px; border:1px solid #FF6600; background-color:#FF6600; color:#FFF; } #div_pager a:hover{ background-color:#FFEEE5; border:1px solid #FF6600; cursor:pointer; FONT-WEIGHT: bold; } #btn_go_input{width:42px;height:25px;line-height:25px;text-align:center;}#btn_go{margin:0px;padding:0px;width:40px;height:20px;line-height:20px;padding:0px;font-family:arial,宋体,sans-serif;text-align:center;border:0px;background-color:#0063DC;color:#FFF;display:none;}--></style>
此页面需要注意这样几点:
1)、页面实用到了jquery,所以在引用此标签的jsp页面中一定要引入一个jquery包;
2)、也面中的customPage对象是一个Pager 对象,里面封装了常用页面处理信息(总记录数、总页数、当前页等)
这个对象需要封装到request 或者 各自使用框架的 类似的对象上,只要你的jsp 页面中能够访问到 pager对象就行;
3)、标签中使用到的属性,在xx.tag中可以通过 ${} 取得值,比如我这里要在pageBar.tag中取得jsp 页面中
<pager:pageBar formID="user_loadUserList" isShowTotalPages="false" isShowJumpToButton="true"/>
formID、 isShowTotalPages 和 isShowJumpToButton的值, 那就用了${} 来取值的。
2、usrListPaged.jsp
<%@ page language="java" import="java.util.*" pageEncoding="UTF-8"%>
<%@taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
<%@taglib prefix="fn" uri="http://java.sun.com/jsp/jstl/functions" %>
<%@taglib prefix="pager" tagdir="/WEB-INF/tags" %>
<%
String basePath = request.getScheme()+"://"+request.getServerName()+":"+request.getServerPort()+request.getContextPath()+"/";
request.setAttribute("path", basePath);
%>
<html>
<head>
<base href="<%=basePath%>">
<title>用户创建成功</title>
<meta http-equiv="pragma" content="no-cache">
<meta http-equiv="cache-control" content="no-cache">
<meta http-equiv="expires" content="0">
<meta http-equiv="keywords" content="keyword1,keyword2,keyword3">
<meta http-equiv="description" content="This is my page">
<!--
<link rel="stylesheet" type="text/css" href="styles.css">
-->
<script type="text/javascript" src="${path}/js/commons/jquery-1.11.1.min.js"></script>
<script type="text/javascript" src="${path}/js/commons/jquery.json-2.4.js"></script>
<style type="text/css">
body{
font-size: 12pt;
margin: 0;
padding: 0;
}
.button{
margin:0;
padding-left:5px;
padding-right:5px;
height: 30px;
line-height: 30px;
border: 2px solid black;
background-color: yellow;
}
</style>
</head>
<body>
<form action="${path }/user/loadUserList.shtml"id="user_loadUserList">
用户名:<input type="text" id="userName" name="userName" maxlength="20" value="${filter.userName }"/>
<input type="submit" class="button" value="提交"/>
</form>
<br>
<table id="friends" width="700" border="1" cellspacing="0" cellpadding="0" >
<caption style="margin-bottom:10px;">查看所有好友信息</caption>
<thead>
<tr bgcolor="yellow" height="30">
<th width="30%">用户名</th>
<th width="30%">密码</th>
<th width="40%">真是姓名</th>
</tr>
</thead>
<tbody>
<c:if test="${userList != null}">
<c:forEach items="${userList}" var="user">
<tr height="30">
<td>${user.userName }</td>
<td>${user.password }</td>
<td>${user.realName }</td>
</tr>
</c:forEach>
</c:if>
<c:if test="${userList == null}">
<tr height="30">
<td colspan="3" align="center">没有数据</td>
</tr>
</c:if>
</tbody>
</table>
<pager:pageBarformID="user_loadUserList" isShowTotalPages="false" isShowJumpToButton="true"/>
</body>
<script type="text/javascript">
$(function(){
//alert("aaaaaaaaaaaaaaaa");
});
</script>
</html>
分页功能的总结: 前端分页 提交给后台 Java类的关键参数就是 当前的搜索条件、当前页号。所以,我的标签里面是给标签处理文件提供 formID 而不是 url地址。后台代码在封装时也要满足这样一条准则,使用你标签的用户只需关注他自己的业务需求,其他的一切分页工作都由你来封装实现。
也许说多了大家也不太相信,好吧,下面给大家秀一秀最终效果吧。
哈哈,就扯到这里吧,感觉如何呢?
- JSP自定义标签开发(八)—— xx.tag自定义标签开发之分页标签(jquery + div +css 美化)
- JSP自定义标签开发(七)—— xx.tld标签开发之权限管理标签开发
- 开发自定义tag标签
- JSP自定义分页标签TAG
- JSP自定义标签(tag)
- JSP 自定义标签(Tag)
- JSP自定义标签开发(一)—— HelloWorld 采用Tag接口实现开发
- 开发第一个JSP自定义标签(Tag)
- JSP自定义标签开发(四)——带标签体的标签实现
- jsp自定义标签开发
- JSP自定义标签开发
- 【jsp】开发自定义标签
- JSP自定义标签开发
- JSP自定义标签开发
- JSP自定义标签开发
- JSP自定义标签开发
- JSP自定义标签开发
- jsp自定义标签开发
- 保存android的颜色数值
- Java中继承注意事项
- 二叉树 中序,后序,叶子节点,深度
- [LeetCode] Longest Consecutive Sequence
- VC项目配置基础
- JSP自定义标签开发(八)—— xx.tag自定义标签开发之分页标签(jquery + div +css 美化)
- FL2440驱动添加(3)LCD驱动添加学习笔记
- Linux使用小技巧记录
- J2EE架构图
- 【Oracle】ORA-00600: [kfgFinalize_2]
- Android如何防止apk程序被反编译
- Java设计模式之策略模式(转)
- Hibernate多表查询 : java.lang.OutOfMemoryError: Java heap space
- 端口查看命令