« Input should be validated by your application, not by your users! | Main | UI technique: changing submit button appearance via background images »

Preventing multiple page requests after double-clicks

A friend asked me for advice today on a problem he had been experiencing with his ColdFusion application. On around one out of every 500 requests, there would be an error saying that a certain session variable was undefined. He wondered if the problem was that he was deleting the session variable at the bottom of the page, but I assured him that it couldn't be the source of the error earlier in the page. But the answer I suggested was... double-clicks.

I think that double-clicks on a link or submit button could cause the same page to be requested and run twice at almost exactly the same time. The first request would run but never reach the browser; the second would run and then be sent back to the browser. If the timing was right, the first request would destroy the session variables right in the middle of the page processing of the second, throwing an error in the process. So what can be done about it?

To prevent multiple clicks from sending more than one request, you can use a JavaScript that does up to two things: first, you can use the "return false;" function of a hyperlink or submit button to prevent any click after the first from sending a request, and second, you can change the link or button to a disabled state so that the browser won't accept clicks and the user can see that a request has already been sent. I think a combination of both is the most effective.

For submit buttons, there's a pretty easy solution: just add an onclick attribute that disables the button:


<input type="submit" name="save" value="Save" onclick="this.form.submit(); this.disabled = 1;" />

For hyperlinks, this is a little bit harder since you can't disable them like you can with submit buttons. So we have to write an script which tracks whether the link already has an active click:


<script language="JavaScript">
window.latestClick = '';

function isNotDblClick(objectID) {
	if(window.latestClick != objectID) {
		window.latestClick = objectID;
		return true;
	} else {
		return false;
	}
}
</script>

And you'd call it from the link like so:


<a href="#" id="saveLink" onclick="if(isNotDblClick(this.id)) {document.theForm.submit(); return false;} else return false;">Save</a>

Does anyone else have any good techniques for preventing double-submissions? If so, let me know-- I'd enjoy hearing about other ways of achieving this.

Comments (12)

For the first method, I think if you have any code that actually checks for the existence of the submit button in the form scope, it will no longer work.

e.g.

will now be broken, because disabling the submit button prevents it being, er, submitted.

Nice solutions, I use two methods:

1. Put the submit button in a span or div and after submission change the span or div contents to say "Processing" or something like that.

2. Use cfform:

cfform method="post"...
.
.
.
cfinput type="submit" name="subBut" id="subBut" validate="SubmitOnce" value="Process"
/cfform

In this case the validate="submitOnce" will allow the button to be clicked only once.

@duncan,

True, it would be an inconvenience if this prevented the submit button from being passed to the server, but in my testing I haven't found that to be the case. Because the submit button is disabled after the submit() function is called, I believe it's passed correctly.

@Sam,

I really like your first technique of changing the value of the button so that the user knows some processing is occurring. I've got one technique that I plan to blog on in the near future. Also, I didn't know that cfform validation offers double-click prevention, that's cool.

Hello,
Thanks for the nice information , I love it! Keep Posting...

Hello,
Thanks for the great post , I like it! Keep Posting...

Hello,
Thanks for the nice information , I appreciate it! Keep Posting...

Hello,
Thanks for the great information , I appreciate it! Keep Posting...

Hello,
Thanks for the important post , I appreciate it! Keep Posting...

Hello,
Thanks for the amazing post , I love it! Keep Posting...

Hello,
Thanks for the great post , I love it! Keep Posting...

Hello,
Thanks for the amazing post , I appreciate it! Keep Posting...

Hello,
Thanks for the kind information , I appreciate it! Keep Posting...

Post a comment


Type the characters you see in the picture above.