PAGE TOP


jQuery ajax ボタンを押すとごとに次のデータ数件を表示する

2017年6月24日Javascript

実装概要

データの一覧を表示しますが、一般的なものは、例えば、1ページ目に、20件を表示して、ページの下部に、1・2・3・4… [最後]  のように、次の20件ごとの番号にリンクしています。今回は、このような形式ではなく、ページの下部に、ボタンを設置し[次の20件]のように、ボタンを押すごとに、データが非同期で追加されていくようにします。また、元に戻すことのできるように[リセット]ボタンを設置します。

WEB開発のことなら福井県敦賀市 SumiDaiNET(すみだいねっと)

まずはデータベースの準備

準備するデータは、なんでもよいのですが、検証の為、とりあえず、100件以上位はあったほうがよいかもしれません。
・テーブル作成 data_01テーブル

CREATE TABLE data_01(
id bigint(20) NOT NULL AUTO_INCREMENT,
title varchar(30) NOT NULL,
date timestamp NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP,
PRIMARY KEY (`id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8;

・挿入するデータ

INSERT INTO data_01 (title) VALUES
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’),
(‘SumiDaiNET テストデータ’);

とりあえず、10件分の挿入ですが、実際は、100件ほどあったほうがよいので、コピペして、挿入箇所だけ複製する、又は、クエリを繰り返すなどして、挿入データを増やしてください。

データベースの準備が完了したら、db.phpにMySQLに接続情報を記載します。それをあとで読み込んで使うようにします。(このあたりは、host dbname $user $password の部分は、環境にあわせて、変更してください。)
db.php

<?php
 
function db_connect(){
	$dsn = 'mysql:host=localhost;dbname=sample;charset=utf8';
	$user = 'root';
	$password = 'japan';
	
	try{
		$dbh = new PDO($dsn, $user, $password);
		return $dbh;
	}catch (PDOException $e){
	    	print('Error:'.$e->getMessage());
	    	die();
	}
}
 
?>

index.phpの解説

まずは、上部のPHPコードから解説します。ここで、db.phpの接続情報を読み込み、接続します。ページが開かれると、変数$offset = 0 ,$limit = 25 で、sqlクエリのデータにLIMIT句をつけて、0の次から、25件を上限として取り出します。また、ボタンに、残りの件数を表示することから、データのトータル件数をSQL_CALC_FOUND_ROWSを使い取得し、25を差し引きます。(25件は表示されている為)。

<?php

require_once("db.php");
$dbh = db_connect();

$offset = 0;
$limit = 25;

try{
   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $sql = "SELECT SQL_CALC_FOUND_ROWS id, id, title, date FROM data_01 LIMIT $offset, $limit";
   $stmt = $dbh->query($sql);
   $data = $stmt->fetchAll();

   $stmt = $dbh->query('SELECT FOUND_ROWS()');
   $data['count'] = $stmt->fetch(PDO::FETCH_ASSOC);
   $data['count'] = $data['count']['FOUND_ROWS()']-$limit;
   
}catch (PDOException $e){
   print('Error:'.$e->getMessage());
   die();
}
?>

次に、javascriptの解説です。大きくわけて、3つの処理があります。上から順番に、ページを開いたときの表示、[次へ]のボタンと[リセット]ボタンを押したときの処理の3つに分かれます。特にコアな部分は、[次へ]のボタンを押したときのajaxでの処理で、外部のget_data.phpに変数offsetの値をPOSTで引き渡して、get_data.phpで、取得した次の件数の25件を取得します。

<script>
$(document).ready(function(){
    var set = 25;
    var ck = 0;    //[次へ]のクリックの回数
    var total = <?=$data['count']?>;  //残りの件数

    if(set + total > set){            //件数が25件よりも小さい場合
      $('#total').html(total+'件');  //残り件数の表示
      $('#set').html(set+'件');       //件数の表示
      $('#reset').hide();        //[リセット]ボタンを隠す
    }else{                           //件数が25件よりも大きい場合
      $('#more').hide();       //[次へ]の表示ボタンを隠す
      $('#reset').hide();    //[リセット]ボタンを隠す
    }
    
     $('#more').click(function(){   //[次へ]の件数表示ボタンを押したときの処理↓
   
         $('#reset').show();    //[リセット]ボタンの表示
              
         ck ++;
         offset = set * ck;
         
         if(total >= 0){
           total -= set;
         }
         
         if(total < set){
           $('#set').html(total+'件');
         }

     $.ajax({
        url: 'get_data.php',    //送信先
        type: 'POST',
        data: { 'offset': offset },
        timeout: 10000,
        dataType: 'text'
        })
      .done(function( data ) {
         //alert("確認" + data);
        $('#add').append(data);     //#addに追加
           if(total <= 0){        //#totalの書き換え
             $('#total').text('0件');      
           }else{
             $('#total').text(total+'件');
           }
        });

         if(total <= 0){
           $('#more').hide();
         }

  return false;

  });

  $('#reset').click(function(){   //[リセット]の件数表示ボタンを押したときの処理↓
       ck = 0;
       total = <?=$data['count']?>;
       $('#more').show();
       $('#reset').hide(); 
       $('#set').html(set+'件');
       $('#add').empty();
       $('#total').text('<?=$data['count']?>件');
  });
});
</script> 


<?php foreach ($data as $key => $value){ ?>
    <?=$value['id'] ?><?=$value['title'] ?><?=$value['date'] ?><br>
<?php } ?>
<div id="add"></div> 

<button id="more" type="button" class="btn btn-default"> >> <?php if (isset($data)){ ?>次の<span id="set"></span>表示 <?php } ?> (あと <?php if (isset($data)){ ?> <span id="total"></span> <?php } ?>) </button>
<a href="#top"><button id="reset" type="button" class="btn btn-default">リセット</button></a>

get_data.phpの解説

こちらのファイルは、index.phpよりajaxで呼びだしているわけですけど、見て分かるように、受け取ったデータをLIMIT句に挿入して、データの取得件数の開始場所をずらしいてるだけですので、ぼぼindex.phpと同じものになります。

<?php

require_once("db.php");
$dbh = db_connect();

$offset = $_POST['offset'];
$limit = 25;

try{
   $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
   $sql = "SELECT SQL_CALC_FOUND_ROWS id, id, title, date FROM data_01 LIMIT $offset, $limit";
   $stmt = $dbh->query($sql);
   $data = $stmt->fetchAll();

     $stmt = $dbh->query('SELECT FOUND_ROWS()');
    $data['count'] = $stmt->fetch(PDO::FETCH_ASSOC);
   $data['count'] = $data['count']['FOUND_ROWS()']-$limit;
   
}catch (PDOException $e){
   print('Error:'.$e->getMessage());
   die();
}
?>
<?php foreach ($data as $key => $value){ ?>
    <?=$value['id'] ?><?=$value['title'] ?><?=$value['date'] ?><br>
<?php } ?>
<div id="add"></div>

感想

今回の実装では、非常にシンプルなものを作りました。セキュリティー面での考慮はあまり考えずにつくりましたので、気になる方は、独自で対策をしてみてください。