Thursday, 5 May 2005

Double click hell

Moving people into the "web world" from being used to a fat client can be "interesting". I don't think that paradigm shifts are ever easy. When you're on one side it's hard to see from outside. Most people that I know who use web applications only click links and buttons once. Some fat clients *cough* Notes *cough* require you to double click for just about everything. Trying to get people who are so used to double clicking to just click once can be hard. So hard.

Where this can prove problems if you have something like "delete record 55". If you are using IE for your browser, it can submit that to the server twice and if you don't guard against this your app will blow up, espically when it makes sense to for it to be an error. Stupid IE. Better browsers don't submit to the server until the page has finished reloading.

The hard part about this sort of thing is when you are testing and debugging your app, you might not even consider double clicking on links. I know I didn't. It's just not something that I would do. But it's going to be one of the first things that I try when getting a weird bug report. You can use something like a Synchronizer Token too... if I have any advice for any kind of workflow app, I'd use those everywhere. *sigh* Just venting...

7 comments:

  1. This is one of those situations where XP-style iterative development works well. If you can get the product into the hands of the client early on, you discover practical problems like this early on.
    There are other problems with the XP approach, but this is one advantage of it.

    ReplyDelete
  2. Ah, but it *was* reported early on. The users could never tell us a path that made it reproducible though. :-(
    The reason why it wasn't fixed / addressed for so long so that we never thought that people would be double clicking links.
    I really hate issues that take so long to figure out. I want my app to be going out with as little bugs in it as possible.
    One of the challenges I have at work is that my users are across Canada. None in Ottawa where I work though. I've not actually watched anyone use the application.

    ReplyDelete
  3. Somebody trying to delete a record that doesn't exist should not make it "blow up". I hate that phrase, but i'll save that for another time. Anyway, my team has also experienced this kind of thing. We were thinking about ways to block it. Since either the user double click and doesn't realized it, or the user click again because the app takes more than 5 seconds to respond, and thinks that nothing is happening. Users are very impatient. And they don't realize what a status bar is.
    Anyway, we've thought of ways to prevent this, most of them consist around disabling the button with JavaScript after the first click. This will work if your user has JavaScript enabled. Which they do, because our app is somewhat JavaScript dependant. Anyway, we haven't employed this methodology yet, so I can't comment on the real effectiveness. We haven't had so much of a problem with this kind of error.

    ReplyDelete
  4. I think that it depends on if you consider deleting a record that doesn't exist an exceptional case or not. It's probably not but that's a fine line.
    For non-js ways to prevent form submission take a look at the Synchronizer Token link that I posted. You put a token in the session and the form and only if they match on a submission you perform the action (ignoring all others as duplicates). Of course you reset the token each time.
    I don't know if you are working in .NET or what, so I don't know how easy that would be, but it's really easy in struts (Java).
    Oh, when I mean "blow up" it's displaying an error page with details. It's not just generating a server error. :-P

    ReplyDelete
  5. Another option is to just "silently work" the second time the user presses delete. If the user's objective is to delete the object and it's already deleted, then the objective is still completed the second time they press delete. Just proceed normally.
    This works well for deleting but not so well for adding new things. Two submits would cause two objects to be added -- unless you used something like the tokens you described.

    ReplyDelete
  6. The solution I found for getting around this at work was to have a hidden field on the form that gets modified once a submit action has been started. Then just have every other action check to see if the field has been modified and if it hasn't then proceed with the submit.
    Oh, while we're on the topic of double-posting, if you're building a web app, be prepated to test with NS6 and it's fun behaviour of double-posting any submits when the user clicks the 'Back' button.

    ReplyDelete
  7. Of course handling it on the server side is always better, but that's not always an option. (time, dev constraints etc)

    ReplyDelete