日期:2014-05-16  浏览次数:20650 次

jquery<--json-->spring(3.0)之DataTables的服务器端翻页
本文是jquery<--json-->spring(3.0)系列的第三篇。

jquery与yui相比,感觉写法很简洁,但也有个问题是配套的jquery ui中的页面控件
不是很全,很多要借助plugin,而这些plugin良莠不齐,选用时要自己好好挑一挑。
列表是一个常用的页面控件,我选了半天发现DataTables这款用的人比较多,就试了
试服务器端翻页功能,现总结如下。

DataTables的主页是http://www.datatables.net/

先上个这个demo的截图,设想的操作是输入客户名称,按检索后进行模糊检索进行分
页显示,每页显示8条记录。




1 页面部分
使用DataTables时,html需要如下书写,其中tfoot部分是表表格的下部标题,可以不
要。
<table class="display" id="customerInfo">
	<thead>
		<tr>
			<th>ID</th>
            略
			<th>身高</th>
		</tr>
	</thead>
	<tbody>
		<tr>
			<td colspan="8"></td> 
		</tr>
	</tbody>
	<tfoot>
		<tr>
			<th>ID</th>
            略
			<th>身高</th>
		</tr>
	</tfoot>
</table>


js部分这样写:
$('#customerInfo').dataTable();


对于从服务器端取数据,还要指定几个参数:
bServerSide:true
sAjaxSource:获取数据的url

这样,在DataTables需要数据时会调用jquery的getJSON获取数据,其中url就是sAjaxSource,
同时传递一堆自定义的参数,包括需要显示的起始记录数,需要显示的记录数,列数,排序
列等等,具体可以参看这里http://www.datatables.net/usage/server-side。其中一个比较
特殊的是sEcho,这个参数需要以后原封不动地返回给页面。
由于默认是以$.getJSON发送请求,所以http命令是GET,参数是以url参数的方式传递的,我
希望以POST命令,以json方式发送请求,而且要加上客户名称这个参数,所以这里需要做些修
改。
DataTables通过fnServerData提供了这样一个接口,fnServerData是与服务器端交换数据时被
调用的函数,默认实现是如上所说的通过getJSON发送请求,然后接收特定格式的json数据(这
个在服务器端处理部分再说)。fnServerData会接到3个参数:
sSource: 接收数据的url,就是sAjaxSource中指定的地址
aoData:DataTables定义的参数,是一个数组,其中每个元素是一个name-value对,我需要
        把客户名称这个参数加进去
fnCallback:服务器返回数据后的处理函数,我需要按DataTables期望的格式传入返回数据
最后自定义的fnServerData如下所示:
function retrieveData( sSource, aoData, fnCallback ) {
    //将客户名称加入参数数组
	aoData.push( { "name": "customerName", "value": $("#customerName").val() } );

	$.ajax( {
		"type": "POST", 
		"contentType": "application/json",
		"url": sSource, 
		"dataType": "json",
		"data": JSON.stringify(aoData), //以json格式传递
		"success": function(resp) {
			fnCallback(resp.returnObject); //服务器端返回的对象的returnObject部分是要求的格式
		}
	});
}


页面的初始化及查询按钮的处理函数如下所示:

var oTable = null;

$(function() {
	$("#customerInfo").hide();
} );

//“检索”按钮的处理函数
function search() {
	if (oTable == null) { //仅第一次检索时初始化Datatable
		$("#customerInfo").show();
		oTable = $('#customerInfo').dataTable( {
			"bAutoWidth": false,					//不自动计算列宽度
			"aoColumns": [							//设定各列宽度
							{"sWidth": "15px"},
							{"sWidth": "80px"},
							{"sWidth": "160px"},
							{"sWidth": "110px"},
							{"sWidth": "120px"},
							{"sWidth": "140px"},
							{"sWidth": "140px"},
							{"sWidth": "*"}
						],
			"bProcessing": true,					//加载数据时显示正在加载信息
			"bServerSide": true,					//指定从服务器端获取数据
			"bFilter": false,						//不使用过滤功能
			"bLengthChange": false,					//用户不可改变每页显示数量
			"iDisplayLength": 8,					//每页显示8条数据
			"sAjaxSource": "customerInfo/search.do",//获取数据的url
			"fnServerData": retrieveData,			//获取数据的处理函数
			"sPaginationType": "full_numbers",		//翻页界面类型
			"oLanguage": {							//汉化
				"sLengthMenu": "每页显示 _MENU_ 条记录",
				"sZeroRecords": "没有检索到数据",
				"sInfo": "当前数据为从第 _START_ 到第 _END_ 条数据;总共有 _TOTAL_ 条记录",
				"sInfoEmtpy": "没有数据",
				"sProcessing": "正在加载数据...",
				"oPaginate": {
					"sFirst": "首页",
					"sPrevious": "前页",
					"sNext": "后页",
					"sLast": "尾页"
				}
			}
		});
	}

	//刷新Datatable,会自动激发retrieveData
	oTable.fnDraw();
}


2 服务器端
页面请求的参数是一个数组,其中每个元素是一个name-value对,我如下定义
public class JSONParam {
	private String name;
	private String value;
	
	//略
}

对应的处理函数如下定义:
@RequestMap