この記事のURL

http://www.dango-itimi.com/blog/archives/2011/001067.html


FLASH tips 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 から取得したり、サーバで動的に埋め込まれたりすることを想定しています。

[ FLASH ] [ tips ] 投稿者 siratama : 2011年06月12日 01:30

トラックバック

http://www.dango-itimi.com/blog/mt-tb.cgi/1027

コメント

以下コメントを書き込むだけでは、管理人には通知が行われません。通知を行いたい場合、管理人の書き込みに「返信」を押してコメントをしていただくか、あるいは Google+, Twitter へご連絡ください。




[EDIT]