業務で削除前に「本当に削除してよろしいですか?」的な確認ダイアログを作りたくて、 意気揚々とdata-confirmを使ったのは良いものの、まさかのところでハマってしまった記録。
そもそもdata-confirmとは
HTML5から使えるようになったもので、railsではaタグやformタグのsubmitボタンに属性追加することで、確認ダイアログを簡単に表示してくれる。
OKが押されたら処理を続行(リンクを飛ばしたり、submitを実行したり)してくれて、キャンセルされたら処理を中断してくれるので、複雑な条件分岐をJSで書かなくてもビューに一行追加するだけで実現できるのが魅力。
ちなみにdata-confirm自体はjquery_ujsが役目を果たしてくれているので、 application.jsでrequireが必要になります。
//= require jquery_ujs
これ、緑になってるからコメントアウトなのかと思いきや違うんだよね。笑
逆に言うと、この記述をコメントアウトしたい時は「=」を抜いてあげればおけ。
何にハマったのか
簡単に言うと、予期しないところでもdata-confirmが適用されちゃった。
今回、どういうわけか仕様上ちょっと複雑な部分があり、
最初から直接ビューにdata-confirmを記述するのではなく、 JSでイベントが発火したらdata-confirm属性を追加する形を取っていたのだが、
どうも一度ダイアログを出す→キャンセル→全然関係ない隣のボタンを押すと出てきちゃう という状況が発生しました。
$(this).parents('form').attr('data-confirm', '一括削除しますか?');
この下でキャンセルされたらattrが削除されるようにJSできちんと書いていて、 実際属性きちんと消えてくれているのに隣のボタン押すと出てきちゃう、、泣
多分、ボタン自体に属性をつけずその親のformに直接つけちゃってたのがいけなかったんだとは思うのだけど(仕様上ボタンにはどうしてもつけられなかった)なぜいけないのかとか詳しいことはよくわからず。。
ちなみに、公式見るとちゃんと「data-confirmはaタグやボタンにつけるものだからformそのものにつけちゃダメよ」ってちゃんと書いてある。
さすが、公式はやっぱり勉強になります。。
Rails で JavaScript を使用する - Railsガイド
それで、そもそも仕様を大きく変えようかとか色々試行錯誤しましたが、やっぱり諦め。
ふと、data-confirmじゃなくて他の方法で確認ダイアログ実装すれば良いんじゃないの、と思いつき調べてやって見た。
解決:ふつうにjQueryで書く
$(document).on('click', '.hoge-btn', function() { if(!confirm('一括削除しますか?')){ return false; } else { $(this).parents('form').submit() } })
えっ、、そんな簡単なこと?!笑
と思うかもしれないけど、半日これで悩んでいた。笑 なんていう時間の無駄行為。笑
(まあ、このおかげでブログ書けているし、JSについて色々調べまくったから勉強にはなったよ、、泣)
こちらのサイト真似して書いたら普通にできた、、
ダイアログの見た目とかもちょっと変わるのかなって思ったけど、全く変わらず(笑)
最初から色々複雑に考えず、もっと簡単に考えたら良かったです。