Wednesday, October 14, 2009

Double submit issue

I know I know, it had been discussed to death before. There are some solutions but in our application the new problem arised. The main problem are not impatient users cos our forms are secured against double-clicks. The thing is: we're using ExtJS and thus our application awaits for callbacks to display appropiate message to the user. But as some our users use mobile internet the connection faults happen quite often. When callback don't reach the browser, the script displays connection error message.

Ok, so now the user gets an error, clicks "ok" and hits "submit" again to see if he gets an error again. Form gets sent again and we have double record in the database.
To prevent it we have secured the actions by using the session token. So it looks like this:
public function executeForm()
{
  $this->getUser()->setAttribute('formToken',$sometoken);
}

public function executeAjaxAction()
{
  if($this->getUser()->hasAttribute('formToken'))
  {
    //its the first time the user hit submit button
    $this->getUser()->getAttributeHolder()->remove('formToken');

    // here the form is processed, saved to db and the callback is sent
    // depending on the result; if operation failed recreate the token
  }
  else
  {
    // there's no token in the session - the form page wasn't reloaded
    // and double submit occured; we can return success callback here
    // as we are sure that the record was created before
  }
}

As you can see, it's very simple solution. It will work for regular html forms as well, as the "back" button makes the browser use the cache and a new token won't be generated.

The problem is, that sometimes it takes 30 seconds for "connection failure" message to appear. In that time user most likely will hit the F5 button, fill the form again... and add a duplicate record! The token protection won't work because page is refreshed. There's no way we can tell if the submitted form is a duplicate because it has input and text fields which can be filled with different words in the same context. Time blockade is not an option because sometimes users need to add few entries one after another via the same form.

So far we couldn't get around that problem. If you have any ideas, feel free to comment.

No comments:

Post a Comment