LoginSignup
15
19

More than 5 years have passed since last update.

CakePHP3 Ajaxを使ったバリデーション

Last updated at Posted at 2015-08-10

こちらを参考にして、CakePHP3でAJAXを使ったバリデーションに挑戦してみました。

前提

  • フォームのフォーカスが外れた際に、validationを実行する
  • フォーカスを得たときにメッセージをクリアする
  • friendsofcakeのbootstrap-uiプラグインを使用している
    CakePHP3でtwitter bootstrapを使う(導入編)

Javascript

以下のようなJavascriptファイルを設置します。

webroot/js/ajax-validate.js
(function($){
    $.fn.validate = function(t) {
        var elements = this;
        elements.each(function(n, i) {
            $(this).on('focus', function() {
                var help_target;
                if ($(this).prev().attr("class") == 'input-group-addon') {
                    help_target = $(this).parent();
                } else {
                    help_target = $(this);
                }
                var error_target = $(this).parents(".form-group").get(0);
                $(help_target).nextAll('p.help-block').remove();
                $(error_target).removeClass('has-error');
            });
            $(this).on('blur', function() {
                var help_target;
                if ($(this).prev().attr("class") == 'input-group-addon') {
                    help_target = $(this).parent();
                } else {
                    help_target = $(this);
                }
                var error_target = $(this).parents(".form-group").get(0);
                var key = $(this).attr('name');
                var check_data = {'key': key, 'value': $(this).val()};
                $.ajax({
                    type: 'POST',
                    url: t.url,
                    data: check_data
                }).done(function(data) {
                    if (data) {
                        data = JSON.parse(data);
                        for (key in data) {
                            error_message = data[key];
                            break;
                        }
                        $(help_target).after('<p class="help-block">' + error_message + '</p>');
                        $(error_target).addClass("has-error");
                    }
                });
            });
        });
        return this;
    }
})(jQuery);
if ($(this).prev().attr("class") == 'input-group-addon') {
    help_target = $(this).parent();
} else {
    help_target = $(this);
}

の部分は、viewファイル内で、prependを指定した場合と指定しない場合で、DOM構造が変わるためこのような変な記述になっています。
prepend使わないのであれば、 help_target = $(this) だけで良いはずです。

Viewファイル

src/Template/Users/add.ctp
echo $this->Form->input('username', [
    'prepend' => '<i class="fa fa-font fa-fw"></i>',
    'class' => 'ajax-validate',
]);
echo $this->Form->input('password', [
    'prepend' => '<i class="fa fa-key fa-fw"></i>',
    'class' => 'ajax-validate',
]);

ajax-validateというクラスをつけておきます

src/Template/Users/add.ctp
echo $this->Html->script('/js/ajax-validate');
<script type="text/javascript">
$('.ajax-validate').validate({url: "/users/ajax_validate"});
</script>

ajax-validateクラスに設置したJavascriptファイルのメソッドをアサインします。

Controllerファイル

src/Controller/UsersController.php
public function ajax_validate()
{
    if ($this->request->is('ajax')) {
        $this->autoRender = false;
        $key = $this->request->data['key'];
        $data = [
            $key => $this->request->data['value']
        ];
        $user = $this->Users->newEntity($data);
        if ($errors = $user->errors() and array_key_exists($key, $errors)) {
            $this->response->body(json_encode($errors[$key]));
        }
    }
}

JSONを返すので、
$this->autoRender = false;
を指定します。

15
19
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
15
19