Certificated Actions - One Click Only

01/14/2009 Updated CanProcessAction - left out where it creates an ID!

Here's something that comes up periodically, "how do you prevent the dreaded double-click?" From something as common as a banking or purchasing transaction getting run twice or more because of overzealous clicking, to batch processing for the night - to pushing items through workflow. How do you prevent it?

A typical strategy is to disable the button in javascript. This works, somewhat, but doesn't prevent someone from hitting refresh once they get to the next page.

My strategy, certificated submits:

  1. A Table (in MySQL here):
     
    CREATE TABLE CLICK_CERTIFICATES (
      certificate_id varchar(40) not null,
      primary key (certificate_id)
    )
    
  2. A way to create a GUID or unqiue id:
     
    function CreateGUID(){
     srand((double)microtime()*1000000);
     $r = rand ;
     $u = uniqid($r);
     $m = md5 ($u);
     return($m);
    }
    
  3. A function that tells us if we can process the action:
      
    function CanProcessAction($certificate_id){
      $certificate_id = addslashes($certificate_id);
    if(trim($certificate_id)!=""){
      $fetch = mysql_query("select count(*) from CLICK_CERTIFICATES where certificate_id='$certificate_id'");
      $row = mysql_fetch_row($fetch);
      $exists =  ($row[0]!=0);
    } else { $exists = false; $certificate_id=CreateGUID();}
      if(!exists){
        mysql_unbuffered_query("insert into CLICK_CERTIFICATES (certificate_id) values ('$certificate_id')");
      }
      return !$exists;
    } 
    
  4. Now, just use a hidden variable on your form that creates the value of the certificate:
     
    <input type="hidden" name="certificate_id" value="<? echo CreateGUID(); ?>">
    
  5. And then just wrap your action on the receiving page like so:
      
    $certificate_id = $_POST["certificate_id"];
    if (CanProcessAction($certificate_id)){
       //do something only this once, even if they clicked twice, or refreshed the page.
    } 
    

You can also put other things in the table to "re-allow" an attempt after a certain amount of time, or log the extra clicks so you can nag your users. By doing the time control, you can prevent users from re-running resource intensive reports for a given interval, and caching the results.




Page :  1