Friday, February 29, 2008

GroupingCollection to group mails on Date and Subject

Here is a sample I wrote using GC to group mails according to Date and Subject very similar to Outlook. This sample serves to show the complex ways in which GC can be configures and used.

Subject grouping: The sample uses GroupingField.groupingFunction and GroupingField.compareFunction to achive the Subject grouping even when subject line text is prefixed with RE:, FW: etc. Grouping.groupingObjectFunction is used to supply a custom grouping object MailGroup which has a date field getter function to return the maximum date of the child mail items.

Date grouping: Again groupingFunction is used to form diffrent groups of mails based on the date value.

The "show unread mails" option can be used to remove the read mails from the view. This shows filtering applied to the HierarchicalCollectionView which ADG creates internally when a GroupingCollection (or anything which implements IHierarchicalData) is supplied as the dataProvider.

The "highlight unread mails" option uses the ADG.styleFunction property to hightlight the unread mails by making them bold.

The source is available here

Please note I have a tweak in the sample to keep it ever-green, that is the date values of the mail items are generated at runtime than hard coded.

Monday, February 25, 2008

PrintTileList along the lines of PrintDataGrid.

After seeing this query I thought it should be easy to get it to work. So spent 2 hours (that is little more than expected, isn't it!) and here is the result.

The source is here.

Saturday, February 23, 2008

Drag-drop between two containers instead of list based controls in Flex

I keep seeing many questions on forums about drag-drop of images between two containers or between a control and a container. So I thought a sample may help.

The sample shows a side toolbox from which cursors can be dragged and dropped into the canvas on the right hand side. The code is simple so I won't try to explain the steps in detail here.

The source for this sample is here.

The source for dragging and dropping items between a DataGrid and container can be found here.

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.

Changing row background color in AdvancedDataGrid

Changing the row backgroundColor in AdvancedDataGrid to highlight few rows is easy (though not possible out of the box).

I have used a different approach than overriding the drawRowBackground function used for DG. The drawback of this approach is that the selection feedback gets almost hidden by the background coloring. If the intention is to highlight a search or hightlight a particular values this should not be a serious problem.

The default itemRenderer ADGItemRenderer extends from UITextField (for perforamnce reasons) which doesn't have a backgroundColor style. Hence it is not possible to do it out of the box. But TextField (parent of UITextField) has background and backgroundColor properties which can be set to change the backgroundColor of the TextField.

I have created a new custom itemRenderer ADGItemRendererEx which derives from ADGItemRenderer. I have added a "rowColor" style to this and use this style value to set the TextFields background color.

By providing a styleFunction to ADG we get control to return any styles we want to be set on the itemRenderer. Any logic to determine a particular rows color can go into this function. The return value is a object with style names as properties and style values as proprety-values. For ex:

return { rowColor:0xFF0000, fontWeight:"bold" };

If function logic decides not to change the styles it can return an empty object.

The following sample shows the result. By typing any string in the text box the particular row containing the searched string is highlighted. User can choose to search for either company column or product column.

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