【CakePHP】Ajaxを使ったバリデーション
どうもfujiharaです。
本当にナツいですね。皆さん体調管理には十分ご注意下さい。と先週風邪を引いた私が言っても説得力がないですが...
本日はAjaxを使用したCakePHPのバリデーションをご紹介いたします。
基本的な新規登録ページにAjax処理を追加します。
処理の流れは以下になります。
1.入力中のフォームフォーカスが外れたときに入力値の妥当性チェック。(Ajax通信) 2.エラーの場合は1で取得したメッセージを表示。 (そうでない場合はエラー文章を取り除く)
ここでは基本的な新規登録に関するビューの書き方などは省きます。詳しくは以下をご参照下さい。
テーブルは以下となっております。
テーブル:posts カラム :title(varchar) ,body(text)
ビューファイル
<div class="posts form">
<?php echo $this->Form->create('Post'); ?>
<fieldset>
<legend><?php echo __('新規追加'); ?></legend>
<?php
echo $this->Form->input('title', array(
'id' => 'title', //追加1
'class' => 'ajax-check', //追加2
));
echo $this->Form->input('body', array(
'id' => 'body', //追加1’
'class' => 'ajax-check', //追加2’
));
?>
</fieldset>
<?php echo $this->Form->end(__('送信')); ?>
</div>
<div class="actions">
<h3><?php echo __('管理'); ?></h3>
<ul>
<li><?php echo $this->Html->link(__('一覧'), array('action' => 'index')); ?></li>
</ul>
</div>
---------------------------追加部分---------------------------------
<script>
$('.ajax-check').on('blur', function() { // 3 (トリガー)
var target = $(this).parent(); // 4 (挿入部)
var key = $(this).attr('id');
var checkData = {'key': key, 'value': $(this).val()};
// 5 (POSTデータ)
$.ajax({
type:'POST',
url:'/posts/ajaxValidate',
data:checkData
}).done(function(data) { // 6 (結果処理)
data = JSON.parse(data);
target.children('div.error-message').each(function() {$(this).remove();});
// 7 (エラーを削除)
if (!data.check) { // 8 (エラー判定)
target.append(data.message);
}
});
});
</script>
では順を追って説明します。 コメント部分と----script----以下はCakePHPの Bakeで 作成したものです。
CakePHP側での追加部分は追加1,2, 追加1',2'となります。
この部分ではフォームIDにカラム名(title, body), クラス名にajax-checkという名前を設定しています。
そしてscript部分です。
3. トリガーは ajax-check クラスであるフォームのフォーカスが外れたときになります。
4. ここでは入力しているフォームの親要素を指定しています。エラーがある場合はメッセージを ここに追加します。
5. バリデーションを行うためのデータをここで整形しています。 key にカラム名、value に 入力値を設定し、 ajax で post しています。
6. 結果処理になります。
7. 取得したデータが json になっているので、パース後チェックしたフォーム以下に表示されているエラーを 一度すべて削除します。(削除するクラス名(error-message)は任意です)
8 最終的に取得したデータのcheck 項目が false だった場合には 4で指定した部分にメッセージを追加します。
以上でビュー側の処理は終了です。 それでは引き続き、コントローラ側の処理を見ていきます。コントローラ側ファンクション
public function ajaxValidate() {
if ($this->request->is('ajax')) {
$key = $this->request->data['key']; //カラム
$data = array('Post' => array( //チェックデータ
$key => $this->request->data['value']
));
$check = array('check' => true); // リターン用配列
$this->Post->set($data); // バリデーション準備
if (!$this->Post->validates()) { // バリデート(エラー時)
$check['check'] = false; // check 判定値変更
$check['message'] = "<div class=\"error-message\">" .
$this->Post->validationErrors[$key][0]. "</div>";
// エラーメッセージ設定
}
$this->render(false, 'ajax'); // Renderなし、Layout = ajax
echo json_encode($check); // デコードし出力
exit;
}
throw new MethodNotAllowedException('不正なアクセスです。');
}
まず、一行目でAjax 通信判定を行っています。そうでない場合はエラーを出力しています。
次にバリデーションを行うための配列を作成します。key がカラムに対応して、valueが入力値になります。
そして ajax 完了後の吐き出すための配列をセットします。check が false の場合はエラーが"アリ"というようにしています。
バリデーション実行し、エラーがある場合は check を false に変更し、出力するメッセージをセットします。
ビュー側で削除するクラス名と同じにする必要があります。
json 出力を行いますので Render:Layout の設定を なし:'ajax' としています。
最後にエンコードして吐き出して処理は終了です。
最後に実装したものの画像を表示しておきます。
バリデートには入力必須と最小文字数を設定しています。
通常画面
入力必須時
最小文字数
(参考)通常のPOSTにおけるエラー
以上でCakePHPのAjaxを使用したバリデーションでした。
Ajax 処理の前後のアニメーションなどでカスタマイズすることでさらにユーザビリティが 上がると思います。是非お試し下さい。