質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.50%
CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

Q&A

解決済

1回答

744閲覧

Ajaxを使うと、Paginatorのアクティブリンクが動かなくなる?

nnafa

総合スコア12

CakePHP

CakePHPは、PHPで書かれたWebアプリケーション開発用のフレームワークです。 Ruby on Railsの考え方を多く取り入れており、Railsの高速性とPHPの機動性を兼ね備えています。 MVCやORMなどを「規約優先の考え方」で利用するため、コードを書く手間を省くことができます。 外部のライブラリに依存しないので、単体での利用が可能です。

0グッド

0クリップ

投稿2018/11/29 12:22

編集2018/11/29 12:35

前提・実現したいこと

CakePHP3でAjaxを使ったページネーションを作成しています。

発生している問題・エラーメッセージ

「該当のソースコード」に記載したソースコードにてページネーションで不具合が発生しております
具体的には、ページネーションの現在のページを表すスタイルがページを移動しても最初のページを指したままになってしまいます
開発者ツール、CakePHPで表示されてるエラーはありません

原因が複数のコントローラーをまたいでPaginatorを使っているからだと考えました
そこで、Paginatorに何か仕掛けをする必要があると考えましたが、妙案が思いつかないため質問いたしました

該当のソースコード

動作確認に必要そうなコントローラ、ビューファイルを追記いたしました
不足な点があれば、修正依頼を頂けると幸いです

ArticleTables.php

php

1<?php 2namespace App\Model\Table; 3 4use Cake\ORM\Table; 5use Cake\Validation\Validator; 6 7class ArticlesTable extends Table 8{ 9 public function initialize(array $config) 10 { 11 $this->addBehavior("Timestamp"); 12 $this->hasMany("Comments") 13 ->setDependent(true); 14 } 15 16 public function validationDefault(Validator $validator) 17 { 18 $validator 19 ->notEmpty("title") 20 ->requirePresence("title") 21 ->notEmpty("name") 22 ->requirePresence("name") 23 ->notEmpty("body") 24 ->maxLength("body", 140, "本文は140文字以内です。") 25 ->requirePresence("body"); 26 27 return $validator; 28 } 29}

CommentsTable.php

php

1<?php 2namespace App\Model\Table; 3 4use Cake\ORM\Table; 5use Cake\Validation\Validator; 6 7class CommentsTable extends Table 8{ 9 public function initialize(array $config) 10 { 11 $this->addBehavior('Timestamp'); 12 $this->belongsTo("Articles"); 13 } 14 15 public function validationDefault(Validator $validator) 16 { 17 $validator 18 ->notEmpty('title') 19 ->requirePresence('title') 20 ->notEmpty('body') 21 ->requirePresence('body'); 22 23 return $validator; 24 } 25}

ArticleController.php

php

1<?php 2namespace App\Controller; 3 4class ArticlesController extends AppController 5{ 6 public $paginate = [ 7 'limit' => 5, 8 'maxLimit' => 10 9 ]; 10 11 // 省略 12 13 public function view($id = null) 14 { 15 $article = $this->Articles->get($id); 16 $comment = $this->Articles->Comments->newEntity(); 17 $query = $this->Articles->Comments->find()->where(["article_id" => $id]); 18 $this->set(compact("article", "comment")); 19 $this->set("comments", $this->paginate($query)); 20 }

CommentsController.php

php

1<?php 2namespace App\Controller; 3 4class CommentsController extends AppController 5{ 6 public $paginate = [ 7 'limit' => 5, 8 'maxLimit' => 10 9 ]; 10 11 public function initialize() 12 { 13 parent::initialize(); 14 $this->loadComponent('Security'); 15 $this->loadComponent('Paginator'); 16 $this->loadComponent('RequestHandler'); 17 } 18 19 // 省略 20 21 public function get() 22 { 23 $id = $this->request->getQuery("article_id"); 24 $query = $this->Comments->find()->where(["article_id" => $id]); 25 $this->response->charset("UTF-8"); 26 $this->response->type("json"); 27 $response = ($this->paginate($query)); 28 $this->set("response", $response); 29 $this->set("_serialize", ["response"]); 30 } 31}

view.ctp

ctp

1<?php 2<h1><?= h($article->title) ?></h1> 3<p><?= h($article->name) ?></p> 4<h1><?= h($article->title) ?></h1> 5<p><?= h($article->name) ?></p> 6<p><?= h($article->body) ?></p> 7<p><small>Created: <?= $article->created->format(DATE_RFC850) ?></small></p> 8<hr> 9 10<?php 11 echo $this->Form->create($comment, ["url" => ["controller" => "Comments", "action" => "add"]]); 12 echo $this->Form->control('title'); 13 echo $this->Form->control('body', ['rows' => '3']); 14 echo $this->Form->hidden("article_id", ["default"=>h($article->id)]); 15 echo $this->Form->button(__('Save Article')); 16 echo $this->Form->end(); 17?> 18<?php if (!$comments->isEmpty()): ?> 19 20 <?php foreach ($comments as $comment): ?> 21 <?php var_dump($comment) ?> 22 <?php endforeach; ?> 23 <?php $this->Paginator->options([ 24 'url' => [ 25 'controller' => 'Comments', 26 'action' => 'get' 27 ] 28 ]); ?> 29 <ul class="pagination"> 30 <?= $this->Paginator->first('<<') ?> 31 <?= $this->Paginator->prev('<') ?> 32 <?php if (!empty($this->Paginator->numbers())): ?> 33 <?= $this->Paginator->numbers() ?> 34 <?php else: ?> 35 <li><?= $this->Paginator->current("Comments") ?></li> 36 <?php endif; ?> 37 <?= $this->Paginator->next('>') ?> 38 <?= $this->Paginator->last('>>') ?> 39 </ul> 40<?php else: ?> 41 <p>この記事にはまだコメントがありません。</p> 42<?php endif; ?> 43 44<hr> 45 46<div id="result"> 47</div> 48 49 50<script> 51 $(function () { 52 $(".pagination a").on("click", function () { 53 $.getJSON($(this).attr("href"), { article_id: <?= $article->id ?> }, function (data){ 54 $("#result").text(data); 55 console.log(data); 56 }); 57 return false; 58 }); 59 }); 60</script>

Commentsテーブルの構造も記載いたします。
article_idに外部キーを用いてコメントの属する記事を参照するようにしています。

sql

1CREATE TABLE `comments` ( 2 `id` int(11) NOT NULL AUTO_INCREMENT, 3 `article_id` int(10) unsigned NOT NULL, 4 `title` varchar(255) NOT NULL, 5 `body` text, 6 `created` datetime DEFAULT NULL, 7 PRIMARY KEY (`id`), 8 KEY `article_key` (`article_id`), 9 CONSTRAINT `comments_ibfk_1` FOREIGN KEY (`article_id`) REFERENCES `articles` (`id`) 10) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8mb4

試したこと

  • getアクションをこのように変更⇒効果なし

php

1 public function get() 2 { 3 $this->autoRender = false; 4 $id = $this->request->getQuery("article_id"); 5 $query = $this->Comments->find()->where(["article_id" => $id]); 6 $response = ($this->paginate($query)); 7 echo json_encode($response); 8 }
  • jQueryでのレスポンスの受け取り方を変えてみる⇒変化なし

何かエラーに心当たりのある方がいらっしゃいましたら、教えていただけますと幸いです
よろしくお願いいたします

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

popobot

2018/11/29 21:54 編集

削除済み(質問を勘違いしていた...)
guest

回答1

0

ベストアンサー

Ajaxで、次のコメント情報を取得しても、HTMLが書き換わるわけではないので、ページネートのアクティブリンクが移動することはありません。
jQueryなどを利用して、自分で表示を切り替える必要があります。

Ajaxではなく、ページ遷移させれば、アクティブリンクは移動させることができると思います。その場合、ArticlesControllerのviewアクションでcommentsのページネートをするような実装になるかと

投稿2018/11/29 21:57

編集2018/11/29 21:58
popobot

総合スコア6586

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

nnafa

2018/11/30 13:59

> jQueryなどを利用して、自分で表示を切り替える必要があります。 なるほど、そこはPaginator Helperが`$this->paginate($query)`を読んでよしなにしてくれると思っていました。なのでコントローラーでの処理がおかしいのかとばかり思い込んでしまい・・・ jQueryで書き換える際に、Paginator Helperが使えないのではと思うのですが、これもAjaxでやる場合には仕方の無いことなのでしょうか?
popobot

2018/11/30 22:36

仕方ないと思います。 Ajaxでjsonをもらう代わりに、コメント一覧+ページネート部分のHTMLを取得して、その部分のDOMを丸ごと置き換えるという方法ならPaginator Helperが使えるかもですが...
popobot

2018/11/30 22:41

Ajaxでやりたいなら、「もっと見る」みたいにして、コメントを下に追加されるような処理にするとか。Vuejsなどを使ってページネートの描画はすべてjs側にやらせるとかした方がスマートかもですね
nnafa

2018/12/01 10:20

ご返信ありがとうございます。 > Ajaxでやりたいなら、・・・ 確かにそのようにすればページネート部分を考えなくていいので、ページネーションを作るより作成が簡単そうです > Ajaxでjsonをもらう代わりに json形式で受け取るメリットもあまりないですし、html形式で返してしまってもいいかもしれないですね。ビューで使うヘルパーをコントローラで使ってしまうのでソースコードを読む時に違和感がある(?)かもしれませんが、アニメーションの工夫をすれば、Webページの閲覧者側の違和感はなさそうです > Vuejsなどを使って・・・ Paginator Helperが使いたいならAjaxで帰ってくるhtmlにページネートを含めておく、使わなくていいなら全部自前で作るかページネート以外の方法を探すということですね よくよく考えれば、Paginator HelperはHTMLテンプレートを使ってマークアップを生成するだけのヘルパーなので、無理して使う利点はないのかもしれないです・・・。フレームワークが用意してくれたものはできるだけ使うべきだと思っていたのがいけなかったです とても勉強になりました。 このたびはお付き合い頂き、どうもありがとうございました!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.50%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問