DataTable Control: Server-side Pagination and Sorting for Dynamic Data

この例の画面は以下。

見た目は先の「DataTable Control: Client-side Pagination」と変わらないのだが、タイトルがServer-side Paginationと、Client-side Paginationと大きく違っている。

どこがどう違うかというと、

  • Client-side Pagination では、一度、サーバーから全てのデータをとってきて、メモリ(=クライアント・マシン)上でPaginatorを生成する。したがって、Paginatorでページを遷移しても、サーバーへのリクエストは発生しない。
  • Server-side Pagination では、1ページに表示する分のデータだけサーバーから取得する。このため、Pagenatorでページを遷移をする度に、サーバーに対して(データを取得するための)リクエストが発生する。

ということになる。

Server-side Paginationの方が、当然、初速が速く、非同期通信を頻繁に発生させるという意味で「Ajax的な」方法といえる(Google Mapがそうであるように、画面全部がいっぺんに現れるのを待つより、少しずつ現れた方が、利用者がイライラしない)。
このような手法は、Narrowbandな環境では、より効果を発揮する。

能書きはいいとして、以下にソースコードの全文を示す。
このケースでも、DataSourceが、うまく機能を担うことで、コードが非常にシンプルになっていることがわかる。
また、データはPHPプログラム(ajax_yui_datatable_clientside_pagination.Proxy.php)を経由して取得するようになっているが、これは「DataTable Control: Client-side Pagination」で利用したのと同じものである。

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd"> 
<html> 
<head> 
    <meta http-equiv="content-type" content="text/html; charset=utf-8"> 
<title>Ajax Sample</title> 
 
<style type="text/css"> 
body {
	margin:0;
	padding:0;
}
</style> 

<link rel="stylesheet" type="text/css" href="scripts/yui/fonts/fonts-min.css" /> 
<link rel="stylesheet" type="text/css" href="scripts/yui/paginator/assets/skins/sam/paginator.css" /> 
<link rel="stylesheet" type="text/css" href="scripts/yui/datatable/assets/skins/sam/datatable.css" /> 
<script type="text/javascript" src="scripts/yui/yahoo-dom-event/yahoo-dom-event.js"></script> 
<script type="text/javascript" src="scripts/yui/connection/connection-min.js"></script> 
<script type="text/javascript" src="scripts/yui/json/json-min.js"></script> 
<script type="text/javascript" src="scripts/yui/element/element-beta-min.js"></script> 
<script type="text/javascript" src="scripts/yui/paginator/paginator-min.js"></script> 
<script type="text/javascript" src="scripts/yui/datasource/datasource-min.js"></script> 
<script type="text/javascript" src="scripts/yui/datatable/datatable-min.js"></script> 

<style type="text/css" id="defaultstyle">
#main {
	margin: 2px;
	padding: 3px;
}
</style>

<script type="text/javascript"> 
YAHOO.util.Event.addListener(window, "load", function() {

	YAHOO.example.DynamicData = function() {
	    var myColumnDefs = [ // sortable:true enables sorting
	        			{key:"id", label:"ID", sortable:true},
	       				{key:"name", label:"Name", sortable:true},
	           			{key:"date", label:"Date", sortable:true, formatter:"date"},
	          			{key:"price", label:"Price", sortable:true},
	        			{key:"number", label:"Number", sortable:true}
	       			];
	                  
	    // カスタムパーサー
	    var stringToDate = function(sData) {
	        var array = sData.split("-");
	        return new Date(array[1] + " " + array[0] + ", " + array[2]);
	    };
	                     
	    // DataSourceのインスタンス化
	    var myDataSource = new YAHOO.util.DataSource("ajax_yui_datatable_clientside_pagination.Proxy.php?");
	    myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
	    myDataSource.responseSchema = {
	          	resultsList: "records",
	            fields: [
	            {key:"id", parser:"number"},
	            {key:"name"},
	            {key:"date", parser:stringToDate},
	            {key:"price",parser:"number"},
	            {key:"number",parser:"number"}
	        	],
	            metaFields: {
            		// サーバーレスポンスのうちの総件数を取得する。
	            	totalRecords: "totalRecords" 
	                }
	            };
	                     
	   	// DataTable のコンフィグ
	    var myConfigs = {
	    	    // 初期データ(最初のページ)
	           	initialRequest: "sort=id&dir=asc&startIndex=0&results=15s",
	           	// DynamicDataを指定。 
	            dynamicData: true, 
	            // データの並び順を指定(dirはdirectionの略)
	            sortedBy : {key:"id", dir:YAHOO.widget.DataTable.CLASS_ASC}, 
				// Pagenatorを25行/ページで作成
	            paginator: new YAHOO.widget.Paginator({ rowsPerPage:15 })  
	            };
	                     
	    // DataTableのインスタンスを作成
	    var myDataTable = new YAHOO.widget.DataTable("dynamicdata", 
	    	    myColumnDefs, myDataSource, myConfigs);

	    // サーバーからのレスポンスから総件数を取得して、DataTableがレンダリングする際に利用するtotalRecordsをセットする。
	    // handleDataReturnPayloadは、DataTableのレンダリングにhookするもの?
	    // http://developer.yahoo.com/yui/docs/YAHOO.widget.DataTable.html#method_handleDataReturnPayload
	    myDataTable.handleDataReturnPayload = function(oRequest, oResponse, oPayload) {
	    	oPayload.totalRecords = oResponse.meta.totalRecords;
	    return oPayload;
	    }		
        
        return {
            oDS: myDataSource,
            oDT: myDataTable
        };
    }();
});
</script>
</head> 
 
<body class=" yui-skin-sam">
<div id="main">
<p>Paginationのサンプルです。<br/>
ページを変えるごとにサーバーからデータを取得します。</p>
<div id="dynamicdata"></div>
</div>
</body> 
</html>