jiichan.com

PROGRAMMING

ページャーを作る(簡易版)

ページャーは「ページャーを作る」で既に作っていましたが、 もう少し簡易なものも欲しいと思い簡易版を作ってみました。


-----2016.09.10(修正)-----
先頭のページと最後のページに移動できるようにボタンを追加しました。
考えてみれば当然必要な機能だと思いました。
また、javascriptのstyleでは疑似要素を扱えないので、 直接styleタグを生成させて対応するという技も知ることができました。

-----2015.08.10(修正)-----
総件数が0件の場合と、総件数が1ページに表示する件数より少ない場合の処理を追加しました。
修正前は総件数が0件でも先頭ページが1になっていました。 また、総件数が1ページに表示する件数より小さくても後ろ側の件数が1ページに表示する件数になっていました。

ページャー用関数を準備

最初にページャー用の関数を準備します。この関数にイベントやスタイルなどを追加していきます。


var MkenPagerSimple = function(tagId, totalRow, viewCount){
	// ページャーが表示されるタグ
	this.tagId = tagId;
	// データの総件数
	this.totalRow = Number(totalRow);
	// 1ページに表示する件数
	this.viewCount = Number(viewCount);
	//	現在のページ番号
	this.currentPageNum = 1;
	//	現在のページの先頭行番号
	this.currentPageTopRow = 1;
	// 最終ページ番号
	this.lastPageNum = Math.ceil(this.totalRow / this.viewCount);
};

引数を3個とる関数です。それぞれの引数の意味は、次のとおりです。
1. tagId:ページャーが表示されるHTMLタグのidです(例:<div id="paging"></div>) 2. totalRow:表示するデータの総件数です。 3. viewCount:1ページに表示したい件数です。

プロパティやメソッドの追加(各要素を生成)

前記の関数MkenPagerにプロパティやメソッドを追加していきます。プロトタイプ定義をオブジェクト形式で追加しています。
まずは各要素の生成です。


createHTML: function(){
	// ページャーを囲む枠
	var htmlStr = '<div id="' + this.tagId + 'PagerSimple">';
	// 先頭ボタン
	htmlStr += '<div id="' + this.tagId + 'FirstBtn"></div>';
	// 前へボタン
	htmlStr += '<div id="' + this.tagId + 'PrevBtn"></div>';
	// ページ番号を囲む枠
	htmlStr += '<div id="' + this.tagId + 'Inner">';
	// 表示中のページ番号
	htmlStr += '<div id="' + this.tagId + 'CurrentPageNum">'
			  + this.currentPageNum + '</div>';
	// ページ区切りの枠
	htmlStr += '<div id="' + this.tagId + 'Mark">/</div>';
	// 最終のページ番号
	htmlStr += '<div id="' + this.tagId + 'LastPageNum">'
			  + this.lastPageNum + '</div>';
	htmlStr += '</div>';
	// 次へボタン
	htmlStr += '<div id="' + this.tagId + 'NextBtn"></div>';
	// 最終ボタン
	htmlStr += '<div id="' + this.tagId + 'LastBtn"></div>';
	htmlStr += '</div>';
	// フロートクリア
	htmlStr += '<div id="' + this.tagId + 'clear"></div>';
	
	document.getElementById(this.tagId).innerHTML = htmlStr;
},

プロパティやメソッドの追加(スタイルの設定)

スタイルの設定です。
少し長くなりました。


setStyle: function(){
	// 全体を囲むdiv
	var pager = document.getElementById(this.tagId + 'PagerSimple');
	pager.style.fontSize = "16px";
	// ページ表示部
	var inner = document.getElementById(this.tagId + 'Inner');
	inner.style.width = "100px";
	inner.style.height = "26px";
	inner.style.margin = "0 5px";
	inner.style.border = "2px solid #bbbbbb";
	inner.style.borderRadius = "4px";
	inner.style.backgroundColor = "#fff";
	inner.style.float = "left";
	// 現在のページ番号
	var currentPage = document.getElementById(this.tagId + 'CurrentPageNum');
	currentPage.style.width = "40%";
	currentPage.style.lineHeight = "26px";
	currentPage.style.float = "left";
	currentPage.style.textAlign = "right";
	// ページ番号区切りのマーク
	var mark = document.getElementById(this.tagId + 'Mark');
	mark.style.width = "20%";
	mark.style.lineHeight = "26px";
	mark.style.float = "left";
	mark.style.textAlign = "center";
	// 最終ページ番号
	var lastPage = document.getElementById(this.tagId + 'LastPageNum');
	lastPage.style.width = "40%";
	lastPage.style.lineHeight = "26px";
	lastPage.style.float = "left";
	lastPage.style.textAlign = "left";
	// 先頭ボタン
	var prev = document.getElementById(this.tagId + 'FirstBtn');
	prev.style.width = "26px";
	prev.style.height = "26px";
	prev.style.borderRadius = "3px";
	prev.style.float = "left";
	prev.style.backgroundColor = "#666";
	prev.style.cursor = "default";
	prev.style.opacity = 0.5;
	prev.style.position = "relative";
	prev.style.marginRight = "6px";
	// 前へボタン
	var prev = document.getElementById(this.tagId + 'PrevBtn');
	prev.style.width = "26px";
	prev.style.height = "26px";
	prev.style.borderRadius = "3px";
	prev.style.float = "left";
	prev.style.backgroundColor = "#666";
	prev.style.cursor = "default";
	prev.style.opacity = 0.5;
	prev.style.position = "relative";
	// 次へボタン
	var next = document.getElementById(this.tagId + 'NextBtn');
	next.style.width = "26px";
	next.style.height = "26px";
	next.style.borderRadius = "3px";
	next.style.float = "left";
	next.style.backgroundColor = "#666";
	next.style.cursor = "pointer";
	next.style.position = "relative";
	// 最終ボタン
	var next = document.getElementById(this.tagId + 'LastBtn');
	next.style.width = "26px";
	next.style.height = "26px";
	next.style.borderRadius = "3px";
	next.style.float = "left";
	next.style.backgroundColor = "#666";
	next.style.cursor = "pointer";
	next.style.position = "relative";
	next.style.marginLeft = "6px";

	// javascriptは疑似要素を操作できないので三角マークは下記方法で
	// 変数CSSに定義したいCSSをそのまま記述
	var css =
		// 前へボタンと次へボタンの三角
		"#"+this.tagId+"PrevBtn:before,#"+this.tagId+"NextBtn:before{"+
				"content:'';"+
				"display:block;"+
				"width:0;"+
				"height:0;"+
				"border-top:6px solid transparent;"+
				"border-bottom:6px solid transparent;"+
				"position:absolute;"+
				"top:8px;}"+
		"#"+this.tagId+"PrevBtn:before{"+
				"border-right:9px solid #fff;"+
				"border-left:9px solid transparent;"+
				"right:10px;}"+
		"#"+this.tagId+"NextBtn:before{"+
				"border-right:9px solid transparent;"+
				"border-left:9px solid #fff;"+
				"left:10px;}"+
		// 先頭ボタンと最終ボタンの三角
		"#"+this.tagId+"FirstBtn:before,#"+this.tagId+"LastBtn:before{"+
				"content:'';"+
				"display:block;"+
				"height:0;"+
				"width:0;"+
				"border-top:6px solid transparent;"+
				"border-bottom:6px solid transparent;"+
				"position:absolute;"+
				"top:8px;}"+
		"#"+this.tagId+"FirstBtn:before{"+
				"border-right:9px solid #fff;"+
				"border-left:9px solid transparent;"+
				"right:7px;}"+
		"#"+this.tagId+"LastBtn:before{"+
				"border-right:9px solid transparent;"+
				"border-left:9px solid #fff;"+
				"left:7px;}"+
		// 先頭ボタンと最終ボタンの縦棒
		"#"+this.tagId+"FirstBtn:after,#"+this.tagId+"LastBtn:after{"+
				"content:'';"+
				"display:block;"+
				"height:12px;"+
				"width:2px;"+
				"background:#fff;"+
				"position:absolute;"+
				"top:8px;}"+
		"#"+this.tagId+"FirstBtn:after{"+
				"left:7px;}"+
		"#"+this.tagId+"LastBtn:after{"+
				"right:7px;}";

	// style要素を生成し、変数styleに保持
	var style = document.createElement('style');
	// style要素のテキストノードとして変数CSSの内容を設定
	style.appendChild(document.createTextNode(css));
	//head要素の子要素としてstyle要素を追加
	document.getElementsByTagName('head')[0].appendChild(style);

},

プロパティやメソッドの追加(イベント登録)

イベントを登録します。イベントは「先頭ページ」と「最終ページ」、「前へ」と「次へ」との4個です。


setEvent: function(){
	// イベントのthisはインスタンスではなくイベントの発生元を指すので
	// インスタンスは一旦ローカル変数に代入して使用する
	var self = this;
	var first = document.getElementById(this.tagId + 'FirstBtn');
	var next = document.getElementById(this.tagId + 'NextBtn');
	var prev = document.getElementById(this.tagId + 'PrevBtn');
	var last = document.getElementById(this.tagId + 'LastBtn');
	var currentP = document.getElementById(this.tagId + 'CurrentPageNum');

	// 先頭ボタンクリック **********
	this.addListener(first, 'click', function(){
		// 先頭ページの時は何もしない
		if(self.currentPageNum === 1){
			return;
		}else{
			// 先頭ページにする
			self.currentPageNum = 1;
			// 先頭の行番号も1にする
			self.currentPageTopRow = 1;
		}
		// ボタンスタイル変更
		self.btnStyle(self.currentPageNum);
		// 現在のページ番号を表示
		currentP.firstChild.nodeValue = self.currentPageNum;
	});

	// 前へボタンクリック **********
	this.addListener(prev, 'click', function(){
		// 先頭ページの時は何もしない
		if(self.currentPageNum === 1){
			return;
		}else{
			// 現在のページを減らす
			self.currentPageNum--;
			// 先頭の行番号は表示件数分マイナス
			self.currentPageTopRow = self.currentPageTopRow - self.viewCount;
		}
		// ボタンスタイル変更
		self.btnStyle(self.currentPageNum);
		// 現在のページ番号を表示
		currentP.firstChild.nodeValue = self.currentPageNum;
	});

	// 次へボタンクリック **********
	this.addListener(next, 'click', function(){
		// 最終ページの時は何もしない
		if(self.currentPageNum === self.lastPageNum){
			return;
		}else{
			// 現在のページを増やす
			self.currentPageNum++;
			// 先頭の行番号は表示件数分プラス
			self.currentPageTopRow = self.currentPageTopRow + self.viewCount;
		}
		// ボタンスタイル変更
		self.btnStyle(self.currentPageNum);
		// 現在のページ番号を表示
		currentP.firstChild.nodeValue = self.currentPageNum;
	});
	
	// 最終ボタンクリック **********
	this.addListener(last, 'click', function(){
		// 最終ページの時は何もしない
		if(self.currentPageNum === self.lastPageNum){
			return;
		}else{
			// 現在のページを最終にする
			self.currentPageNum = self.lastPageNum;
			// 先頭の行番号
			self.currentPageTopRow = 
				(self.lastPageNum - 1) * self.viewCount + 1;
		}
		// ボタンスタイル変更
		self.btnStyle(self.currentPageNum);
		// 現在のページ番号を表示
		currentP.firstChild.nodeValue = self.currentPageNum;
	});
	
},

プロパティやメソッドの追加(ボタンのスタイル変更用メソッド)

ページの位置が変わることによるボタンのスタイル変更用です。


btnStyle: function(currentPageNum) {
	var first = document.getElementById(this.tagId + 'FirstBtn');
	var prev = document.getElementById(this.tagId + 'PrevBtn');
	var next = document.getElementById(this.tagId + 'NextBtn');
	var last = document.getElementById(this.tagId + 'LastBtn');
	if(currentPageNum === 1){
		first.style.cursor = "default";
		first.style.opacity = 0.5;
		prev.style.cursor = "default";
		prev.style.opacity = 0.5;
		next.style.cursor = "pointer";
		next.style.opacity = 1;
		last.style.cursor = "pointer";
		last.style.opacity = 1;
	}
	if(currentPageNum > 1 && currentPageNum < this.lastPageNum){
		first.style.cursor = "pointer";
		first.style.opacity = 1;
		prev.style.cursor = "pointer";
		prev.style.opacity = 1;
		next.style.cursor = "pointer";
		next.style.opacity = 1;
		last.style.cursor = "pointer";
		last.style.opacity = 1;
	}
	if(currentPageNum === this.lastPageNum){
		first.style.cursor = "pointer";
		first.style.opacity = 1;
		prev.style.cursor = "pointer";
		prev.style.opacity = 1;
		next.style.cursor = "default";
		next.style.opacity = 0.5;
		last.style.cursor = "default";
		last.style.opacity = 0.5;
	}
},

プロパティやメソッドの追加(イベントのクロスブラウザ対策)

おきまりのIE対策。


addListener: function(elm, ev, listener){
	if(elm.addEventListener) {		// IE以外
		elm.addEventListener(ev, listener, false);
	} else if(elm.attachEvent) {	// IE
		elm.attachEvent('on' + ev, listener);
	} else {
		throw new Error('イベントリスナーに未対応です。');
	}
},

プロパティやメソッドの追加(ページャー表示用メソッド)

いままでのメソッドを集めて、ひとつのページャー表示用メソッドにしてあります。
インスタンスの後にこのメソッドを呼び出してページャーを使用します。


showPager: function(){
	this.createHTML(); // 各要素を生成
	this.setStyle();   // スタイルをセット
	this.setEvent();   // イベントをセット
}

ページャーの使い方

このページのページャーサンプルではidがpagingのdivに表示させています。
データの件数は100件、1ページの表示件数は7件で呼び出ししています。


<head>
	<meta charset="UTF-8">
	<title>団塊爺ちゃんの備忘録</title>
	<link rel="stylesheet" href="index.css">
	<script src="jquery-1.8.0.min.js"></script>
	<script src="mkenPagerSimple.js"></script>
	<script src="index.js"></script>
</head>
<body>
	<div id="paging"></div> <!--ページャーの表示場所-->

↓index.js


var tagId = "paging";
// データの総件数が100件で1ページに7件づつ表示の場合
var pager = new MkenPagerSimple(tagId, 100, 7);
// ページャーの表示
pager.showPager();

// ここから各イベント
// 先頭へボタンクリック
$("#" + tagId + "FirstBtn").on("click", function(){
	action();
});
// 次へボタンクリック
$("#" + tagId + "NextBtn").on("click", function(){
	action();
});
// 前へボタンクリック
$("#" + tagId + "PrevBtn").on("click", function(){
	action();
});
// 最終へボタンクリック
$("#" + tagId + "LastBtn").on("click", function(){
	action();
});
function action(){
	var msg = 
		'現在のページは' + pager.currentPageNum +'ページ目で'+
		'先頭の行番号は' + pager.currentPageTopRow +'行目です。';
	alert(msg);
}

7行目から下がページャーのイベントで、jQueryでイベントを追加しています。
アプリ側で必要なデータはページャーの各プロパティから取得します。
ページの先頭の行番号:pager.currentPageTopRow
などです。