Tuesday, January 22, 2008

Extending DGColumn and ADGColumn to handle nested data fields.

I have seen numerous questions regarding how to specify DataGridColumn.dataField when the data is nested (object or XML). Developers attempt to use "datafield1.datafield2.datafield3" to find out that it doesn't work !

The data might look like this :

<mx:XMLList id="testData" xmlns="">

<root>

<item>

<childItem>

<name>India Flex group</name>

<mail>indiafx@gmail.com</mail>

</childItem>

<location>India</location>

</item>

<item>

<childItem>

<name>Singapore Flex group</name>

<mail>singaporefx@gmail.com</mail>

</childItem>

<location>Singapore</location>

</item>

<item>

<childItem>

<name>Sreenivas</name>

<mail>sreenivas.ramaswamy@gmail.com</mail>

</childItem>

<location>Bangalore</location>

</item>

</root>

</mx:XMLList>

The answer has always (most of the time?) been to use DataGrid.labelFunction. I dislike the solution because it requires the developer to do this again and again for every column and every usage. I find it easier to extend the DataGridColumn and override the itemToLabel function to do the needful.

The usage is simple. The Nested and ordinary columns can be mixed or only nested columns can be used as the logic kicks in only when "." is present in dataField value.

<mx:AdvancedDataGrid dataProvider="{testData.item}">

<mx:columns>

<local:AdvancedDataGridColumnNested dataField="childItem.name" headerText="Name" width="150"/>

<local:AdvancedDataGridColumnNested dataField="childItem.mail" headerText="email" width="100"/>

<mx:AdvancedDataGridColumn dataField="location" headerText="Location" />

</mx:columns>

</mx:AdvancedDataGrid>

<mx:DataGrid dataProvider="{testData.item}">

<mx:columns>

<local:DataGridColumnNested dataField="childItem.name" headerText="Name" width="150"/>

<local:DataGridColumnNested dataField="childItem.mail" headerText="email" width="100"/>

<mx:DataGridColumn dataField="location" headerText="Location" />

</mx:columns>

</mx:DataGrid>

The result looks like this:

The data can be nested to any level not just two. The same logic takes care of everything!

Here are the source files for DataGridColumnNested and ADGColumnNested and test app.

6 comments:

Scott Bailey said...

I was getting errors when data was null. Changed to:
if (data && dataField.indexOf(".") != -1)

The problem is that it does not seem to know how to sort. Presumably because we are only changing the label.

Sreenivas said...

You need to supply a custom sorting function to handle the situation.

Nate said...
This comment has been removed by the author.
Nate said...

I recently extended the DataGrid to allow for nested properties because making a custom sort function and a custom label function can get quite tedious for every DataGrid you use with nested object properties. I allow for a DataGridColumn to use dataField="object1.object2.object3.property" or dataField="object1.objectList1[0].object2.objectList2[5].property" for example. Feel free to check it out on my blog

LuizRolim said...

Hi.

I accomplished the same funcionality but using a totally diferent aproach.

Instead of extending the DGC I created a proxy class that wraps the Object in the grid and executes the method for both getter and setter direction.

I took inspiration from Ruby missing method def, and its implementation in flex.

For more details

here:http://flexonrails.net/?p=95

The code is still a little bit fuzzy , but i can send how i implemented it as soon as i get it cleaner.

tamyadore said...

thanks for sharing :)
I was going crazy trying to do this.