CAKEPHP4でajaxを使ったページング処理
一覧画面などでよくあるajaxを利用したアレの実装例です。
CAKEPHP4でのコーディングを想定しています。
取得するDBのデータはidとnameカラムを持つItemsテーブルを想定します。
 

初期表示部分の実装
controller/ItemsController.php
namespace App\Controller\Mypage;
class ItemsController extends AppController{
	/**
	 * 一覧ページ用のaction
	 */
	public function index(){
		//1ページ当たりの件数
		$perpage = 5;
		$items = $this->Items->find();
		//レコードの総数を取得
		$count = $items->count();
		//初期表示件数
		$items->orderDESC('id')->limit(5);
		//変数をtemplateファイルに渡す
		$this->set(compact(['items', 'count', 'perpage]));
	}
}
templates/Items/index.php
一覧を表示させるテンプレートファイルです。
初期値としてItemsControllerのindexから5件分のデータが渡ります。
 
<div class="contents">
	<div id="list">
		<?php foreach($items as $item): ?>
		<div class="item"><?= $item->name ?></div>
		<?php endforeach; ?>
	</div>
	<button id="btn-ajax-more">もっと見る</button>
</div>
追加表示部分の実装
 
追加読み込みするデータを取得するための処理をItemsControllerにactionを追加して記述していきます。
 
controller/ItemsController.php
	public function more($page){
		if($this->request->is('ajax')){
			$this->viewBuilder()->enableAutoLayout(false);
			$this->paginate = [
				'order' => ['id' => 'DESC'],
				'limit' => 5,
				'page' => $page,
			];
			$this->set('items',$this->paginate($this->Items));
		}
	}
 
Layoutを読み込んでいる場合enableAutoLayout(false)でLayoutを使わないようにする必要がありますがこちらの関数名がCAKEPHP3以下と変更されているので注意が必要です。
こちらの処理を追加することで「/items/more/2」のURLをajaxで読み込むことで2ページ目の情報が取得できます。
 
templates/Items/more.php
moreで取得した情報を出力するためのtemplateファイルです。
単純に一覧の中身のHTMLと取得したレコードのnameを出力するだけのコードです。
 
<?php foreach($items as $item): ?>
<div class="item"><?= $item->name ?></div>
<?php endforeach; ?>
追加読み込み実行のためのjavascriptの実装
templates/Items/index.php
追加読み込み時の処理をjavascript(JQuery)で追加していきます。
 
$(function(){
	var isLoading = false;
	var page = 1;
	var count = <?= $count ?>;
	var perpage = <?= $perpage ?>;
	var url = '<?= $this->Url->build(['controller'=>'Items','action'=>'more']) ?>'
	$('#btn-ajax-more').on('click', function(){
		if(!isLoading){
			$(this).html('loading...')
			isLoading = true
			page++
			$.ajax({
				url: url + '/' + page,
				type: 'POST',
			})
			.done( function(data){
				$(data).appendTo($('#list')).hide().slideDown(200)
				if(count > (perpage * page)){
					$('#btn-ajax-more').html('もっと見る')
				} else {
					$('.link-more').remove()
				}
				isLoading = false
			})
		}
	})
})
 
ajax実行ごとにControllerに渡るurlのページ数を加算していくことでページ数に対応したデータが取得され最終的に#listのHTML末尾に追加表示されます。
また、変数isLoadingがfalseの場合のみajaxが実行されるようにし追加読み込みの連打など想定されない挙動に対処し、総件数よりも表示件数が上回った場合ボタンを表示させないように実装します。
 
以上、CAKEPHP4で実装する一覧表示をajaxで追加読み込みするアレの簡単な実装でした。