Source:
http://techrays.wordpress.com/2007/10/12/filtering-of-hierarchical-data-in-advanceddatagrid/
There is a TextInput control, in which the user can type some string to filter. After the user click a button, the filterFunction will be changed to a new one, which actually does the filter.
<?xml version="1.0" encoding="utf-8"?>
<s:SkinnableContainer xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:components="com.demandtec.common.controls.*"
xmlns:views="com.demandtec.openlink.producthierarchy.views.*"
xmlns:comp="com.demandtec.openlink.producthierarchy.util.*"
width="100%" height="100%"
creationComplete="init()">
<fx:Script><![CDATA[
import com.demandtec.openlink.common.IconConsts;
import com.demandtec.openlink.producthierarchy.model.ProductHierarchyTree;
import com.demandtec.openlink.producthierarchy.model.presentation.ProductHierarchyPresenta
tionModel;
import com.demandtec.openlink.producthierarchy.util.CategoryNameErrorRendere
r;
import com.demandtec.openlink.producthierarchy.util.ImageStatusRenderer;
import mx.collections.ArrayCollection;
import mx.collections.IHierarchicalCollectionV
iew;
import mx.managers.PopUpManager;
[Bindable]
private var itemRendererFactory:ClassFactory= null;
[Bindable]
private var imageItemRendererFactory
:ClassFactory= null;
[Autowire]
[Bindable]
public var model:ProductHierarchyPresenta
tionModel;
private function init():void {
itemRendererFactory = new ClassFactory(CategoryNameErrorRendere
r);
imageItemRendererFactory
= new ClassFactory(ImageStatusRenderer);
model.init(this);
}
protected function showDialog():void
{
var myPop:AddCategoryPopupDialog=AddCategoryPopupDialog(PopUpManager.createPopUp(this, AddCategoryPopupDialog, true));
PopUpManager.centerPopUp(myPop);
}
private function filter():void
{
// assign filter function to the AdvancedDataGrid's dataProvider
IHierarchicalCollectionV
iew(dataGrid.dataProvider).filterFunction = filterFunction;
// refresh the ADG's dataProvider
IHierarchicalCollectionV
iew(dataGrid.dataProvider).refresh();
}
public function filterFunction(node:Object):Boolean
{
var str:String = searchString.text.toLowerCase();
var allowed:Boolean = false;
var treeNode:ProductHierarchyTree = node as ProductHierarchyTree;
var hasValidChildren:Boolean = false;
var children:ArrayCollection = treeNode.children;
for each (var child:ProductHierarchyTree in children){
if(filterFunction(child)){
hasValidChildren = true;
break;
}
}
// begin filtering
if(str=="")
{
allowed = true;
}
else if(treeNode.nodeName.toLowerCase().indexOf(str) != -1)
{
allowed = true;
}
else {
allowed = hasValidChildren;
}
return allowed;
}
]]></fx:Script>
<s:layout>
<s:VerticalLayout gap="0" />
</s:layout>
<mx:HDividedBox width="100%" styleName="toolBar">
<s:SkinnableContainer styleName="toolBarBreadcrumbAreaSki
n" height="30">
<s:Label text= "{OpenlinkI18N.openlink_title_product_hierarchy}" styleName="breadcrumbSelected" />
</s:SkinnableContainer>
<s:SkinnableContainer
styleName="toolBarButtonAreaSkin">
<components:IconButton label="{DTCommonI18n.common_label_save}" id="btnSave"
icon="{IconConsts.saveIcon}" enabled="false" click="model.saveMappingHandler()" />
<components:IconButton label="{OpenlinkI18N.openlink_btn_revert_last_save}" id="btnRevert"
icon="{IconConsts.displayIcon}" enabled="false" click="model.cancelMapping();" />
<mx:Spacer width="10"/>
<components:IconButton label="{OpenlinkI18N.openlink_btn_add_category}" id="btnAddCategory" icon="{IconConsts.toolbarIconNew}" click="showDialog();" />
<s:TextInput id="searchString"/>
<components:IconButton id="searchNode" label="Find" click="filter()"/>
</s:SkinnableContainer>
</mx:HDividedBox>
<s:SkinnableContainer styleName="gridBorderContainer" height="100%" width="100%" >
<mx:AdvancedDataGrid id="dataGrid" width="100%" height="100%" editable="true" folderClosedIcon="{null}" folderOpenIcon="{null}">
<mx:dataProvider>
<mx:HierarchicalData id="hierarchydata" source="{model.PHTree}" childrenField="children"/>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn dataField="nodeName" headerText="{OpenlinkI18N.openlink_headtext_product_hierarchy}" editable="false"/>
<mx:AdvancedDataGridColumn dataField="nodeID" visible="false"/>
<mx:AdvancedDataGridColumn id="edtCol" headerText="{OpenlinkI18N.openlink_label_dt_category}" editable="true" sortable="false" dataField="demandCatName"
itemRenderer="{itemRendererFactory}"
>
<mx:itemEditor>
<fx:Component>
<comp:AutoComplete dataProvider="{outerDocument.model.demandCategories}" labelField="categoryName" prompt="{data.IsInheritedNew?null:data.demandCatName}" />
</fx:Component>
</mx:itemEditor>
</mx:AdvancedDataGridColumn>
<mx:AdvancedDataGridColumn dataField="updateExistingProducts" id="cbUpdate" headerText="{OpenlinkI18N.openlink_headtext_update_existing_products_on_save}" editable="false" >
<mx:itemRenderer>
<fx:Component>
<comp:HidableCheckBox label="" selectedField="updateExistingProducts" change="data.updateExistingProducts = selected"
paddingLeft="10" forceHide="{!data.isDemandCatNameChanged}" enabled="{data.isUpdateCheckBoxEnabled}"
click="ProductHierarchyApp(mx.core.FlexGlobals.topLevelApplication).ProductHierarchyView.model.updateExistingProductsHa
ndler();"/>
</fx:Component>
</mx:itemRenderer>
</mx:AdvancedDataGridColumn>
</mx:columns>
</mx:AdvancedDataGrid>
</s:SkinnableContainer>
</s:SkinnableContainer>
private function filter():void
{
// assign filter function to the AdvancedDataGrid's dataProvider
IHierarchicalCollectionV
iew(dataGrid.dataProvider).filterFunction = filterFunction;
// refresh the ADG's dataProvider
IHierarchicalCollectionV
iew(dataGrid.dataProvider).refresh();
}
public function filterFunction(node:Object):Boolean
{
var str:String = searchString.text.toLowerCase();
var allowed:Boolean = false;
var treeNode:ProductHierarchyTree = node as ProductHierarchyTree;
var hasValidChildren:Boolean = false;
var children:ArrayCollection = treeNode.children;
for each (var child:ProductHierarchyTree in children){
if(filterFunction(child)){
hasValidChildren = true;
break;
}
}
// begin filtering
if(str=="")
{
allowed = true;
}
else if(treeNode.nodeName.toLowerCase().indexOf(str) != -1)
{
allowed = true;
}
else {
allowed = hasValidChildren;
}
return allowed;
}
<?xml version="1.0" encoding="utf-8"?>
<mx:WindowedApplication xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" height="500">
<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;
import mx.collections.HierarchicalData;
import mx.collections.IHierarchicalCollectionV
iew;
// dataProvider for the AdvancedDataGrid
[Bindable]
private var fs2:XML =
<item fileName="1" size="5563" lastModified="October 6, 2006">
<item fileName="2" size="234" lastModified="November 7, 2003">
<item fileName="3" size="2345" lastModified="December 8, 2006"/>
<item fileName="4" size="3256" lastModified="November 9, 2005"/>
</item>
<item fileName="5" size="2345342" lastModified="October 10, 2007">
<item fileName="6" size="523452563" lastModified="November 11, 2006"/>
<item fileName="17" size="124234" lastModified="December 12, 2006"/>
</item>
<item fileName="8" size="23452" lastModified="October 13, 2007">
<item fileName="9" size="12345" lastModified="November 14, 2006"/>
<item fileName="10" size="241" lastModified="December 15, 2004">
<item fileName="11" size="34563" lastModified="November 16, 2005"/>
<item fileName="12" size="3456345" lastModified="October 17, 2006"/>
</item>
</item>
</item>;
private function filterIt():void
{
// assign filter function to the AdvancedDataGrid's dataProvider
IHierarchicalCollectionV
iew(adg.dataProvider).filterFunction = browseFilter;
// refresh the ADG's dataProvider
IHierarchicalCollectionV
iew(adg.dataProvider).refresh();
}
private function browseFilter(item:Object):Boolean {
var xml:XML = XML(item);
if(xml.children().length() > 0){
var hasValidChildren:Boolean = false;
for each(var node:XML in xml.item){
if(browseFilter(node)){
hasValidChildren = true;
break;
}
}
if (String(xml["@fileName"].toString().toLowerCase()).indexOf(txt.text.toLowerCase()) >= 0) {
return true;
}
else {
return hasValidChildren;
}
}
else {
return String(xml["@fileName"].toString().toLowerCase()).indexOf(txt.text.toLowerCase()) >= 0;
}
}
]]>
</mx:Script>
<mx:Label fontSize="16" htmlText="<b> Filtering of Hierarchical Data in AdvancedDataGrid </b>" />
<mx:AdvancedDataGrid id="adg" dataProvider="{new HierarchicalData(fs2)}" displayItemsExpanded="true"
width="400" height="350" >
<mx:columns>
<mx:AdvancedDataGridColumn dataField="@fileName" />
<mx:AdvancedDataGridColumn dataField="@size" />
<mx:AdvancedDataGridColumn dataField="@lastModified" />
</mx:columns>
</mx:AdvancedDataGrid>
<mx:HBox>
<mx:Label text="Enter text:" />
<mx:TextInput id="txt" change="filterIt();" />
</mx:HBox>
</mx:WindowedApplication>