:disable_withで処理中を明確にして二重送信を防止

フォームに入力した内容をサーバー送信する時、送信ボタンを押してから処理に時間がかかると不安になる。(特にファイルをアップロードする時など。)ユーザーによっては、2回、3回と送信ボタンを押しまくるかもしれない...。不要な操作は、サーバーにも負荷がかかるし、きっとユーザーもイライラしているはず。そんな時は、submit_tagの:disable_withオプションで手軽に解決できた!

  • 以下のように:disable_with=>'アップロード処理中...'と設定しておけば...
    • ボタンを押すと、操作できない状態に変化して、二重送信が防止できる。
    • 同時にボタンの表示が[アップロード処理中...]に変更され、ユーザーにフィードバックできる。
<%= start_form_tag({:action => 'create'}, :multipart => true) %>
  <%= render :partial => 'form' %>
  <%= submit_tag "アップロード", :disable_with=>'アップロード処理中...' %>
<%= end_form_tag %>


ボタンを押すと...

単純だけど、効果が大きい。これから多用しそう。

ajax更新の場合

  • 調子に乗って、CSVサーバーの多くの送信ボタンに:disable_withオプションを設定してみたら...
    • form_remote_tagブロックの中で:disable_withオプションを使うと、ajax更新でなく、ページ遷移の更新になってしまった。
<%= form_remote_tag :update => 'list_update', 
                    :submit => 'list_params', 
                    :url => {:action => 'list_update'} %>
  <%= render :partial => 'filter_form' %>
  <%= submit_tag "フィルターを実行", :disable_with=>'フィルターを実行中...' %>
<%= end_form_tag %>
  • そうなのです。ajax更新なんだから、:loadingと:completeオプションを使えば良いのだ!
<%= form_remote_tag :update => 'list_update', 
                    :submit => 'list_params', 
                    :url => {:action => 'list_update'}, 
                    :loading => "$(filter_submit).disabled=true; $(filter_submit).value='フィルターを実行中...'", 
                    :complete => "$(filter_submit).disabled=false; $(filter_submit).value='フィルターを実行'" %>
  <%= render :partial => 'filter_form' %>
  <%= submit_tag "フィルターを実行", :id => 'filter_submit' %>
<%= end_form_tag %>

:disable_withの中身

  • ちなみに、disable_withオプションを設定すると、以下のように展開される。
  • onclick="this.disabled=true;this.value='アップロード処理中...';this.form.submit();"が付加されている。
<%= submit_tag "アップロード", :disable_with=>'アップロード処理中...' %>

展開後は...
<input name="commit" onclick="this.disabled=true;this.value='アップロード処理中...';this.form.submit();" type="submit" value="アップロード" />


なるほど。そのうち、自分流にヘルパメソッドに定義して、拡張しても良いかもしれない。例えば、イージケータがクルクル回るとかね。