Found a typo or error? Suggest an edit! If accepted, your contribution is listed automatically here.

Comments

avatar

30 responses

  1. Avatar for sirrocco
    sirrocco January 1st, 2010

    One small problem, if I start clicking fast on delete/undo it starts creating rows :).
    Probably you should disable the link while the animation is on.
    Otherwise .. nice plugin.

  2. Avatar for Coden4fun
    Coden4fun January 1st, 2010

    Very useful, thank you! I can use this in my MVC CMS I'm writing. You know if you want to get real familiar with GIT Rob Conery has some nice vids on using it at his TekPub site.
    http://tekpub.com/

  3. Avatar for Adam
    Adam January 1st, 2010

    Looks cool but this means you have to wire the insert up as well when they click undo doesn't it?
    And you would have store retrieve all data, even stuff that doesn't get displayed like created_date etc.

  4. Avatar for Adriaan
    Adriaan January 1st, 2010

    Phil what methods would you use to keep the data for the undo action? Do you pull everything down to the client, and if they undo you just re-insert the data. I can think of another way where you just have a IsDeleted column, but then you sit with data that you don't need.

  5. Avatar for Rajesh Batheja
    Rajesh Batheja January 1st, 2010

    Good one Phil! I will very likely use this. I first noticed Gmail doing something similar when delete an email. There's no confirmation but undo delete exists.

  6. Avatar for luis
    luis January 1st, 2010

    Very nice, tkx for sharing...
    I need samples of code to do the opposite, that is to expand the info of a row to provide full details for a given ID ex: expand the full address for a given name....
    tkx again and happy new year

  7. Avatar for Kenny Ma
    Kenny Ma January 1st, 2010

    Great plug-in Phil, thanks.
    For those wondering how to post or wire up the undo action, here's the code:

    $(function() {
    $('a.delete').undoable({
    url: 'http://example.com/delete/',
    undoUrl: 'http://example.com/insert/'
    });
    });

    You can also override how the undo data is generated by overriding the "getUndoPostData" option like this:

    $(function() {
    $('a.delete').undoable({
    url: 'http://example.com/delete/',
    undoUrl: 'http://example.com/insert/',
    getUndoPostData: function(clicksource, target, options) {
    // return your JSON post data here
    }
    });
    });

  8. Avatar for Tomas
    Tomas January 1st, 2010

    Hi Phil!
    This is great, but for it to be really useful, we need the "Death to confirmation dialogs, part II" blog post where you explain how the "undo" button works.
    Keep up the good work!
    // Tomas

  9. Avatar for Dan Dumitru
    Dan Dumitru January 2nd, 2010

    @Adriaan:


    I can think of another way where you just have a IsDeleted column, but then you sit with data that you don't need.


    I think this is the most logical and easy way to do it, with an IsDeleted column.
    And then you can keep a date when it was deleted, and run a clean-up task that permanently deletes items from the database one day after they were deleted by the user, or something like that.

  10. Avatar for Dan Dumitru
    Dan Dumitru January 2nd, 2010

    And btw, Phil, putting your live preview plugin here on this comment writing would be a nice touch :)

  11. Avatar for haacked
    haacked January 2nd, 2010

    I agree with Dan and that's the way I do it. In the case of comments, I have a status column because a comment could be deleted, marked as spam, needing moderation, or approved.
    I then have another interface that allows you to look at deleted comments (kind of like the recycling bin in Windows). You can destroy those items if you really need to free up space.
    For the most part, I don't care so much about data hanging around as disk space is cheap and it doesn't hurt anything. But I do clean it out from time to time. The UI for destroying items doesn't have an UNDO. I figure if you've already moved the item to the trash, it's very unlikely you want to keep it.

  12. Avatar for haacked
    haacked January 2nd, 2010

    @sirrocco thanks for the bug report. I'll fix it.


    UPDATE: I fixed it in the latest checkin.

  13. Avatar for Mike
    Mike January 2nd, 2010

    There is a different approach to plugin modeling with an easier way to customize and reduce file size. A good example here github.com/.../jquery.ui.autocomplete.js .
    It's a snap to change the behavior of the plugin without the developer having to support all the options since it uses jquery's rich event model.
    I have other example of this plugin pattern too if you'd like some.

  14. Avatar for Saif Khan
    Saif Khan January 3rd, 2010

    That's the work of Bill Scott...I think.

  15. Avatar for Andy Edinborough
    Andy Edinborough January 3rd, 2010

    What about making the action delayed? When then user clicks delete, it gives them something like 3 seconds before actually sending the ajax post to delete? That way, if they click 'undo', we didn't have to communicate with the server at all?
    I really like this idea, and agree that confirmation dialogs are evil, but I don't like the delete-first-then-re-insert-later-if-it-was-a-mistake model.

  16. Avatar for Bob Armour
    Bob Armour January 3rd, 2010

    Phil,
    While I fully agree with the sentiment of this post, I don't really see how the jquery plugin has anything to do with 'undo' - it just seems like a wrapper around the AJAX calls to the server side actions that actually handle the delete/undo operations. Th implementations of the operations still need to be implemented by the user.
    Or am I missing something?

  17. Avatar for Sean Grimes
    Sean Grimes January 4th, 2010

    @Andy
    The problem with your approach is what happens if the user ends up closing out the browser or browser tab before the event gets a chance to fire. You then have a disconnect between what the user expected to happen when the user clicked the delete button and what the software actually did. I generally consider that kind of situation to be a bug, even if the software is working exactly as intended.

  18. Avatar for Andre Sanches
    Andre Sanches January 4th, 2010

    I'm starting to write some JQuery plugins and found your articles and code very useful. Do you know of any Visual Studio add-ins or whatnots that would enable intellisense and highlight opening->closing parenthesis when writing javascript code? That would be awesome.

  19. Avatar for haacked
    haacked January 4th, 2010

    @Andy I don't think you should delete and re-insert. I think you should do a soft-delete in this case. For example, in Subtext, we have the ability to flag something as spam. The record isn't deleted, it gets moved to a "spam folder". But now, when you flag something as spam, you can easily undo it without having to navigate to the spam folder.
    @Bob the point of my plug-in is to make building the UI around undoable operations much easier. I couldn't find anything existing that provided the same effect. You are right, you still need to implement the underlying server action yourself. That'd be out of scope for a jQuery plugin.

  20. Avatar for Tobin Titus
    Tobin Titus January 4th, 2010

    Remember the milk does somethign similar too. I've always loved this convention over the others.

  21. Avatar for Glen
    Glen January 6th, 2010

    It would be nice if it didn't cause the headers/cells to shift around. If you look at your sample, and click the first item to delete, stuff moves to the right. Not much movement on the third item. Not sure if you have any cotrol over that, but the shifting is noticeable(in IE 7 anyways).
    Good job otherwise, I also like not having a confirmation dialog.

  22. Avatar for haacked
    haacked January 6th, 2010

    @Glen Yeah. What I probably need to do is get the size of the target and explicitly set the width and height of the new row to be that of the original. I'm not sure how to do this yet as I didn't have time to look into it.

  23. Avatar for Visual C# Kicks
    Visual C# Kicks January 7th, 2010

    This is very cool, never thought about it. Question though, what would be better approach: delete an entry, and if the user hits undo the data is reinserted OR delete simply sets the task to delete within a certain amount of time or something and undo cancels the task. I'm just curious

  24. Avatar for Andrei Ignat
    Andrei Ignat January 7th, 2010

    I tend to agree with IsDeleted column. However, for more advanced scenarios, the CSLA framework from Lhotka is a must have

  25. Avatar for Brian
    Brian January 12th, 2010

    A similar point to the one I made about your hide/show div script. If you don't intend to support the delete functionality with script off it should be written to add the delete links dynamically. i.e. the plugin could inject delete links into td elements with a class of options or something like that.

  26. Avatar for Christian Toivola
    Christian Toivola January 13th, 2010

    What a great UX pattern - much more intuitive than the alternative.

  27. Avatar for sadomovalex
    sadomovalex May 19th, 2010

    Phil, thank you for your plugin
    but I've found that localization of "undo" link text is not very convenient. Without modification of plugin's code I was needed to copy-past whole showUndo function and replace hardcoded "undo" literal by value from resource file: http://tinyurl.com/36a4kch. Think that it can be improved in future versions. Nevertheless current flexibility allowed me to find workaround for this. So thank you very much again

  28. Avatar for Erich
    Erich October 13th, 2011

    Nice job!
    Suggestion: instead of having the a tags as :
    delete
    I would like to see something like:
    delete
    This way we don't have to specify the url option and the links will still work if javascript is disabled/unsupported/etc. (not that we should have Delete actions happening from a GET request...but that's a different topic) :)

  29. Avatar for Erich
    Erich October 13th, 2011

    Sorry, I didn't realize that a tag is also allowed, re-posting:
    Nice job!
    Suggestion: instead of having the a tags as :
    a href="#1" class="delete"
    I would like to see something like:
    a href="Controller/Action/1" class="delete"
    This way we don't have to specify the url option and the links will still work if javascript is disabled/unsupported/etc. (not that we should have Delete actions happening from a GET request...but that's a different topic) :)

  30. Avatar for jhod
    jhod December 18th, 2011

    Its great. Is possible too open a dialog to process it.
    There is a example here : stackoverflow.com/...