Solving the old user-hits-the-submit-button-twice problem is fairly easy using JavaScript and even easier using jQuery. Setting up a sequence like the following is no problem:
- User clicks the submit button
- Button becomes disabled
- The values of the form’s inputs are submitted
My problem is that disabling the submit button causes its value to not submit. Apparently no one else on the planet uses the submit button’s value because none of my Google searches revealed anyone caring about this in the context of using JavaScript to disable the submit button.
No doubt my custom framework could be better designed, but there are a few rare instances when I want to know whether a user submitted a particular form, or even which button in the form they used to fire the submit. If I disable the button, then I don’t get the button’s name/value and thus I lose information about what is happening on the user’s end.
I have two solutions to this problem, the first of which was inspired by Ryan’s comment to my initial draft of this blog entry.
SOLUTION #1: hide the submit button after click
$(document).ready(function() { $("input:submit").click(function (event) { $(event.target).addClass("Hidden"); var form = event.target.parentNode; var msg = document.createElement("i"); msg.innerHTML = "PROCESSING..."; form.insertBefore(msg, event.target.nextSibling); }); $("form").submit(function() { $(":submit:not(.Hidden)", this).attr("disabled", "disabled"); }); });
You will note that I am making use of a CSS class that I’ve called “Hidden”:
.Hidden { display: none; }
Now the sequence of events looks like this:
- User clicks the submit button
- The
click
listener runs a function that hides the submit button and replaces it with some italicized PROCESSING… text - The
submit
listener then disables all other submit buttons - The values of the form’s inputs are submitted, including the newly hidden submit button
SOLUTION #2: copy the name/value to a hidden element
This is my original, hacky solution:
$(document).ready(function() { $("input:submit").click(function (event) { var $submitName = event.target.name; var $submitValue = event.target.value; var $form = event.target.parentNode; $($form).append("<input type=\"hidden\" name=\"" + $submitName + "\" value=\"" + $submitValue + "\">"); }); $("form").submit(function() { $(":submit",this).attr("disabled", "disabled"); }); });
Can you see what horrors I’ve wrought? Now the sequence of events looks like this:
- User clicks the submit button
- The
click
listener runs a function that copies the name/value of the clicked submit button to a hidden input which is appended to the form - The
submit
listener then disables the submit button - The values of the form’s inputs are submitted, including the new hidden input
- To the rest of my code, it appears as if the submit button’s name/value came through with everything else
Now don’t be stingy, man. Pass the data, dude.
another option is to make the button invisible using CSS “display:none;”. In a few projects I’ve used that trick to hide the button, then show “processing…” text in it’s place, with an animated gif if you want to be fancy.
Very good solutiones, both. I’ve been in the same situation using stripes as framework in JEE development.
I have preference for the first one.
Pingback: jQuery.disableDoubleSubmit / ボタンクリックで多重投稿を防ぐ « ゆるぶ
Thanks, this works great!
Sometimes we need the submit button, so this solution is great for those times.
Thank you! This is just what I was looking for!
Solution 1 worked great. You’re correct about searching for a solution on this. I couldn’t find anything else on how to solve getting which button got pressed. – Tom