Monday, January 28, 2008

Using AdvancedDataGrid as a tree control with sorting

The AdvancedDataGrid control can be configured and used as a simple Tree control with sorting support (which is not available in the Tree control).

The following example shows how.

When hierarchical XML (or Object based) data is fed into a HierachicalData (which implements IHierachicalData) and set as dataProvider to ADG it internally converts it into a HierarchicalCollectionView (implementing IHierarchicalCollectionView). The good news is that HierarchicalCollectionView provides the sort and filtering APIs which can be used to sort and filter the data very similar to flat data.

Click on the "Simple sort" button to see how the data gets sorted recursively. It doesn't do a good job as it mixes up parent and leaf items. If you are one those who expects everything according to the alphabetical order you may like it !

Click on the "Custom sort" button to see how the sorting can be customized to show the parent items at the top and leaf items at the bottom. The custom sort function uses the IHierarchicalData.canHaveChildren API to move the parent items up the ladder.

"Remove sort" does the obvious.

The source and data used for example.

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.

Flex talking to a ActiveX (using ExternalInterface)

I keep seeing/getting request to know how Flex can communicate with a ActiveX control/DLL. So thought will post this sample in which calls were being exchanged between a Flex app and a ActiveX C++ DLL. You can find the source code here.

The sample has two portions a flex app called CalledApp and a C++ DLL called CallingDLL. Load the CalledApp project in FlexBuilder and CallingDLL project is Visual Studio 2003 or later. Build the DLL and the Flex app. Run the Flex app and click on the button. When flex app calls the DLL function the DLL calls back the flex app.

The key is to make the ActiveX DLL scriptable in IE. I went through the trouble long back. The C++ code shows how to traverse the browser DOM to get access to the correct player and how to invoke functions exposed by the SWF.

The Flex app uses ExternalInterface to create a instance of the ActiveX and make calls to it.

However the sample doesn't show passing arrays to the ActiveX which requires conversion of JavaScript Arrays to COM arrays. I am sure smart developers out there can figure out this :).

If you are looking for a sample where in the SWF is loaded in the Flash player ActiveX control embedded in a Desktop application it can be found here.

Sunday, January 20, 2008

Extending DateChooser.selectableRange to accept multiple values/ranges

Recently I came across the following requirement: Enable few disjoint dates in a DateChooser for user selection. The default DateChooser.selectableRange does not allow inserting of list of dates. It takes only a range and disables the rest.

I copied and modified the Flex 2 DateChooser control to achive the new functionlity. The swc is available here http://sreenivas.ramaswamy.googlepages.com/FlexEx2.swc.

I used this file to do the testing. I have done basic testing and it seems to work.

Only few dates in Jan, Feb and March of 2008 are enabled and it restircts the navigation to only those months

Currently I have made changes to only Flex 2 DateChooser. I would be happy to fix any bugs found !

Here are the Flex 3 files: DateChooser and CalenderLayout. The project source to build a Flex3Ex SWC which contains the modified code for DateChooser and CalendarLayout can be found here.