Coldfusion - How to prevent multiple clicks?

559 views Asked by At

I have a button (anchor tag) that send a confirm message if you press it. The problem is that for example if you press it 5 times very quickly it will send 5 confirm messages, if you press it 2 times it will send 2 messages.

This can occur when the user has low connection speed and while the page is refreshing he presses again the button.

How can I manage this situation? I though of disabling the button but for other reasons this is not possible.

<a class="msg" href="/manage/conversations.cfm?destination=#destination#">
        #ucase(request.l('Send'))#
</a>

Thank you for your time

3

There are 3 answers

2
Dave Ferguson On BEST ANSWER

Ultimately, you need to have code on your server to prevent processing the link multiple times from the same user.

However, to solve the UI issue, have you link call a function instead of the cf file directly.

<a class="msg" href="javascript: processLink(#destination#);">
        #ucase(request.l('Send'))#
</a>

<script>
runCount = 0;

function processLink(destination){
runCount++;

if (runCount == 1){
 window.location.href = "/manage/conversations.cfm?destination=" + destination;
}

}
</script>
1
Dan Bracuk On

The best way is to disable the link once it's selected. If you don't want to do that, an alternative is to structure conversations.cfm like this.

<div id="pageContent">
small amount of text
</div>
<cfflush>
</body>
</html>

<cfsavecontent variable = "actualPageContent">
code
</cfsavecontent>

<cfoutput>
<script>
var #toScript(actualPageContent, "newPageContent")#; 
document.getElementById("pageContent").innerHTML = "newPageContent";
</script>
</cfoutput>
0
M.Scherzer On

As mentioned in the previous answer it's nice to have some client side javascript to stop duplicate submissions from trigger happy users however you should also do this checking server side.

One approach would be to create a hidden formfield with a GUID that coldfusion generates when coldfusion renders your form.

So something like:

<cfset GUID = createUUID()>

<cfoutput>
<form id="frm" action="/target.cfm" method="post">
<input type="hidden" name="guid" value="#GUID#">
<!-- all your formfields go here -->
<input type="submit">
</form>
</cfoutput>

On the server side the target page then checks if it has already previously received the GUID. There are lots of ways to do, here are two of many ways.

a) Use Session Scope.

This is probably the quickest way if you are not running in a clustered environment and just need something quick for a tiny application.

<cfif isDefined("session.MYPAGE_GUID") AND session.MYPAGE_GUID EQ form.guid>
<cfoutput>Duplicate Form Submission</cfoutput>
<cfabort>
<cfelse>
<cfset session.MYPAGE_GUID = form.guid>
<!-- Do Business Logic Here -->
</cfif>

b) Use a Database Table. Create a database table with a column called GUID. Make sure that GUID is the primary key or has a unique constraint.

Before you run your business logic insert the form.GUID into the database table. If you can do the insert process your business logic, if not the database query will throw an error that the record exists. You can then catch this error and take the appropriate action for a duplicate submission.

I prefer the database option as it works across clustered environments and database server are solid protecting against race conditions to ensure that a GUID is only set once.

Please be aware that this is just demonstrating the basic concepts and is not a drop in solution. There is a bit of more work to get these concepts into an e-commerce solution.