【CakePHP】Ajaxを使ったバリデーション

【CakePHP】Ajaxを使ったバリデーション

どうもfujiharaです。

本当にナツいですね。皆さん体調管理には十分ご注意下さい。と先週風邪を引いた私が言っても説得力がないですが...

本日はAjaxを使用したCakePHPのバリデーションをご紹介いたします。

基本的な新規登録ページにAjax処理を追加します。

処理の流れは以下になります。

1.入力中のフォームフォーカスが外れたときに入力値の妥当性チェック。(Ajax通信)

2.エラーの場合は1で取得したメッセージを表示。
(そうでない場合はエラー文章を取り除く)

ここでは基本的な新規登録に関するビューの書き方などは省きます。詳しくは以下をご参照下さい。

CakePHPチュートリアル

テーブルは以下となっております。

テーブル: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' としています。

最後にエンコードして吐き出して処理は終了です。

最後に実装したものの画像を表示しておきます。

バリデートには入力必須と最小文字数を設定しています。

通常画面

20140716_fujiwara_01.png

入力必須時

20140716_fujiwara_02.png

最小文字数

20140716_fujiwara_03.png

(参考)通常のPOSTにおけるエラー

20140716_fujiwara_04.png

以上でCakePHPのAjaxを使用したバリデーションでした。

Ajax 処理の前後のアニメーションなどでカスタマイズすることでさらにユーザビリティが 上がると思います。是非お試し下さい。

  • このエントリーをはてなブックマークに追加

この記事を読んだ人にオススメ