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