欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-06-11 12:08:08
因为项目中之前的模块用的分页插件是datatables,很方便,但是新做的模块表格中的布局有变化,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)" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
  #else class="paginate_button" pagenum="1" href="javascript:gopage(1)" rel="external nofollow" 
  #end style="margin-left: 2px;" 
  >首页</a> 
  <a #if($data.pagenum ==1) class="paginate_button disabled" disabled="disabled" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
  #else class="paginate_button" pagenum="$prevpage" href="javascript:gopage($prevpage)" rel="external nofollow" 
  #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)" rel="external nofollow" #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)" rel="external nofollow" 
  #end style="margin-left: 2px;" 
  > 下页 
  <a 
  #if($data.pagenum == $data.pages) 
   class="paginate_button disabled" disabled="disabled" href="javascript:void(0)" rel="external nofollow" rel="external nofollow" rel="external nofollow" 
  #else 
   class="paginate_button" pagenum="$data.pages" href="javascript:gopage($data.pages)" rel="external nofollow" 
  #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);" rel="external nofollow" 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" rel="external nofollow" /> 
 <link rel="stylesheet" type="text/css" href="$ctx/assets/js/datatables/css/jquery.datatables_theme.css" rel="external nofollow" /> 
 <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地址:

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

以上这篇springmvc+velocity实现仿datatables局部刷新分页方法就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持。