Pager アルゴリズムサンプル : javascript
業務で必要となるため Pager(ページャー) 用処理を javascript にて作成してみることに。
図 1)

仕様
どのような動作にするかの仕様を決定します。prev, next ボタン表示に関しては、まずは考慮から外します。
デフォルトの現在のページ表示位置
現在のページ表示位置は、中心位置となるようにします。
例えばページ総数が 30, ページ表示総数を 6 (偶数値)、現在表示されているページが 7、とした場合の表示は 図 2 となるようにします。
図 2)

ページ総数が 30, ページ表示総数を 7 (奇数値)、現在表示されているページが 7、とした場合の表示は 図 3 となるようにします。
図 3)

特定条件での現在のページ表示位置
ページによっては表示位置を中心位置以外にする必要がでてきます。
例えば 図 2 と同じ条件で現在のページが 2 あるいは 1 の場合、図 4, 5 となるようにします。
図 4)

図 5)

同じように、図 2 と同じ条件で現在のページが 29, あるいは 30 の場合、図 6, 7 となるようにします。
図 6)

図 7)

仕様詳細
「ページ総数」「ページ表示総数」「現在のページ」を与えることで、「表示最小ページ」「表示最大ページ」「現在のページ表示位置」の値が取得できるようにすれば、各図のような表示が可能となります。
例えば 図 2 の表示を行うには 以下の値のやりとりを行います。
[ 与える値 ] ページ総数 : 30 ページ表示総数 : 6 現在のページ : 7 [ 取得する値 ] 表示最小ページ : 5 表示最大ページ : 10 現在のページ表示位置 : 2
図 5 の表示を行うには 以下の値のやりとりを行います。
[ 与える値 ] ページ総数 : 30 ページ表示総数 : 6 現在のページ : 2 [ 取得する値 ] 表示最小ページ : 1 表示最大ページ : 6 現在のページ表示位置 : 1
現在のページの表示位置は、配列要素数と同じく 0 から始まるものとします。ページ表示総数が 6 の場合、現在のページの表示位置は 0 ~ 5 の値となります。
ソースコード
上記処理を行うための PagerDataCreator, PagerData クラス(PagerDataCreator.js)の内容は以下となります。
/**
* page --- 1 ~ this.pageTotal
* viewPosition --- 0 ~ (this.viewTotal - 1)
*/
function PagerDataCreator(){
this.init.apply(this, arguments);
}
PagerDataCreator.prototype.init = function(pageTotal, viewTotal){
this.pageTotal = pageTotal;
this.viewTotal = (viewTotal > pageTotal) ? pageTotal : viewTotal;
this.maxPage = pageTotal;
this.minPage = 1;
this.defaultViewPosition = Math.ceil(this.viewTotal / 2) - 1;
};
PagerDataCreator.prototype.create = function(page){
var min;
var max;
var viewPosition;
if(page - this.defaultViewPosition < this.minPage){
min = this.minPage;
max = this.viewTotal;
viewPosition = page - 1;
}
else if(page + this.defaultViewPosition >= this.maxPage){
min = this.maxPage - this.viewTotal + 1;
max = this.maxPage;
viewPosition = (this.viewTotal - 1) - (this.maxPage - page);
}
else{
min = page - this.defaultViewPosition;
max = page + ((this.viewTotal - 1) - this.defaultViewPosition);
viewPosition = this.defaultViewPosition;
}
return new PagerData(min, max, viewPosition);
};
/**
*
*/
function PagerData(){
this.init.apply(this, arguments);
}
PagerData.prototype.init = function(min, max, viewPosition){
this.min = min;
this.max = max;
this.viewPosition = viewPosition;
//console.log(min, max, viewPosition);
};
PagerData.prototype.getMin = function(){
return this.min;
};
PagerData.prototype.getMax = function(){
return this.max;
};
PagerData.prototype.getViewPosition = function(){
return this.viewPosition;
};
図 2 の表示を行うための PagerDataCreator, PagerData クラスの利用方法は以下となります。
var pageTotal = 30; var viewTotal = 6; var page = 7; var pagerDataCreator = new PagerDataCreator(pageTotal, viewTotal); var pagerData = pagerDataCreator.create(page); //pagerData.min : 5 //pagerData.max : 10 //pagerData.viewPosition : 2
サンプル
PagerDataCreator, PagerData クラスを利用した、図 1 の表示を行うためのサンプルは以下となります。Pager.js では jQuery を用いて DOM 操作を行っています。
・PagerDataCreator, PagerData を呼び出し、HTML タグに値を設定するための Pager.js
function Pager(){
this.init.apply(this, arguments);
}
Pager.prototype.init = function(pageTotal, viewTotal, page){
var pagerDataCreator = new PagerDataCreator(pageTotal, viewTotal);
var pagerData = pagerDataCreator.create(page);
var element = $("#pager").append("<ul>");
for(var i = 0, p = pagerData.min; p <= pagerData.max; i++, p++){
var pageStr = (i == pagerData.viewPosition) ?
["<b>", p, "</b>"].join("") :
["<a href='", p, "'>", p, "</a>"].join("");
$("ul", element).append(["<li>", pageStr, "</li>"].join(""));
}
//prev navi
if(page > 1)
$("ul", element).prepend([
"<li>",
"<a href='", page - 1, "'>",
"prev",
"</a>",
"</li>"
].join(""));
//next navi
if(page < pageTotal)
$("ul", element).append([
"<li>",
"<a href='", page + 1, "'>",
"next",
"</a>",
"</li>"
].join(""));
};
・Pager.js から出力される HTML 要素の見ためを制御するための pager.css
#pager ul{
list-style: none;
}
#pager li{
float: left;
margin: 0 10px 0 0;
}
.clear_both{
clear: both;
}
・Pager.js と pager.css を呼び出す index.html
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html>
<head>
<link rel="stylesheet" type="text/css" href="css/pager.css" />
<script type="text/javascript" src="https://ajax.googleapis.com/ajax/libs/jquery/1.6.1/jquery.min.js"></script>
<script type="text/javascript" src="js/PagerDataCreator.js"></script>
<script type="text/javascript" src="js/Pager.js"></script>
<script language="javascript">
var PAGE_TOTAL = 30;
var VIEW_TOTAL = 6;
var page = 7;
$(function(){
new Pager(PAGE_TOTAL, VIEW_TOTAL, page);
});
</script>
</head>
<body>
<div id="pager"></div>
<div class="clear_both"></div>
</body>
</html>
変数 page には直に 7 という値を設定していますが、 実際はこの値は URL から取得したり、サーバで動的に埋め込まれたりすることを想定しています。


