Tuesday, September 7, 2010

DataGrid Reminder: Item Renderers Don't Trigger Events Until They're Visible

Ran into this recently; no code, since that's not really necessary. But this info is pretty valuable imho. I've seen tons of info on the net in all the forums that work around this every which way without every actually stating the precise issue.

Say you've set up the following:

- A datagrid with a dataprovider (say, XML).
- One of the columns in the datagrid has a custom renderer.
- You need to update a model (say, processed XML you will send to a service after the user is done with the grid) with some data that is automatically populated in that renderer's UI field (like a default value).

For instance, say you have this:

<item>
<itemdata>Hello</itemdata>
</item>

You use this as your dataprovider. Your custom renderer has a textfield. You write Hello into the textfield on dataChange. Nice nice so far.

Now, when that textfield changes, you want to update a model of XML, or trigger some other event, whatever. You add the textfields change handler, you see it work, you breakpoint the code that updates the model, and you see the info added. Nice.

Then you say, "let me blow it out to 20 rows". You add them all, you breakpoint the model code, and it works...up to a point. For some reason, 7 or so of the pieces of data you want in the model are there, but then it just stops, as if the data is getting skipped or just not sent.

You fiddle with it...sometimes 7, sometimes, 5, sometimes all 10. WTF is going on?

If you know the answer already, raise your hand...but I bet you don't (I looked and asked around for a week before figuring it out).

Drum roll...

...datagrids only render visible rows. If you had to scroll to see any of your rows, then those renderer's events never fired (like it's textfield change event). Which means that the events never dispatch, so your model, or whatever, never gets the message.

So, if you're counting on events from a renderer events to update a model or trigger some other action when all the data is initially loaded into the datagrid based on a value set in a renderer, don't dispatch the events from the renderers, because if they aren't visible, they'll never send their messages.

Perhaps a datagrid creationPolicy of "all" would be useful under certain circumstances.

As always, thanks for visiting.