Tuesday, September 18th, 2007

Aza Raskin’s Case for Undo

Category: Design, UI

Aza Raskin, whose company created the EnsoQuicksilver-ish” PC launcher and the perpetual scrolling blog, wrote “Never Use a Warning When You Mean Undo” for A List Apart a few months ago, echoing the advice given by his father Jef Raskin in The Human Interface.

I don’t think anyone refutes the wisdom of this suggestion, but many folks responded to Aza’s article with the complaint that the implementation of undo is too hard to be generally feasible. Aza has now come back with his thoughts on a simple client-side implementation of undo for Ajax (part 1).

I admit I personally cut corners all the time in this matter, violating my own beliefs and issuing warnings. :-) Has anyone in the community had experience implementing a robust undo?

Posted by Ben Galbraith at 6:00 am

3.4 rating from 32 votes


Comments feed TrackBack URI

I really don’t like his proposed “event queue” technique, which involves stashing a queue of changes in the browser and only sending them to the server when the onunload event fires (due to the user closing their page). It’s too easy to see data getting lost due to browser crashes, or users getting confused by the inconsistency between their mental model and the actual state of the persistent data on the server.

Comment by Simon Willison — September 18, 2007

Why do it on unload? If you’re gonna do it, do it when the user undos.

Adding undo functionality to your existing JS code is relatively easy. The “difficulty” arises integrating into your app (server comms, UI – where does the history list go? etc) and needs to be thought out from the beginning not as an afterthought.

Comment by Lawrence Carvalho — September 18, 2007

I have to say that the implementation of “undo” in the article leaves a lot to be desired. For those who require this functionality in their own applications, take a look at the command pattern. It is not difficult to code and will give you much more robust results than simple client side event queueing.

Comment by Dav Bacci — September 18, 2007

So you have these items (pictures, messages, files, whatever) and you select some and simply delete them. Instead of a warning you implement some kind of trashcan policy. When deleting you move things to the trashcan. (Or you create a “deletion queue” where things can be undeleted from… which is very similar)

And then… your girlfriend/boyfriend deletes those pictures from that weekend you went to the beach. Yeah, those ones you both said it would be “safer” to delete. But, you know, they’re still there. He/she thought he/she deleted them but actually did not, just moved them to the trash/queue.

On the other hand you accidentally also deleted the one picture you really really liked from that weekend which was “acceptable” and you wanted to keep.

Can the trashcan/queue be emptied automatically? How does the application know one from the other? How can the programmer beforehand decide which policy is applicable? Should we get a “delete” (move to trashcan), a “really delete” and an empty trashcan/queue? Or do we really want a system which let’s us delete and for a period of time undo, and then does the actual deletion on its own when/if it considers appropriate?

Comment by Gonzalo — September 18, 2007

Creating an undo feature isn’t any more difficult on the web than it is on the desktop side of things. The principle is the same. The problem is that an undo is difficult to do, period. The more unique the action, the more difficult an undo. How do you undo an update to a database? You would be forced to keep an undo “history” allowing you to undo a certain amount of actions. You can also try transactions. Either way, this is overhead and is more difficult to implement than a warning/confirm. Not every fancy feature is a necessity. We also have to balance overhead and development time vs actual utility. Also, keep in mind that some applications need an undo more than others.

Comment by Marat Denenberg — September 18, 2007

There is a Command pattern, that can be used to do this, not by stacking a queue to be applied at the end, but by having them provide an undo() method.

From wikipedia:
“If all user actions in a program are implemented as command objects, the program can keep a stack of the most recently executed commands. When the user wants to undo a command, the program simply pops the most recent command object and executes its undo() method.”

If you think that the undo() won’t work with complicated state, look at the memento pattern, which provides the ability to restore an object to its previous state (“undo by rollback”).

Comment by Laurian — September 18, 2007

I think an undo proof-of-concept is easy as the author pointed out. However, a robust solution to make web user experiences as similar as desktop user ones possible is more complex. Besides many issues that were brought up by other readers, there are other issues. For example, if you give them undo, they’re going to ask for redo, because that’s already common in desktop applications. Now forget about desktop, how to differentiate or integrate between browsers back/forward buttons and undo/redo commands? OK, so back to the article, assuming no redo, no back/forward issues, why shouldn’t the “trash can” be implemented on the server? With Ajax or rather XHR, it is almost very easy.

Comment by Kevin Hoang Le — September 18, 2007

As, I pointed out with my example in the comments on the Humanized blog, it’s trivial to just put a deleted bit on items in the database, and then have a script that periodically removes them. Until they’re removed the user can still see them and delete/undelete them. I think the other big problem with the approach shown is that the queue isn’t viewable, so if you deleted three items, and you want the first back, that’s five steps.

Comment by Alexander Botero-Lowry — September 18, 2007

For a robust working undo/redo solution you will need an extensive framework that will monitor actions and ‘knows’ how to undo them. Here’s an example of such an implementation:


Comment by Ruben Daniels — October 2, 2007

I’ve implemented undo in my AJAX application it only took 3 days and it’s done reusably. See a video of it in action here:

Comment by ebdrup — November 9, 2008

Doesn’t work for me, I delete som folders in the first window, click undo and they reappear in the second window not the first, and also an “undefined” appeared as filename.

Comment by ebdrup — November 9, 2008

Leave a comment

You must be logged in to post a comment.