Wednesday, February 20, 2008

Auto generating DataGrid columns for XML data

When we have dynamic XML data as follows

<employees>

<employee>

<name>Christina Coenraets</name>

<phone>555-219-2270</phone>

<email>ccoenraets@fictitious.com</email>

<active>true</active>

</employee>

<employee>

<name>Louis Freligh</name>

<phone>555-219-2100</phone>

<email>lfreligh@fictitious.com</email>

<active>true</active>

</employee>

</employees>

or in the form of attributes

<employees>

<employee name="Christina Coenraets"

phone="555-219-2270"

email="ccoenraets@fictitious.com"

active="true" />

<employee name="Louis Freligh"

phone="555-219-2100"

email="lfreligh@fictitious.com"

active="true" />

</employees>

and feed into DG or ADG it won't create columns auto-magically as it does for Object data type. This may be because it is difficult to decide whether you want to display the child nodes as columns or attributes of nodes. And may be it was not appropriate to clutter the API with one more flag to do this.

I wrote the following code to get this working.

private function generateCols(input:XMLList, 
 useAttributes:Boolean = false):Array
{
 var e1:XML = input[0];
 var columns:Array = [];
 var children:XMLList ;
 if (useAttributes)
    children = e1.attributes();
 else
    children = e1.children();
 for each(var child:XML in children)
 {
    var col:DataGridColumn = new DataGridColumn();
    col.dataField = useAttributes ? "@" + child.name() : child.name();
    
    var fieldName:String = child.name();
    col.headerText = fieldName.charAt(0).toUpperCase() + fieldName.substr(1);
    columns.push(col);
 }
 return columns;
}

The source is available here

The thread related to this post is here

12 comments:

Justin said...

I'm pretty new to flex. Frankly I just started playing this week. Your post is almost exactly what I was looking for except I'm wondering 2 things:

1. Can this be sourced through HTTPService

2. Can I have this auto rebuild with a different set of columns on the fly if the HTTPService returns different data?

Sreenivas said...

Justin,

1. Yes. It can be sourced from a HTTPService. In the result handler set the DG.dataProvider to the data returned.

2. Yes. In the HTTPService result handler do the following

dg.columns = generateCols(..with the data returned...);

As you learn more you can attempt to modify the generateCols to use a XMLListCollection instead of XMLList which makes it possible to call generateCols() with dg.dataProvider itself :)

-Sreenivas

Madhav said...

Can we retain the order of columns which is used while creating XML result structure and display the columns in DataGrid element in the same order?

DataGrid is taking alphabetical order and I am not able to find any property to alter this.

Sreenivas said...

There is no order defined to read a XML document. Hence column order cannot be expected to be maintained.

If you want this feature then you have to traverse the XML "node by node" and build the column hierarchy.

Or you can send the order of columns by some other means.

Madhav said...

>>If you want this feature then you have to traverse the XML "node by node" and build the column hierarchy.

Then, is there a way to populate DataGrid in a loop/iteration while I'm iterating over the returned XML resultset?

HyderAlamgir said...

Dude, I needed this so bad!

You are A W E S O M E !!!

theway200 said...

Thank you much, helped me out.
austin

Gerardo said...

Thank for your solution. It works great. :)

Rinkesh said...

I would like to thank you for the efforts you have made in writing this article. I am hoping the same best work from you in the future as well.
We buy Any Car

anon said...

This really helped me too, my data grids are looking top notch now.
mike @ sell my car

The Motoring said...

My search was ending here. Thanks to Author.
usedcarsforsale

Stiv said...

I really like this information, the video is wonderful,I would like to download the information, thanks for sharing.
lesbian bondage videos