CakePHP 2.x JSヘルパーでajax通信(ajax helperは使わない)

本日の目標が一段落したので、
ビールのみながら技術メモです。

やりたいこと

コメントフォーム。
送信ボタンを押すと、メッセージはデータベースに保存され、
リダイレクトなしで送信完了のメッセージを出す。

まぁこれは一例で、実際の使い方はいろいろ。

画面遷移せずに…
•TODOリストを追加する
•ON/OFFを切り替える
•記事を削除する

とかね。

ヘルパー

AJAXヘルパーってあるんだけど今回は使いません。
AJAX helper

こんなのあるよって教えてもらったんだけど、
更新されてないっぽいしね。2.xでも使えるのは確認してますが。
ダウンロードしてインストールする必要もある。

CakePHPに標準であるJsHelperでできるので、こっちでやります。
JsHelper

コーディング

jQueryはあらかじめ読み込んでおいてください。

app/view/messages/index.ctp

php
1
2
3
4
5
6
7
8
9
10
11
12
<? php
echo $this->Form->create();
echo $this->Form->input('name');
echo $this->Form->input('email');
echo $this->Form->input('message');
echo $this->Js->submit('Send', array(
    'before'=>$this->Js->get('#sending')->effect('fadeIn'),
    'success'=>$this->Js->get('#sending')->effect('fadeOut'),
    'update'=>'#success'
));
echo $this->Form->end();
?>

でどこかに下のようなdivを置いておく。

1
2
div#success
div#sending

  
だいたい通常通りですが、
$this->Form->submit ではなく、
$this->Js->submit としています。

FormHelperがとるオプションはすべて渡せるし、
追加で色々なオプションを渡すことができます。

●before 送信ボタンを押した後にすること(“送信中...”とかを表示する)
div id="sending を出す
●success 送信完了したあとにすること(“送信中...”とかを消す)
div id="sending を消す
●update 処理が終わった後にここで指定した要素の中身を書き換えます
div id="success" は今は空っぽだけど、送信後に何か入ります。

そうすると、Jsヘルパーがjavascriptを作ってくれます。
作ってくれるんだけど、このままでは出力される場所があませんので指定してあげます。
下記をbody閉じタグの直前に書く。

1
<? php echo $this->Js->writeBuffer(); ?>

そうすると、JsHelperで作られたすべてのスクリプトがここに出力される。

でもそうされると困る場合もあるので、そんな時はオプションに
'buffer' => false
を追加しましょう。そうするとフォームが出力されたすぐ後にjavascriptが出力されます。

MessagesController.ctp

php
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<? php
class MessagesController extends AppController {
    public $helpers = array('Js');
    public $components = array('RequestHandler');

    public function index() {
        //データが空でないかチェック
        if (!empty($this--->data)) {
            //もし保存がうまくいったら
            if ($this-&gt;Message-&gt;save($this-&gt;data)) {
                //もしリクエストがajaxだったら
                if ($this-&gt;RequestHandler-&gt;isAjax()) {
                    //ajaxレイアウトを使って、success.ctpを出力
                    $this-&gt;render('success', 'ajax');
                }
                //(念のため)リクエストがajax以外なら
                else {
                        //メッセージをセットしてリダイレクト
                    $this-&gt;Session-&gt;setFlash('Message sent');
                    $this-&gt;redirect(array('action'=&gt;'index'));
                }
            }
        }
    }
}

public $helpers = array('Js');
でJSヘルパーを読み込む。
JSじゃないですよ。コードには'Js'と書いてください。

public $components = array('RequestHandler');
はリクエストがajaxかどうか判別するのに必要です。

$this->render('success', 'ajax');
ここがポイントすね。

successはビューファイル。ajaxはレイアウトファイルです。
app/view/messages/success.ctp の内容が
app/view/messages/index.ctp の div id="success" の中に出力されます。

app/view/Layouts/ajax.ctp

1
2
<!--これだけ-->
<? php echo $this -> fetch('content'); ?>

app/view/messages/success.ctp

1
2
<!--送信完了メッセージ-->
メッセージが送信されました!

以上です。

1.メッセージを入力
2.送信ボタンをクリック
3.“送信中...”を表示
4.“送信中...”が消える
5.メッセージがデータベースに保存される
6.送信完了をお知らせ

という流れになるはず。

参考ビデオ

とても分かりやすいです。英語だけど。
Cakephp Ajax Tutorial - Using Cakephp's Js Helper and jQuery

何かありましたらコメントをどうぞ

comments powered by Disqus

人気の記事

950 Points チリ出身のギタリストが弾くドラゴンボールZがむちゃくちゃかっこいい…
774 Points Wordpress + Heroku + PostgreSQL + Amazon S3 = ¥0 / 無料でサイト運営
700 Points Rubyのチートシート 変数 / クラス / モジュール
524 Points Rubyのチートシート / アクティブサポート
451 Points 紙のデザイナーがウェブ開発できるようになるまでに必要なこと
435 Points Rails / Google Analyticsのデータを使って分析や管理画面のためのグラフをつくる
323 Points RailsとHerokuでノーティフィケーションをプッシュする / PusherとTurbolinksの兼ね合い
222 Points Rails / RSpec テスト書いたことない メンドクサイ(n´Д`)という時のチートシート
193 Points Rails / Ajaxを使って画面遷移しない一時保存機能をつける
193 Points Protractorでスクレイピングしてみた