Showing posts with label DataGridColumn. Show all posts
Showing posts with label DataGridColumn. Show all posts

Wednesday, February 20, 2008

Alternate row color in DataGrid per DataGridColumn

The idea came from a flexcoders post here. After attempting the previous example of row background colors in ADG I thought it should be easy to achive this which resulted in this post.

I extended the DGColumn and added a "alternatingItemColors" style it so that it would be possible to set it per column.

I extended the DGItemRenderer and used the background and backgroundColor properties to set the items background color. I added logic in a overridden validateNow function to pick up the color from the alternatingItemColors color array.

The drawback of this approach is that the selection feedback gets almost hidden by the background coloring which would not be the case if the drawRowBackground function is overridden.

The result :

The source is available here.

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

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.