LoginSignup
5
5

More than 3 years have passed since last update.

CakePHP3:postLinkのonclick時に独自の処理を走らせたい場合

Last updated at Posted at 2017-07-15

CakePHPのpostLink、便利ですよね。ボタン1つで画像を削除するような機能を、次のような記述で簡単に実現できます

postLink.php

$this->Form->create($post, ['type' => 'file', 'id' => 'create_post']);

    echo $this->Form->postLink(__('Delete'), [
         'controller' => 'MyImages',
         'action'     => 'delete',
         123
    ], [
         'block'   => true, // フォームの中にpostLinkを入れることはできないのでこの指定をし、後述のfetchをしてform外にpostLinkを設置する
         'class'   => 'delete_button',
         'id'      => 'delete_button_123'

    ]);
    // 2つ目のpostLink
    // 3つ目のpostLink

echo $this->Form->end();

echo $this->fetch('postLink');

postLinkが出力するHTMLは次のようになります:

output.html
<form>
    <a href="#" class="delete_button" id="delete_button_123" onclick="document.post_ランダムなID.submit(); event.returnValue = false; return false;">Delete</a>
</form>

<form name="post_ランダムなID" style="display:none;" method="post" action="/my-images/delete/123">
  <input type="hidden" name="_method" value="POST"/>
  <input type="hidden" name="_csrfToken" autocomplete="off" value="(省略)"/>
  <div style="display:none;">
    <input type="hidden" name="_Token[fields]"   autocomplete="off" value="(省略)"/>
    <input type="hidden" name="_Token[unlocked]" autocomplete="off" value=""/>
    <input type="hidden" name="_Token[debug]"    autocomplete="off" value="(省略)"/>
  </div>
</form>

さて、postLinkはAタグにonclickを自動的に入れてくれるのでクリックするとフォームが投稿されますが、
ajaxを使ってsubmitしたい場合はこのonclickが邪魔になります。

そこで対策としてjQueryを使ってページの読み込み完了と同時にpostLinkが生成するonclickイベントを削ります。
次にaタグに対して独自のイベントハンドラを登録しその中に独自の処理を記述すると、submit前に独自処理を行うことが可能になります:

submit.js
$(document).ready(function() {
    // 全てのリンクから、postLinkが自動生成するonclickを削除する
    $('.delete_button').removeAttr('onclick');

    // 全てのリンクのクリックイベントを拾うハンドラを登録する
    $('.delete_button').click(function(event){
        var selector_id   = event.target.id;
        var res           = selector_id.match(/^delete_button_([0-9]+)$/);
        var my_image_id   = res[1];

        // 投稿する対象のフォームをactionを元に特定する
        var form = $("form[action='/my-images/delete/" + my_image_id + "']");

        // フォームのurlを取得する
        var url  = $(form).attr("action");

        $.ajax({
            type:    'POST',
            cache:   false,
            url:     url,
            data:    $(form).serialize(), // securityコンポーネントを使っているのでフォームの全ての項目をsubmitする
            timeout: 5000,

        }).done(function(data, textStatus, jqXHR) {
            if (data.result == 'OK') {
                alert("画像の削除に成功しました");
            }else{
                alert("画像の削除に失敗しました");
            }
        }).fail(function(jqXHR, textStatus, errorThrown) {
            alert("画像の削除に失敗しました");
        });
        return false;
    });
});

参考URL:https://stackoverflow.com/questions/9750326/intercept-cake2-postlink-form-posts-with-jquery

5
5
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
5
5