DataTable Control: Client-side Sorting

このExampleには、Client-side Sorting(クライアント=scriptでのソート)という紛らわしい名前がついているが、「ソーティングをカスタマイズする」方法を説明するものである。

サンプルは、初期画面として以下の画面を出す。この画面ではarea codeで昇順にソートされている。

次に、stateの見出しをクリックして、stateを昇順に並べると、state > area code という順のソートがかかるようになっている。(下図のCaliforniaやIllinoisを参照)

ソーターのカスタマイズは、YAHOO.util.Sort.compare()を用い、関数の引数として2つのレコードオブジェクトと昇順・降順を表すBooleanを渡すことを前提にしているので、比較的平易なコードでカスタマイズができる。

以下にJavascriptを含むソースコードを示す。

<!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/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/element/element-beta-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" src="scripts/yui/datatable/assets/js/data.js"></script>
<script type="text/javascript"> 
YAHOO.util.Event.addListener(window, "load", function() {

	YAHOO.example.CustomSort = function() {

	     // カスタムソートの関数; a,bは2つの任意のRecordオブジェクト、descはソーティングが降順の場合にtrueとなるboolean。
		var sortStates = function(a, b, desc) {
            // Deal with empty values
            // Returns false for null/undefined/NaN, true for other values
            if(!YAHOO.lang.isValue(a)) {
				// aレコードが「null/undefined/NaN」で、bレコードが「null/undefined/NaN」でなければ1
				// 以外なら、0(差異なし)。
            	return (!YAHOO.lang.isValue(b)) ? 0 : 1;
            }
            else if(!YAHOO.lang.isValue(b)) {
                // a
                return -1;
            }
 
            // http://developer.yahoo.com/yui/docs/YAHOO.util.Sort.html#method_compare
            var comp = YAHOO.util.Sort.compare;
            // stateが最初のソート項目なので、まずは、2レコードのstateを比較する。
            var compState = comp(a.getData("state"), b.getData("state"), desc);
 
            // If states are equal, then compare by areacode
            // compState=0(stateが同じ)場合、エリアコードで比較する。
            return (compState !== 0) ? compState : comp(a.getData("areacode"), b.getData("areacode"), desc);
        };
 
        var myColumnDefs = [
            {key:"areacode",
                label:"Area Codes",
                sortable:true},
            {key:"state",
            	label:"States",
            	sortable:true,
            	// sortOptionとして、カスタムソートの関数名を指定。
            	sortOptions:{sortFunction:sortStates}}
        ];
 
        var myDataSource = new YAHOO.util.DataSource(YAHOO.example.Data.areacodes.slice(0,25));
        myDataSource.responseType = YAHOO.util.DataSource.TYPE_JSARRAY;
        myDataSource.responseSchema = {
            fields: ["areacode","state"]
        };
 
		// areaコードの昇順(ascend)で初期データをつくって、DataTableを作成する。
        var myDataTable = new YAHOO.widget.DataTable("sort", myColumnDefs,
                myDataSource, {sortedBy:{key:"areacode", dir:"asc"}});    
            
        return {
            oDS: myDataSource,
            oDT: myDataTable
        };
    }();
});
</script>
</head> 
 
<body class=" yui-skin-sam">
<div id="main">
<p>カスタムのソーティングのサンプルです。<br/>
Stateでソートすると、Stateでソートした後にarea codeでソートします。</p>
<div id="sort"></div>
</div>
</body> 
</html>