prevent form double submit

by Laurens Maneschijn

HTML

Attempts at preventing double clicking or double submitting a form by accident.
See HTML and JS for details.

<hr>
<form target="dummy" method="GET" action="/echo/jsonp/">
	<input name="formid" value="0">
	<input type="submit" name="a" value="A" onclick="this.disabled=true; $(this).attr('disabled', true);">
	<input type="submit" name="b" value="B" onclick="this.disabled=true; $(this).attr('disabled', true);">
	on click disable submit button. note that the initial request also isn't sent this way. so not a useful method.
</form>

<hr>
<form target="dummy" method="GET" action="/echo/jsonp/">
	<input name="formid" value="1">
	<input type="submit" name="a" value="A" onclick="setTimeout(function(el){ el.disabled=true; $(el).attr('disabled', true); }, 1, this);">
	<input type="submit" name="b" value="B" onclick="setTimeout(function(el){ el.disabled=true; $(el).attr('disabled', true); }, 1, this);">
	on click disable button with a slight delay using setTimeout(..., 1). this works.
</form>

<hr>
<form target="dummy" method="GET" action="/echo/jsonp/">
	<input name="formid" value="2">
	<input type="submit" name="a" value="A" onclick="this.form.disabled=true; $(this.form).attr('disabled', true);">
	<input type="submit" name="b" value="B" onclick="this.form.disabled=true; $(this.form).attr('disabled', true);">
	on click disable form element. does not work. &lt;form disabled&gt; is not a supported element attribute.
</form>

<hr>
<form target="dummy" method="GET" action="/echo/jsonp/" onsubmit="$(this).find('*').attr('disabled',true);">
	<input name="formid" value="4">
	<input type="submit" name="a" value="A">
	<input type="submit" name="b" value="B">
	on form.submit disable all elements in form. note that this has the side effect that the first request is done, but none of the name="x" value="y" are sent along. so not useful.
</form>

<hr>
<form target="dummy" method="GET" action="/echo/jsonp/" onsubmit="setTimeout(function(form){$(form).find('*').attr('disabled',true);},...

CSS

form.disabled {
	opacity: 0.5;
}
form.disabled * {
	background: #80808080;
}

JavaScript

$(document).ready(function (){

	$('#form6').bind('submit', function(e){
		var form = e.currentTarget;
		// NB:. form.disabled is not an existing property;
		// we just use this to mark it as disabled and look for it here:
		if(form.disabled) {
			e.preventDefault();
			return;
		}
		// Mark form to be disabled for next submit event:
		form.disabled = true;

		// optional: also visually mark form and/or elements in form as being disabled:

//		$(form).addClass('disabled'); // optional: add class so it can be targeted with css.

		setTimeout(function() {
			// Easiest way to make the form look disabled is by disabling all elements in it.
			// Note that this has the side effect that all name="x" value="y" on these elements are NOT send with the form request following on this form.submit event,
			// so work around this by only disabling them after a small (1ms) timeout.
			$(form).find('input, select, button, textarea').attr('disabled', true);
		}, 1);

		// optional: un-disable form and elements after 3 sec:
		setTimeout(function() {
			form.disabled = false;
//			$(form).removeClass('disabled');
			// Note that if any elements were already disabled before disabling them above, they are now also un-disabled. likely not what you want.
			$(form).find('input, select, button, textarea').removeAttr('disabled');
		}, 3000);
	});

});

// attempt to show used url, but... I think jsfiddle is doing magic to prevent any variation on this to work:
/*
setInterval(function(){
var url = $('#iframe').attr('src');
var ts = ''+(new Date()).toISOString();
$('#url').val( ts + ' ' + url );
}, 1000);
*/

/*
// Another attempt at showing the submitted form url and values using MutationObserver
// (including parameter values) but does not show ?a=b etc.
// source: https://stackoverflow.com/questions/2429045/iframe-src-change-event-detection
new MutationObserver(function(mutations) {
  mutations.some(function(mutation) {
    if (mutation.type === 'attributes' && mutation.attributeName...