Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Prevent double submits in a Rails AJAX form

What I have:

I have a form that I submit via AJAX.

<%= form_for([@map, @annotation], :remote => true ) do |f| %>
   ...
   <%= f.submit "Save annotation", :class => "btn btn-primary", :id => "annotation-submit-button" %>
<% end %>

What I want:

I would like to prevent double submits. Since the form only disappears when the request has successfully completed, users can click the submit button as long as the database hasn't finished writing the data. I don't want that, obviously.

What I've tried:

I tried adding this to the submit button itself – but it doesn't work. The button gets disabled, but no data is sent.

:onclick => "this.disabled = true"

I've also tried adding a click handler to the submit button. This has the same effect as before. No data is actually sent to the controller, but the button is disabled.

$("#annotation-submit-button").click(function(event) {
  $(this).attr("disabled", "disabled");
  return false;
});

Also tried the same without returning false. Nothing happens after the button is disabled.

$("#annotation-submit-button").click(function(event) {
  $(this).prop("disabled", "disabled");
});

I begin to think that this is something Rails-specific?

like image 775
slhck Avatar asked Jul 16 '12 13:07

slhck


3 Answers

Try disable_with in the view like this for Rails 3 and above:

<%= f.submit "Save annotation", :data => {:disable_with => "Saving..."}, ... %>

For Rails 2:

<%= f.submit "Save annotation", :disable_with => "Saving...", ... %>
like image 89
abhas Avatar answered Sep 22 '22 23:09

abhas


Disabling the button should work just fine.

Just disable the button in the same function where you execute your ajax-call.

$("#annotation-submit-button").click(function(event) {
  // do ajax call
  $.ajax(...);
  // disable the button
  $(this).prop("disabled", true);
  // prevent the standard action
  return false;
});

However, as of jQuery 1.6 you should use prop() instead of attr().

Edit:

In reply to your comment try omitting the return false; so you don't interrupt the execution of the formsubmit via Rails.

$("#annotation-submit-button").click(function(event) {
  // disable the button
  $(this).prop("disabled", "disabled");
  // do not return false since this stops the event propagation
});
like image 24
Christoph Avatar answered Sep 22 '22 23:09

Christoph


By jQuery: you can do the following to handle the action you want

$.ajax({
  .....,
  beforeSend: function (){ $('#your-button').attr('disabled', 'disabled'); },
  success: function (){ 
    // Here you can enable the button
  }
});

Hope this may help you

like image 22
Alaa Badran Avatar answered Sep 25 '22 23:09

Alaa Badran