ページング機能を実装する

前回の続き。今まで全画像を表示していたが、ページに表示する画像数を決めて、下部に各ページへのリンクを設定した。

成果物:ranking.html (ページ移動のリンクを追加)

メモ

  • PHPプログラム(ranking.php)を実行する際にパラメータでページ番号を渡している
  • JavaScriptでURLのパラメータ(?以降の文字列)を取得するのにgetUrlVars()を使った
  • ページング部分は、1ページに表示する画像数(PHPで’IMAGENUM_PER_PAGE’を定義した)を決めて登録画像数がわかると、ページの開始インデックス(offset)と全ページ数は計算できる。
  • SQLで何件目からどれだけ取得するかは、SELECT文にLIMIT offset(0スタート), numberを付ける。
  • $offset = IMAGENUM_PER_PAGE * ($page - 1);
    $sql = "select * from mobile_capture_showcase where status='active' order by counter desc limit ".$offset.", ".IMAGENUM_PER_PAGE;
    $items = array();
    foreach ($dbh->query($sql) as $item) {
    	array_push($items, $item);
    }
    
    $totalnum = $dbh->query("select count(*) from mobile_capture_showcase")->fetchColumn();
    $totalpage = ceil($totalnum / IMAGENUM_PER_PAGE);
    
  • JavaScriptでカウントアップのつもりで+1しても文字列連結になる場合があるから、変数に+を付けて数値にキャストした
    if (page < totalpage) {
    	$('#paging').append('<a href="?page='+(+page+1)+'">次</a>');
    }
    else {
    	$('#paging').append('次');
    }
    

ソースコード
ranking.html

<!DOCTYPE HTML>
<html lang="ja">
<head>
	<meta charset="UTF-8">
	<title>スマホキャプチャーギャラリー</title>
</head>
<body>
	<a href="index.html">Home</a> | <a href="upload.html">アップロード</a> | <a href="ranking.html">人気順</a>  | <a href="latest.html">新着順</a>

	<p>ランキングページ[ranking.html]</p>
	<div id="ranking"></div>
	<div id="paging"></div>

	<script src="//ajax.googleapis.com/ajax/libs/jquery/1.9.0/jquery.min.js"></script>
	<script type="text/javascript" src="./function.js"></script>
	<script type="text/javascript">
		$(document).ready(function() {
			var page = getUrlVars()['page'];
			if (page === undefined) {
				page = 1;
			}

			$.ajax({
				type: "GET",
				url: "ranking.php",
				data: { page: page },
				success: function(json_data) {
					/*
					パラメータ(json_data):ranking.phpの処理結果
					{
						"items":{
									{"id":"xx", "name":"xx", ...},
									{"id":"xx", "name":"xx", ...},
									...
								},
						"totalnum":"xx",
						"totalpage":"xx"
					}
					*/

					// 画像部のHTML生成
					$.each(json_data.items, function(index, data) {
						$('#ranking').append(
							'<a href="item.php?id='+data.id+'"><img src="./images/'+data.filename+'" alt="image" width="160" /></a> '
						);
					});

					// ページング部のHTML生成
					var totalpage = json_data.totalpage;
					if (page > 1) {
						$('#paging').append('<a href="?page='+(page-1)+'">前</a>');
					}
					else {
						$('#paging').append('前');
					}

					for (var i=1; i<=totalpage; i++) {
						// 現在ページの番号を強調する
						if (page == i) {
							$('#paging').append('<strong><a href="?page='+i+'">'+i+'</a></strong>');
						}
						else {
							$('#paging').append('<a href="?page='+i+'">'+i+'</a>');
						}
					}

					if (page < totalpage) {
						$('#paging').append('<a href="?page='+(+page+1)+'">次</a>');	// "page+1"だと文字列結合になるから+pageにして数値型に変換している
					}
					else {
						$('#paging').append('次');
					}
				}
			});
		});
	</script>
</body>
</html>

ranking.php

<?php
// パラメータの確認
if (preg_match('/^[1-9][0-9]*$/', $_GET['page'])) {
	$page = (int)$_GET['page'];
}
else {
	$page = 1;
}

header('Content-Type: application/json; charset=utf-8');
echo json_encode(get_ranking($page));

function get_ranking($page) {
	require_once('config.php');

	try {
		$dbh = new PDO(DSN, DB_USER, DB_PASS);
	} catch(PDOException $e) {
		var_dump($e->getMessage());
		exit;
	}

	// page offset count
	// 1    0      3
	// 2    3      3
	// 3    4      3
	// 4    7      3
	$offset = IMAGENUM_PER_PAGE * ($page - 1);
	$sql = "select * from mobile_capture_showcase where status='active' order by counter desc limit ".$offset.", ".IMAGENUM_PER_PAGE;
	$items = array();
	foreach ($dbh->query($sql) as $item) {
		array_push($items, $item);
	}

	$totalnum = $dbh->query("select count(*) from mobile_capture_showcase")->fetchColumn();
	$totalpage = ceil($totalnum / IMAGENUM_PER_PAGE);

	$dbh = null;

	// ランキング取得に必要なデータを返却
	// array(
	// 		"items" => array(
	// 					array("id"=>"xx", "name"=>"xx", ...),
	//					array("id"=>"xx", "name"=>"xx", ...),
	//					...
	//				   ),
	//		"totalnum" => "xx",
	//		"totalpage" => "xx"
	// );
	$ret = array("items" => $items, "totalnum" => $totalnum, "totalpage" => $totalpage);
	return $ret;
}
?>

function.js

function getUrlVars()
{
    var vars = [], hash;
    var hashes = window.location.href.slice(window.location.href.indexOf('?') + 1).split('&');
    for(var i = 0; i < hashes.length; i++)
    {
        hash = hashes[i].split('=');
        vars.push(hash[0]);
        vars[hash[0]] = hash[1];
    }
    return vars;
}

参考サイト

パーフェクトJavaScript (PERFECT SERIES 4)
井上 誠一郎 土江 拓郎 浜辺 将太
技術評論社
売り上げランキング: 60,832
パーフェクトPHP (PERFECT SERIES 3)
小川 雄大 柄沢 聡太郎 橋口 誠
技術評論社
売り上げランキング: 24,082

関連エントリー

  1. PHPのPDOでMySQLデータベースのデータを取得する3(指定キーワードを含むデータのみを取得する)
  2. jQuery.ajaxでPHPプログラムに処理要求を出す
  3. PHPのPDOでMySQLデータベースのデータを削除する(投稿の削除)
  4. PhoneGapお試し(iOS)
  5. jQuery.ajaxでPHPプログラムに処理要求を出したい
This entry was posted in 未分類 and tagged , , , . Bookmark the permalink.