Railsでフォームを作る際、送信ボタンに disable_with オプションを付けることで、二重送信を防ぐことができる。
= f.button '送信する', data: { disable_with: '送信中…' }
しかし、Safariに限って、なぜかボタンの文言が変化しなかった。GitHub上でも、多々報告されている。
disable_with doesn't work with link in Safari #306
解決策
結論から書くと、JSで送信処理をあえて遅らせることで、とりいそぎは回避できた。
Issue内ではバニラJSで書かれた例が出てくるので、jQueryを使っていなけば、そちらを参考にした方が早いかもしれない。
= f.button '送信する', data: { disable_with: '送信中…' }, class: 'disable_with_safari'
$('.disable-with-safari').click(function (event) {
if ($(this).data('disableWith')) {
$(this).prop('disabled', true);
$(this).text($(this).data('disableWith'));
var form = $(this).closest('form');
if (form.length) {
event.preventDefault();
setTimeout(() => form.submit(), 300);
}
}
});
備考
冒頭のIssueでも議論されていたが、Safariの独特な仕様で、一度submitが走った後はDOMの更新が行われなくなるようだ。(あくまでもIssue上でのコメントなので、正確な仕様は一次情報を参照してください)
そのため、disable_withをつけても、ボタンの文言は変わらなかった。
ちなみに、今回の問題について検索すると以下の解決策が出てきていたが、わたしの場合は効果がなかった。
- cursor: pointer; をつける
- 空のclickイベントを設定する
- 空のtouchstartイベントを設定する
- バインドを$(document)に変更する