views:

308

answers:

1

I'm working with a UI that has a (YUI2) JSON DataSource that's being used to populate a DataTable. What I would like to do is, when a value in the table gets updated, perform a simple animation on the cell whose value changed.

Here are some relevant snippets of code:

var columns = [
    {key: 'foo'},
    {key: 'bar'},
    {key: 'baz'}
];

var dataSource = new YAHOO.util.DataSource('/someUrl');
dataSource.responseType = YAHOO.util.DataSource.TYPE_JSON;
dataSource.connXhrMode = 'queueRequests';
dataSource.responseSchema = {
    resultsList: 'results',
    fields: [
        {key: 'foo'},
        {key: 'bar'},
        {key: 'baz'}
    ]
};

var dataTable = new YAHOO.widget.DataTable('container', columns, dataSource);

var callback = function() {
    success: dataTable.onDataReturnReplaceRows,
    failure: function() {
        // error handling code
    },
    scope: dataTable
};

dataSource.setInterval(1000, null, callback);

And here's what I'd like to do with it:

dataTable.subscribe('cellUpdateEvent', function(record, column, oldData) {
    var td = dataTable.getTdEl({record: record, column: column});
    YAHOO.util.Dom.setStyle(td, 'backgroundColor', '#ffff00');
    var animation = new YAHOO.util.ColorAnim(td, {
        backgroundColor: {
            to: '#ffffff';
        }
    });
    animation.animate();
};

However, it doesn't seem like using cellUpdateEvent works. Does a cell that's updated as a result of the setInterval callback even fire a cellUpdateEvent?

It may be that I don't fully understand what's going on under the hood with DataTable. Perhaps the whole table is being redrawn every time the data is queried, so it doesn't know or care about changes to individual cells?. Is the solution to write my own specific function to replace onDataReturnReplaceRows? Could someone enlighten me on how I might go about accomplishing this?

Edit:

After digging through datatable-debug.js, it looks like onDataReturnReplaceRows won't fire the cellUpdateEvent. It calls reset() on the RecordSet that's backing the DataTable, which deletes all of the rows; it then re-populates the table with fresh data. I tried changing it to use onDataReturnUpdateRows, but that doesn't seem to work either.

Edit2:

To achieve the control that I wanted, I ended up writing my own <ul>-based data list that made a bit more sense for the problem I was trying to solve. Jenny's answer below should help solve this for most others, so I've accepted it as the solution.

+3  A: 

cellUpdateEvent only fires in response to a call to updateCell(). What you want is to subscribe to the cellFormatEvent. There were a couple other issues in your code, so this should work:

dataTable.subscribe('cellFormatEvent', function(o) {
    YAHOO.util.Dom.setStyle(o.el, 'backgroundColor', '#ffff00');
    var animation = new YAHOO.util.ColorAnim(o.el, {
        backgroundColor: {
            to: '#ffffff'
        }
    });
    animation.animate();
});

var callback = {
    success: dataTable.onDataReturnReplaceRows,
    failure: function() {
        // error handling code
    },
    scope: dataTable
};
dataSource.setInterval(1000, null, callback);
Jenny Donnelly
Thanks for registering just to provide this answer :) - I'm closer now with this. However, it seems that the 'cellFormatEvent' is fired at every interval that the DataSource is polled. Is there another event that would only fire when the data in the cell itself changes? Or perhaps I should be using a different callback method than onDataReturnReplaceRows? I have the feeling that what I'm asking is beyond the capability of the default YUI DataTable/DataSource functionality and that I'll have to write my own setInterval success callback, or something along those lines.
Rob Hruska
There is no event that fires when data changes from a previous value, so that is up to you to determine. To set up a more granular update, you may want to define your own callback success handler function that calls updateRow or updateCell for specific pieces of data that have changed, instead of re-rendering all the rows of the table (which is what onDataReturnReplaceRows does).
Jenny Donnelly
What I ended up doing was writing a custom `<ul>`-based data list that fit my needs a little bit better. It allowed me to have finer-grained control over the data being presented, and made a bit more sense semantically (as well as being lighter-weight). However, thanks for your answer; I'll accept it because I believe it will help solve the problem for others looking for similar solutions.
Rob Hruska