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