Search code examples
ruby-on-railsprototypejshamlrjs

How to disable Rails submit buttons alongside Prototype helpers & RJS?


I'm trying to follow this post How can I unobtrusively disable submit buttons with Javascript and Prototype? but I can't get it to work. The form triggers an RJS function, so I need to keep the helpers' onclick events intact. The RJS returns/reloads the same forms along with two new texts. I'm really confused. Here is my rails code for the forms:

.span-20#comparison
  / new comparison . . .
  / voting forms (also reloaded)
  .span-4.prepend-3.append-6
    - form_remote_tag :action => url_for(:controller => :comparisons), :method => :post do
      = hidden_field_tag :poem1_id, poems[:a].id
      = hidden_field_tag :poem2_id, poems[:b].id
      = hidden_field_tag :response, 1
      = submit_tag "Vote for me", :disabled => false, :disable_with => 'Vote for me', :class => "compare"    

  .span-4.append-3.last
    - form_remote_tag :action => url_for(:controller => :comparisons), :method => :post do
      = hidden_field_tag :poem1_id, poems[:a].id
      = hidden_field_tag :poem2_id, poems[:b].id
      = hidden_field_tag :response, 2
      = submit_tag "Vote for me", :disable_with => 'Vote for me', :class => "compare"

  .span-4.prepend-8.append-8.prepend-top.last
    - form_remote_tag :action => url_for(:controller => :comparisons), :method => :post do
      = hidden_field_tag :poem1_id, poems[:a].id
      = hidden_field_tag :poem2_id, poems[:b].id
      = hidden_field_tag :response, 'draw'
      = submit_tag "Declare Draw", :disable_with => 'Declare Draw', :class => "compare"

RJS

page.replace_html :comparison, :partial => 'poems', :object => @poems
page.insert_html :top, :previous, :partial => 'comparison', :object => @comparison
page << "Effect.ScrollTo($('top'));"

Solution

  • Here's one way you could do it using Prototype:

    <script type="text/javascript">
      document.observe("dom:loaded" function() {
        $$("input .compare").each(function(submit) {
          submit.observe("click", function() {
            submit = true;
          });
        });
      });
    </script>
    

    This adds an onclick event handler to every input element with a compare CSS class (i.e. your submit buttons) when the DOM is loaded. The onclick event handlers disables each button when it's clicked. Note that adding event handlers using Prototype this way does not replace any existing event handlers on the elements.