springMVC+velocity实现仿Datatables局部刷新分页

        因为项目中之前的模块用的分页插件是Datatables,很方便,但是新做的模块表格中的布局有变化,Datatables插件满足不了了。为了风格的统一,同时也不希望查询参数再传递回显在页面上,所以就采用局部刷新分页的实现方案。

        实现方案是这样的,将表格部分提取出来,用来作为页面局部刷新的部分,文件名为list-data.vm

<table class="table text-center table_acolor">
	<thead>
		<tr>
			<th width="16%">userName</th>
			<th width="24%">age</th>
		</tr>
	</thead>
	<tbody>
		#foreach($data in $!{page.list})
		<tr>
			<td width="16%">$!{data.userName}</td>
			<td width="24%">$!{data.sex}</td>
		</tr>
		#end
	</tbody>
</table>
#pageNation($!{page})

其中的pageNation是定义的一个宏(macro),用来做底部的分页条和分页条的显示逻辑。page对象是ajax请求返回的分页数据。每一次ajax请求,查询出分页数据,将数据放入list-data.vm所对应的视图的ModelAndView对象,然后返回ModelAndView对象,将这一部分追加到主页面表格所在的部分。

macro部分如下:

#macro(pageNation $data)
	#if(!$data.list.size() or $data.list.size() == 0)
<div class="row DTTTFooter no-padding" style="height:40px; line-height:40px; text-align:center; font-size:14px;">
未查询到记录
</div>
	#end
    	#if($data.list.size() and $data.list.size() > 0)
	     <div id="activityTable_info" class="dataTables_info" role="status" aria-live="polite">显示第 $!{data.startRow} 至 $!{data.endRow} 项结果,共 $!{data.total}项</div>
	     <div id="pagination" class="dataTables_paginate paging_full_numbers">
			#set($prevPage = ${data.prePage})
    		#set($nextnPage = ${data.nextPage})
			<a #if($data.pageNum ==1) class="paginate_button disabled" disabled="disabled" href="javascript:void(0)"
				#else class="paginate_button" pageNum="1" href="javascript:goPage(1)"
				#end style="margin-left: 2px;"
			>首页</a>
			<a #if($data.pageNum ==1) class="paginate_button disabled" disabled="disabled" href="javascript:void(0)"
				#else  class="paginate_button" pageNum="$prevPage" href="javascript:goPage($prevPage)"
				#end style="margin-left: 2px;"
            > 上页 </a>
            #set($temp = ${data.pageNum} - 1)
            #set($numbers = $!{pageUtil.numbers($temp, $data.pages)})
            
            #foreach($foo in $numbers)
            #if($foo == -999)
            <span>…</span>
            #else
            <a class="paginate_button #if($foo==${data.pageNum}) current #end" pageNum="$foo" #if($foo!=${data.pageNum}) href="javascript:goPage($foo)" #end style="margin-left: 2px;"
				> $foo </a>
            #end
            #end
		
			<a 
				#if($data.pageNum == $data.pages) class="paginate_button disabled" disabled="disabled"
				#else  class="paginate_button" pageNum="$nextnPage" href="javascript:goPage($nextnPage)"
				#end style="margin-left: 2px;"
            > 下页
			<a
				#if($data.pageNum == $data.pages)
				  class="paginate_button disabled"	disabled="disabled" href="javascript:void(0)"
				#else
				 class="paginate_button" pageNum="$data.pages" href="javascript:goPage($data.pages)"
				#end 
				>末页</a>
		  到第 
		<input id="changePage" class="margin text-center" type="text" maxpage="10" style="height:28px;line-height:28px;width:40px;">
 		页 
 		<a id="dataTable-btn" class="btn btn-default shiny" href="javascript:jumpPage($data.pages);" style="margin-bottom:5px">确认</a> 
		#end
	</div>
	<div p_sortinfo="$!{data.orderBy}" p_isFirst=$!{data.isFirst} p_isLast=$!{data.isLast} p_currentpagenum="$!{data.pageNum}" p_totalsize="$!{data.total}" p_endrow="$!{data.endRow}" p_totalpagesnum="$!{data.pages}" p_pagesize="$!{data.pageSize}" p_startrow="$!{data.startRow}" style="display:none" class="paginator"></div>
#end

pageUtil是写的velocity toolbox的一个工具类,用来仿Datatables分页条的分页页码显示的逻辑:

public class PageUtil {

	public static LinkedList<Integer> range(Integer len,Integer start) {
		LinkedList<Integer> out = new LinkedList<>();
		Integer end;
	
		if (start == null ) {
			start = 0;
			end = len;
		}
		
		else {
			end = start;
			start = len;
		}
	
		for (int i=start ; i<end ; i++ ) {
			out.add(i);
		}
	
		return out;
	}
	
	public static List<Integer> numbers (Integer page,Integer pages) {
		LinkedList<Integer> numbers = new LinkedList<>();
		Integer	buttons = 7;
		Integer	half = buttons / 2;
	
		if (pages <= buttons ) {
			numbers = range( 0, pages );
		}
		else if ( page <= half ) {
			numbers = range( 0, buttons-2 );
			numbers.add(-1000);
			numbers.add( pages-1 );
		}
		else if ( page >= pages - 1 - half ) {
			numbers = range( pages-(buttons-2), pages );
			numbers.addFirst(-1000 ); //向头放
			numbers.addFirst(0 );
		}
		else {
			numbers = range( page-1, page+2 );
			numbers.add( -1000 );
			numbers.add( pages-1 );
			numbers.addFirst(-1000 );
			numbers.addFirst(0 );
		}
		List<Integer> res = new ArrayList<>();
		for (Integer integer : numbers) {
			res.add(integer+1);
		}
		return res;
	}
}

而这段逻辑是从Datatables的js源码中找到的,我将其转化为java代码。Datatables源码的该部分代码如下

function _numbers ( page, pages ) {
		var
			numbers = [],
			buttons = extPagination.numbers_length,
			half = Math.floor( buttons / 2 ),
			i = 1;
	
		if ( pages <= buttons ) {
			numbers = _range( 0, pages );
		}
		else if ( page <= half ) {
			numbers = _range( 0, buttons-2 );
			numbers.push( 'ellipsis' );
			numbers.push( pages-1 );
		}
		else if ( page >= pages - 1 - half ) {
			numbers = _range( pages-(buttons-2), pages );
			numbers.splice( 0, 0, 'ellipsis' ); // no unshift in ie6
			numbers.splice( 0, 0, 0 );
		}
		else {
			numbers = _range( page-1, page+2 );
			numbers.push( 'ellipsis' );
			numbers.push( pages-1 );
			numbers.splice( 0, 0, 'ellipsis' );
			numbers.splice( 0, 0, 0 );
		}
	
		numbers.DT_el = 'span';
		return numbers;
	}

var _range = function ( len, start )
	{
		var out = [];
		var end;
	
		if ( start === undefined ) {
			start = 0;
			end = len;
		}
		else {
			end = start;
			start = len;
		}
	
		for ( var i=start ; i<end ; i++ ) {
			out.push( i );
		}
	
		return out;
	};

我将页面的ajax请求分页的数据做了封装:

/**
 * 
 */
//macro分页跳页调用方法,调用的页面需要提供goPage(redirectpage)方法
function jumpPage(totalPage) {
	var redirectpage = $("#changePage").val();
	if(redirectpage == ""){
		$("#changePage").focus();
	}else{
		var rex = /^\d+$/;
		if(!rex.test(redirectpage)){
			alert("页码输入有误,只能输入不大于总页数的正整数");
		}else{
			var pageNo = parseInt(redirectpage);
			if(pageNo <= 0 || pageNo > totalPage){
				alert("页码输入有误,只能输入不大于总页数的正整数");
			}else{
				goPage(redirectpage)
			}
		}
	}
}

$.fn.pagenation = function(options) {
	
	//默认参数
	var defaults={
			url:"",
			data:{},//参数
			pageNo:1,//页码
			pageSize:10,//页面大小
			pageSuccess:{}//分页数据成功返回的回调函数
	}
	var _self = $(this);
	options = $.extend(defaults,options);
	var ajaxData = {
		"pageNo":options.pageNo,
		"pageSize":options.pageSize
	};
	
	
	this.fnDraw = function(pageNo) {
		if (typeof (options.data) == 'function') {
			ajaxData = options.data(ajaxData);
		} else {
			ajaxData = $.extend(ajaxData,options.data);
		}
		if (pageNo != undefined) {
			ajaxData['pageNo'] = pageNo;
		}
		
		$.ajax({
			url: options.url,
			async: false,
			type:"post", 
			data: ajaxData,
			success: function(result,code,dd) {
				_self.html(result);
				if (typeof options.pageSuccess == 'function') {
					options.pageSuccess();
				}
			},
			error:function(){
				alert("操作失败");
			}
		});
	};
	
	this.init = function() {
		this.fnDraw(1);
		return this;
	}
	
	return this;
	
}

在主页面调用:

<!DOCTYPE html>
<html>
<head>
<meta charset="UTF-8">
<title>Insert title here</title>
#set($ctx = ${request.getContextPath()})
<link rel="stylesheet" type="text/css" href="$ctx/assets/js/dataTables/jquery.dataTables.min.css" />
	<link rel="stylesheet" type="text/css" href="$ctx/assets/js/dataTables/css/jquery.dataTables_theme.css" />
	<script type="text/javascript" src="$ctx/assets/js/jquery-1.11.2.min.js"></script>
	<script type="text/javascript" src="$ctx/assets/js/macro.pagination.js"></script>
</head>
<body>
	<div class="dataTables_wrapper" id="pageDiv">
		
	</div>
	<script type="text/javascript">
	var pagenation = $("#pageDiv").pagenation({
		url:"${ctx}/listData.do",
		pageSize:20,
		data:function (data) {
			$("#searchForm [name]").each(function(i, n){
				data[$(n).attr('name')] = n.value;
				});
			return data;
		},
		pageSuccess:function(){
			
		}
	}).init();
	
	function goPage(pageNo) {
		pagenation.fnDraw(pageNo);
	}
	</script>
</body>
</html>

其中pageSuccess参数是用来在ajax返回数据成功后,需要做的一些操作。

这里说的也不太明白,附上码云的git地址:http://git.oschina.net/ivwpw/pagenation

其中并没有做从数据库插数据的部分,只是在Controller中模拟了页面需要的数据。


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值