views:

252

answers:

1

i have list of rows that user select and i want to delete them, one by one and show the result in the end.

obviously if i just do simple loop and call each time ajax function, but how can i loop and check which one successed and which one failed and when they are all done?

how would you do it? what is proper way of doing the bulk editing/deleting?

+4  A: 

Each ajax request is going to have overhead associated with it. It would be a bad idea to make a call for each row because it could overload the server with requests and you could DoS yourself if your receive enough traffic. Also, all browsers have a limit on how many HTTP requests can be made at once, so (depending on the browser), the deletions will happen in bursts, not all at once, even if you tell them to execute one after another.

Your best option would be to group the rows to edit/delete into a JSON array and send them to the server in a single request. On the server you can then parse the JSON and delete the items accordingly. Once you're finished, return a JSON array containing your results.

This jQuery pseudo-code code assumes you're either targeting browsers with a native JSON object, or you're using json2.js. Basically, this code just looks for "the hidden ID" field in each row of the table you display to the user and adds it to an array. You can adjust this as you feel it is needed.

var recordsToDelete = [];
$("tr.myRow").each(function() {
    var id = $(this).find("input:hidden").val();
    recordsToDelete.push(id);
});
var json = JSON.stringify(recordsToDelete);

Dealing with results can be harder. You should design your system so that (if successful), every row is deleted. Unless you're dealing with a very complex system, you should never have a situation where some rows pass and some rows fail. If this happens you need to re-consider your system architecture. jQuery has events for success and failure which you can use to deal with the general success or failure of the request, which I recommend you use.

Continuing from the code above, this is one way to deal with deleting records. I use the complete event here for simplicity's sake, but you should use the success and failure events if possible. The complete event always happens, whether a request succeeds or fails.

$.ajax({
    url: "http://stackoverflow.com/questions/1653127",        
    type: "POST", // Always use POST when deleting data
    data: { ids: json },
    complete: function(xhr, status) {
        var response = JSON.parse(xhr.responseXML);
        // Response will be an array of key/value
        // pairs indicating which rows succeeded or failed
        for (var i = 0; i < response.length; i++) {
            var recordID = response[i].recordID;
            var status = response[i].status;
            // Do stuff with the status codes here
        }
    }
});

In Response to Comments:

  • For apps like gmail, the way it works is so massively complicated that saying "I'll do it this way because Google does it this way", isn't a good idea. Not everything that works for Google will work for every company or web site. Companies like Google have problems to deal with that almost no other web site needs to worry about. However to answer your question
    • I just verified this to be sure: GMail uses one AJAX request with an array of IDs. No individual status codes are sent back. It seems like (and I'm speculating here) Gmail returns an "action ID" for the action you just performed, so you can undo that action by clicking an undo link that appears briefly after you delete an email.
    • When working on an app, you generally want to make it reliable enough that operations don't fail. You should be performing rigorous QA to make sure of this. Basically, a delete operation should either pass or fail as a whole. A scenario where this could happen is if the user clicks delete as your server goes down. To the user, the site is still up because you're not reloading the page, but the AJAX request will fail because it has no where to go. You'll want to handle stuff like this.
    • It really depends on the business rules of your app. If your application is being used in a situation where multiple people can change records at the same time (just an example), something that one user tries to delete could have been deleted by someone else just before they click that "delete" button. In most cases, I can't see people caring who deleted the record first since if it's deleted, it's deleted, no matter who really did it. However, a business rule may dictate (as ridiculous as it may be) that you need to report this information to the user. In this case you would have to return the array of statuses for every deletion.
  • For preventing hackers from deleting other people's records, there are a few things to do:
    • Treat your AJAX handlers no differently than the rest of the site. They should get no special privileges. A request to an AJAX handler should get authenticated just as everything else.
    • Use POST requests (as I mention in my example) for destructive operations, or for operations that change data. This will make it harder for hackers to perform Cross-Site Request Forgeries (CSRF). Obviously this is not a foolproof thing to do, but it stops the easy exploits.
    • Obviously, don't assume the user has the right to delete a record just because the user sent the deletion request. Make sure you verify that the user performing the deletion has the right to remove each record. How you do this will depend on your server-side application.
    • Make sure you encode all of your values sent from the client to the server. This will prevent SQL injections.
    • Make sure you're familiar with the OWASP Top Ten list. It covers the most common (but not all) major exploits on web sites and explains how to prevent becoming a victim of them.
Dan Herbert
let me ask you this question. if you were building an application like gmail OR application like flicker and lets say user selected 20 rows and sent for moving/deleting, would you check each selected row if it deleted or not, OR would you just assume that all the rows got deleted by getting success response from the server or getting the error response from the server for knowing that something went wrong?
Basit
and what if hacker try to use hijack method, meaning like getting someone else id and pushing it inside his id, so other person media gets deleted too.. (im assuming you will be saying to check each id and then delete it), but you seem very expert and knowing alot, so i wanted to ask you what you would do.
Basit
You asked some complicated questions in your comments. I've updated my answer to respond to them since 600 characters is not enough space to answer fully.
Dan Herbert
really appreciate all your answers and you been very helpful. thank you again. i think what i will do, is sent all the ids and check if all belong to user himself, then continue with request, regardless if one fails (sence its manage by one user, so that wont need to check each removed id). but if any id is not user, then return array. ok if you think i should not do this, please do let me know, if not, then im just gonna do this. :) btw thank you again.
Basit