I'm working on an auto-updating table of information using AJAX, but I've run into a bump in the road. I'm using PHP to return a JSON object on each request, which contains data in the following format:

({
    "table": {
        "544532": {
            "field1": "data",
            "field2": "data2",
            "field3": "data3",
            .....
        },
        "544525": {
            "field1": "data",
            "field2": "data2",
            "field3": "data3",
            .....
        },
        ......
    }
}); //

I use Prototype.js to get the list of IDs into an array:

var ids = Object.keys(data.table).sort();

However, random rows of the table could be disappear from the list at any time, and new rows could be added to the end at any time. I assume I would store the array of IDs from the previous request and compare those with the new array, but since random rows can disappear, thus shifting the IDs after that one, how do I compare these so that I can only add new rows or remove deleted rows from the page?

share|improve this question

+1 for a fun challenge! – clockworkgeek Jan 12 '11 at 17:44
feedback

3 Answers

up vote 2 down vote accepted

Unfortunately Prototype doesn't include a Set type which would have made things a whole lot simpler. So we'll have to make do with this:

Array.prototype.subtract = function(a){
    return this.reject(this.include.bind(a));
}

The above adds a much needed subtract function. We can use it like this:

added_ids = new_ids.subtract(old_ids);
removed_ids = old_ids.subtract(new_ids);

It's not too slow either since some browsers supports indexOf which Prototype's include checks for and uses.

PS. Array already has an intersect function, if you'd like a complement too here it is...

Array.prototype.complement = function(a){
    return a.reject(this.include.bind(this));
}

Essentially a.subtract(b) is the same as b.complement(a).

share|improve this answer
Thank you! I've been struggling with this all day, and this works flawlessly! – James Simpson Jan 12 '11 at 18:28
Actually the best solution would be for each response to carry a version number, then on the next AJAX you would request the differences from that version. It means the minimum bandwidth is used each time but it also means a whole lot more work on the server side, something you might not be willing to do. I guess that's another topic for another question. – clockworkgeek Jan 12 '11 at 18:36
Yes, I am planning on only sending the updated data, but I wanted to take it one step at a time. – James Simpson Jan 12 '11 at 22:02
feedback

You should update your JSON data structure when the table is updated. That would be that data model for the page. Then you can just call Object.keys(data.table) everytime you need it.

share|improve this answer
feedback

Im sure there are better ways to do this - but you will need to store the rows that are shown in the table somewhere - perhaps an array - then loop the JSON object comparing the rows against the array.

share|improve this answer
What do you loop through though? Do you loop through the new list of rows or the old one? The length of both could be the same, but have different IDs, which would be ideal for this, but what if their length is different? – James Simpson Jan 12 '11 at 18:06
feedback

Your Answer

 
or
required, but never shown
discard

By posting your answer, you agree to the privacy policy and terms of service.

Not the answer you're looking for? Browse other questions tagged or ask your own question.