Here’s an easy way to have all your SimpleForm submit buttons default to setting
data-disable-with so that you don’t get errors when users double click on
submit buttons. If you’ve gotten a few
that were hard to reproduce, then here’s your solution, with our without
SimpleForm. Additionally, using
data-disable-with provides the user with nice
feedback once a button is clicked.
If you’re using Devise, and you get a
ActiveRecord::RecordNotUnique error when
a new user is signing up, where do you look?
An ActiveRecord::RecordNotUnique occurred in registrations#create: PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "index_users_on_email" DETAIL: Key (email)=(firstname.lastname@example.org) already exists. : INSERT INTO "users" ("address", "city", "confirmation_sent_at", "confirmation_token", "created_at", "default_location_id", "email", "encrypted_password", "first_name", "last_name", "mobile", "role", "state", "updated_at", "zip_code") VALUES ($1, $2, $3, $4, $5, $6, $7, $8, $9, $10, $11, $12, $13, $14, $15) RETURNING "id"
At first, I was concerned that my unique index on my users table is not case insensitive. I started going down the road of converting my normal unique index on users.email to this index:
However, I soon figured out that Devise was already always saving email in the
database in lower case via a
So then I tried to double click the
SAVE button, and, BOOM, I got the same error.
A little bit of googling quickly revealed some handy rails techniques disabling
a submit button after being clicked, namely the setting of attribute
data-disable-with: “Some Message…” on both links and buttons. This works
nicely to fix the double submit RecordNotUnique error, and it provides some
sweet user feedback upon clicking a button. Here’s an example of a
Immediately after clicking the
SAVE button, the button disables and the text changes.
Example and API: button_tag
Example and API: link_to
SimpleForm Submit Buttons
Even better, this can be done in one place for all SimpleForm submit buttons!
In a file like
config/simple_form.rb, place this initialization code:
1 2 3 4 5 6 7 8
What the bit of code above does is that it:
- Opens up the FormBuilder class to add a method
- Modifies options hash’s :data element, setting a default value for key
disable_withthat will not apply if there’s already a value there, thus allowing the default to be overridden by any individual button.
- Calls alias_method_chain which makes is so that a call to submit actually
submit_with_overrideand that method can call
submit_without_override, which is the original
submitmethod. The pattern of naming the methods
without_overrideis part of the
alias_method_chaincall. Pretty darn cool!
Here’s a sample sign-up form that overrides the default “Processing…” label
SAVE button is clicked.
1 2 3 4 5 6 7
Now go and click on some of your submit buttons, and they will all disable and
display “Processing…”. On a remote form that returned
js.erb, I had to send
back this line to reset the submit button: