クリックしたボタンによって処理を分ける
formでpostする際において複数のボタンを設置している場合、クリックしたボタンの値を受け取って処理を分岐できる。
例えばメールフォームなどで、確認画面から入力画面に戻るか、送信するかという場合、以下のような処理で実現できる。
<form action="post.php" method="post">
<button type="submit" name="action" value="back">戻る</button>
<button type="submit" name="action" value="send">送信</button>
</form>
$action = (string)filter_input(INPUT_POST, 'action');
if ($action === 'back') {
// 入力画面に戻る処理
// リダイレクトとか
}
// 送信処理
なんてことない、よくある実装だ。
buttonの値が送信されない
上記のようなフォームを実装して、実際に動かしてみたところどちらのボタンをクリックしても、送信処理だけが実行されてていた。$action
のチェックがすり抜けているようだ。
$_POST
をダンプすると、actionの値そのものが送信されていない。
原因
しばらく原因がわからず、さまざまな検証をしたが、JavaScriptでこのようなコードを記述していた。
$(function($) {
$('form').submit(function() {
$('.submit', this).prop('disabled', true);
});
});
disabled…?
このコードを削除すると、buttonタグの値が送信された。
これなに?
いわゆる多重送信を防ぐために、サブミット後にボタンを無効化する処理。
disabledの要素の値が送信されないことは承知だが、submit後に変更してもダメなのか?
と、この記事を書いている途中に以下の記事を見つけた。
Chromeの場合、submitボタン押下時にボタンをdisabledにすると、フォームデータが送信されない。 - Qiita
なるほど…、Chrome特有の問題なのか?
しかし、改善後の内容と現在の記述は(私はjQueryだが)同じものと思われる。
結論(未解決)
記述を変更したが、二重送信防止のためのdisabed処理を実装している場合、Chromeでは値が送信されなかった。
二重送信については、これにおいては直接の問題にはならないので、該当コードを削除して対応した。
解決済み(2022.02.16 追記)
コメントにて@rfr67183様にご提示いただきました。以下に引用させていただきます。
document.querySelector('form').addEventListener('click', e => {
const t = e.target;
if(t.tagName !== 'BUTTON' || t.type !== 'submit') return;
setTimeout(() => t.disabled = true);
});
この内容で、Chromeでもbuttonの値が送信されることを確認しました。