CakePHPのpostlinkで生成した削除リンクをクリックしても処理が実行されない対処法
postlinkで生成した削除リンクをクリックしても処理が実行されないときの対処法
削除をクリックしても処理されないという発生した事象
CakePHP4、CakePHP5環境で、一覧表にある「postlink()」から生成された「削除」のリンクをクリックしても処理が実行されないという不具合が発生しました。
そして「OK」をクリックしても削除処理は実行されない、という不具合です。
削除をクリックしても処理されない原因
今回の原因は、上記の画像にもありますが、「詳細」「変更」「削除」の処理を一覧表の右と左の両方に表示していることでした。
上記の画像は一覧表の項目が少ないため、表の左右に付ける必要性を感じませんが、実際の表は項目が多くスクロールさせる必要がありました。
そのため、右端までスクロールさせなくてもいいよう、左右にリンクを設置することにしました。
その際のコードが下記になります。
不具合が発生したソースコード
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
<?php $actionLink = $this->Html->link("詳細", ['action'=>'view', $user->id]) . " "; $actionLink .= $this->Html->link("変更", ['action'=>'edit', $user->id]) . " "; $actionLink .= $this->Form->postLink("削除", ['action'=>'delete',$user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]); ?> <?php /* 左側の操作の列 */ ?> <td class="actions"><?= $actionLink ?></td> : 中略 : <?php /* 右側の操作の列 */ ?> <td class="actions"><?= $actionLink ?></td> |
上記のソースコードで不具合が発生する原因
このような記述をすると、「$this->Form->postLink()」で生成される formタグの name(「<form name=”post_691428....”」の部分)が同じものが 2つ生成されるのです。
「name」の IDが同一なものが複数あるため、いざ処理を実行しようとすると、ブラウザはどちらの formタグの処理を実行すればいいのかが分からないため、処理の継続ができなくなる、という不具合でした。
(不具合が発生するのは「$this->Form->postLink()」だけで、「詳細」「変更」のリンクはただのリンクなので、いくつ複製しても全く問題ありません。)
不具合を解決するソースコード
解決策としては、下記のように出力の都度「$this->Form->postLink()」を実行することです。(もう少しスマートな書き方はできますが...)
|
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
<?php $actionLink = $this->Html->link("詳細", ['action'=>'view', $user->id]) . " "; $actionLink .= $this->Html->link("変更", ['action'=>'edit', $user->id]) . " "; $actionLink .= $this->Form->postLink("削除", ['action'=>'delete',$user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]); ?> <?php /* 左側の操作の列 */ ?> <td class="actions"><?= $actionLink ?></td> : 中略 : <?php $actionLink = $this->Html->link("詳細", ['action'=>'view', $user->id]) . " "; $actionLink .= $this->Html->link("変更", ['action'=>'edit', $user->id]) . " "; $actionLink .= $this->Form->postLink("削除", ['action'=>'delete',$user->id], ['confirm' => __('Are you sure you want to delete # {0}?', $user->id)]); ?> <?php /* 右側の操作の列 */ ?> <td class="actions"><?= $actionLink ?></td> |
リンクをクリックしても動作しなかった時の詳細な状況
今回発生した事象について、どのような状況が発生していたか、改めて説明します。
(似たような症状が発生した方が確認するための情報として書いておきます。)
リンクをクリックしても PHPのエラーログは出力されない
まず、PHPのエラーログは出力されません。
「$this->Form->postLink()」で生成される処理は、JavaScriptを利用して、POSTする処理となっています。
そのため、JavaScript側の不具合か、PHP側の不具合か、を見極めるために、PHP側の関数にログを出力する処理を追加しました。
しかし、ログは出力されなかったため、PHP側ではなく、その処理に到達するまでに不具合があることを確認しました。
ChromeのDevToolsのコンソールにエラー出力
そのため、今度は Chromeの DevToolsを起動し、実行すると、下記のエラーが発生していることを確認しました。
|
1 2 3 |
VM597 users:1 Uncaught TypeError: document.post_9999999999.submit is not a function at HTMLAnchorElement.onclick (VM597 users:1:82) onclick @ VM597 users:1 |
|
1 |
if (confirm(this.dataset.confirmMessage)) { document.post_9999999999.submit(); } event.returnValue = false; return false; |
上記のエラーはざっくりとは下記の内容です。
『JavaScriptが「document.post_9999999999」という名前の HTMLフォーム要素を見つけ、その.submit()メソッドを呼び出そうとしました。
しかし、JavaScriptがこの名前の要素を見つけることはできました。』
そして、エラーの内容を ChatGTPや Google Geminiに聞いても
「CSRFトークンが欠落している(最も可能性が高い)」
「JavaScriptが正しく実装されていない」
と言った返答をするだけで、正しい解決策には至りませんでした。
そして、いろいろ確認していく中で、『「document.post_9999999999」を見つけられない』原因が、「document.post_9999999999」が 2つあるためであることを認識し、問題を解決することができた、ということになります。
「postLink()」で発生した不具合の対処のまとめ
今回の不具合は、「$this->Form->postLink()」で生成される HTMLのソースを変数に入れ、複数個所で echoすることで、同一の IDをもつフォームが生成されることが原因でした。
最近は、不具合が発生しても生成AIが答えてくれるため、このブログに記事を書く必要性を感じなくなりましたので、しばらく記事を書いていませんでした。
ですが、今回の不具合は、おそらく過去に記事として書かれたことがない不具合なのだろうと思いましたので、こうして記事にすることにしました。
CakePHPのデフォルトテンプレートの一覧表は、項目が多いとスクロールが表示される仕様になっています。
そのため、今回の私のように、表の左右に「操作」の列を作りたいと思う方もそれなりにいるのではないか、と思いますが、同じような不具合が発生したときの一助になれば、と思っています。
GoogleAdwords
GoogleAdwords
この記事が参考になったと思いましたらソーシャルメディアで共有していただけると嬉しいです!
関連記事
-
-
CakePHP 2.3 ログイン、操作履歴、アクセスログ出力
CakePHPでログインや操作履歴などのアクセスログ出力処理を作成します。
-
-
CakePHP3のデバッグキット(DebugKit)を強制的に有効、無効に変更する方法
CakePHP3に付属しているデバッグのためのツール、デバッグキットを強制的に有効化、無効化する方法を解説。初期設定では開発環境としてありそうなドメインの場合のみ有効になるように設定されている。
-
-
CakePHP4のFrozenDateで1ヵ月前、先月、今月1日、来月末の日付などを算出する方法
CakePHPには「FrozenDate」の日付を扱う関数が用意されている。これを利用して、1ヶ月後、月末日、月初日、5日後などを指定して日付を取得できる。それを解説。
-
-
CakePHP3のCakeDC/Usersのバリデーションのカスタマイズ方法解説
CakeDC謹製Usersプラグインの紹介。Usersのカスタマイズとして入力項目のバリデーションの変更を、プラグインのファイルは触らずオーバーライドにより実装する方法を解説する。
-
-
getParam('action')で取得するアクション名は別関数に移動しても不変CakePHP4系、5系では「getParam()」で処理中のアクション名を取得できる。そのアクションから別関数を呼び出してた関数でアクション名を調べたが同一の名称だった。
-
-
CakePHP3のユーザ管理・ログイン認証プラグインCakeDC/Usersのインストール解説・3.6以降対応
CakePHP3のユーザ管理プラグイン Usersは、ユーザ登録、メール認証、ログイン認証、ユーザ管理、権限管理、reCAPTCHAなど会員制のサイトを簡単に実現可能。その導入方法、カスタマイズ方法を解説。
-
-
CakePHP3、CakePHP4のdatetime型カラムの日時の扱い。秒まで表示する方法
CakePHP3の日時カラムで秒まで扱う場合はdate()、strtotime()関数ではうまくいかない。CakePHP3であらかじめ用意された「i18nFormat()」を使用する。
-
-
CakePHP4の数値項目は「like %10%」の部分一致検索(find select)はできない
CakePHP4でテーブルの数値項目に対してlike句を使用した部分一致検索を実行するとエラーが発生する。クリエービルダーの不具合だと思われ対処方法が分からない。
-
-
CakePHP3で Ajaxを使う方法の解説。3.6以降対応。Successとthenの両方を解説。
CakePHP3でajaxを利用する処理の実装方法を解説。プルダウンを変更するとデータベースの値を取得し検索結果の内容を変更するというような処理を想定。CakePHP3.6以降の CSRF対策対応済。
-
-
CakePHP3のCakeDC/Usersのログイン後のリダイレクトとユーザ権限管理の設定解説
CakeDC謹製Usersプラグインの紹介。ログイン認証後にリダイレクトする先の設定方法についての解説と実運用するために必要なコツを解説。便利な仕組みも仕様の理解があって初めてうまく使いこなせる。

