2011/06/16

すべての submit に disable_with を

submit ボタンをダブルクリックとかされて、二重登録されてしまうことありますね。
その対策として、クライアント側でお手軽なのが、submit ボタンを押された瞬間に disabled にしてやるというのがあります。
サーバ側でのチェックをするには token を組み込むだのありますが、今回はクライアント側 JavaScript のお話のみということで。

Rails だと非常に簡単にこの機能を提供していて、f.submit :disable_with => '処理中' みたいな感じでできます。
submit_tag でも同様です。(f.submit は submit_tag を呼び出してるし)
ところが、全てのフォームにおいてこれを仕込んでいくのは非常にめんどくさい。
どうせなら一度の設定でアプリケーション全体に適応させましょう。
やってみると意外と簡単で、$RAILS_ROOT/config/initializers の下にこんなコードのファイルを配置するだけ。
module ActionView
  module Helpers
    module FormTagHelper
      alias_method :original_submit_tag, :submit_tag
      def submit_tag(value=nil, options={})
        options[:disable_with] = '処理中...' unless options[:disable_with]
        original_submit_tag(value, options)
      end
    end
  end
end

これで全ての submit は二度押し禁止になりました。
しかし、submit でダウンロードさせた場合、レスポンスがファイルにいってしまうので disabled のまま画面は止まってしまいます。
そんなときは、f.submit :disabl_with => '' のように空文字を渡すだけで大丈夫。

5 件のコメント :

  1. こまったー2011/09/09 11:13:00

    はじめまして
    ダウンロード処理時の対応について、「f.submit :disabl_with => ''」をセットするとのことですが、
    どのタイミングで処理すればよいのでしょうか?

    できれば簡単なソースを公開していただけると有難いです

    返信削除
  2. view に記載する f.submit を f.submit :disable_with => '' にすれば大丈夫です。
    各 view で必要に応じて挙動を上書きするということです。
    ダウンロード処理時にコントローラなどで何かをするのではなく、ダウンロードを実行する submit ボタンを書き換えるのです。

    返信削除
  3. こまったー2011/09/09 12:00:00

    早速の回答ありがとうございます。
    ヘルパー側で、disable_withを設定しているので
    view側では、初期化するよう記述しておけばよい、ということでしょうか?

    返信削除
  4. そういうことです。

    返信削除
  5. こまったー2011/09/09 13:20:00

    なるほどです

    案件の制約上、同様の対応はできないのですが
    これをヒントに対応することにします

    素早いレス、ありがとうございました m(_ _)m

    返信削除