Crafting the SAPO Campus platform, a thousand pixels at a time.
Search
Latest posts

High Performance Javascript - dealing with JSON

No Widget is an Island

Designing Email - Part II

Designing Email - Part I

The amazing "widget" object

The Facebook Witch Project

SAPO Campus keynote from OSL Unesco demonstration session

SAPO Campus session at the UNESCO OSL Seminar

SAPO Campus - Eden Seventh Open Classroom Conference

SAPO Campus leaflet for the UA freshmen

Archive

Janeiro 2011

Novembro 2010

Fevereiro 2010

Dezembro 2009

Novembro 2009

Outubro 2009

Setembro 2009

Julho 2009

Maio 2009

Abril 2009

Março 2009

Fevereiro 2009

Dezembro 2008

Novembro 2008

Outubro 2008

Setembro 2008

Segunda-feira, 23 de Março de 2009
Presenting the 'Awesome Undo Event Queue'
I suppose at some point of their lives, everyone wished they could just CTRL-Z (note: when I say everyone, I really mean geek people). The ability to undo one's actions is a basic principle of HCI, as it gives the user freedom to explore the application and make mistakes. Surprisingly, however, is the number of Web Applications which actually implement an undo feature in their user interface. Rather than the possibility of undoing actions, users are usually presented with the dreaded confirm box:



This kind of behaviour only serves to interrupt the user's workflow, and actually adds little value: most people would just click OK without reading the confirmation text. When developing an application, it's normal to fantasize about users paying attention to your instructions, but you know what? They don't. Also, the confirm box is an omen of something even more terrible: It shouts out to the user: "Be careful, once you click OK there is absolutely NO GOING BACK!".

So how do we solve this mess? How do we provide our users with a safety net that does not interrupt their workflow and also allows them to recover from mistakes? We turn to Javascript, and the 'Awesome Undo Event Queue' (yes, I came up with the name myself, thank you very much).

The implementation I'm proposing is so easy to write and adapt that I'm baffled more Web Applications aren't doing this right now. The code base is taken from this very good post which speaks volumes about this very issue, but I've adapted it in order to provide more flexibility. Everyone should be able to implement this code throughout the SAPO Campus tailoring it to their specific undoing needs. Let's get cracking:

Assume you wanted to add undo support for the deletion of elements. Firstly, include the undo.js file in your page(s). To actually start using the Undo Queue, you need to declare a new UndoQueue object, like this:
var undoDeleteQueue = new UndoQueue();

After this, it's time to start defining your custom functions. Currently, there are two mandatory functions which must be implemented: doInit() and commitToServer().
undoDeleteQueue.doInit = function () {
      // Handler for the delete link.
      $(".widget .closeButton").click( function(event){
           var widget = $(this).parent().parent().parent().parent();
           // Hide the newly deleted widget.
           widget.slideUp();

           // Get the ID of the to-do item. If it doesn't have one, throw
           // an error.
           theId = widget.attr("id");
           if(theId == null ){
               alert( "Error: Widget needs an id." );
           }

           // Add the to-do item to the event queue.
           undoDeleteQueue.EVENT_QUEUE.push(widget.attr("id"));
           undoDeleteQueue.updateUndoLink(undoDeleteQueue.message);
       });

        // Handler for clicking on the Undo link
       undoDeleteQueue.undoLink.click( function(){
            // Get the last to-do item added to the event queue and un-hide it.
           $( "#" + undoDeleteQueue.EVENT_QUEUE.pop() ).slideDown();
           undoDeleteQueue.updateUndoLink();
           return false;
        })

        undoDeleteQueue.syncEventQueueWithCookie();
   }

The doInit() function handles the initial binding of events to elements of your choice. In this example, we're adding an event to a link on the widget chrome that hides the widget and, most importantly, we add the widget ID attribute to the EVENT_QUEUE property of our undoDeleteQueue object. This property is simply an array that holds all the IDs of widgets the user deletes.
Next up we're defining what happens when the user clicks the undo link. This one is easy. You simply get the last ID out of the EVENT_QUEUE, select it using jQuery and do whatever you want to make it appear again (in this case, the opposite of slideUp, slideDown).

Worthy of note is the function syncEventQueueWithCookie(). If the user opens the application in different browser windows , the actions he performs on one do not sync with the other. This means that, if she deletes a widget in one window, the deletion won't be undoable in the other. We solve that with a cookie. No need to worry too much about this, just make sure you call the function at the end of your doInit() handler. This functionality requires the jQuery Cookie plugin.

Finally, we implement the commitToServer() handler and initialize our undo queue, like this:
// Implements undoQueue.commitToServer
undoDeleteQueue.commitToServer = function() {
    // your AJAX call to a page executing some server-side magic goes here.
}

// Initializes the object
undoDeleteQueue.init();

Inside the commitToServer() function, you would perform some sort of AJAX call to your server that would actually delete the items. This is called by default when the user leaves the page, but you can call call it manually whenever you wish. Afterwards, just initialize the object and you're good to go!

Here is the list of other properties you can set:

Last, but not least, here is the source file. Have fun!

UPDATE: Support for CTRL-Z (and COMMAND-Z for Mac OS X) is in. Use the property supportsCtrlZ to control the functionality.
tags:

Published by bruno-abrantes às 15:35

5

De adn a 23 de Março de 2009 às 15:40
I like the name! : )
Very cool feature, gratz!


De José Pedro a 23 de Março de 2009 às 16:24
Sexy!


De Rodolfo a 23 de Março de 2009 às 21:50
José Pedro said it all :)


De lab.sapo/ua a 24 de Março de 2009 às 12:06
Great! Extra coffee for Bruno :)


De joe a 30 de Março de 2009 às 16:23
Wow, how handy! :)


Post a comment

About us
Janeiro 2011
Dom
Seg
Ter
Qua
Qui
Sex
Sab

1

2
3
4
5
6
7
8

9
10
11
12
13
14
15

16
17
18
19
20
21
22

23
24
25
26
27
28
29

30
31


tags

todas as tags

subscrever feeds

RSSPosts

RSSComentários

RSSComentários do post