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.