Posted by: Sameer on: October 12, 2007
Filtering of Hierarchical Data in AdvancedDataGrid is quite straight forward.
Assign the filter function to the ADG’s dataProvider and call refresh() -
// assign filter function to
//the AdvancedDataGrid's dataProvider
IHierarchicalCollectionView(
adg.dataProvider).filterFunction =
myFilterFunc;
// refresh the ADG's dataProvider
IHierarchicalCollectionView(
adg.dataProvider).refresh();
Here is a Sample
And the Source
Hello, interesting post but I tried to filter real world data and failed
Is it is easy because there are only “mx” strings in it ?
How do you filter something more complex, for example :
private var fs2:Object =
{fileName:”something”, children: [
{fileName: “more”, children: [
{fileName: “complex”, size:”5563 bytes”, lastModified:”October 6, 2006″}, …
thank you in advance
Sameer, I’m new and I don’t understand your last post. Can you elaborate? Does the children:ICollectionView go in the filterfunction?
Thanks
Looked all over the web for this. Very simple and elegant. Anything similar for the Tree control? Tried iterating filterFunction in a Tree control with limited success. So converted to a single column AdvancedDataGrid and got it all.
Well done.
Sameer, how about if you wanted filter all A, B, A1, A2, B1, and B2 using the same filterfunction?
How do you use custom item renderer with hierarchical data in an AdvancedDataGrid?
I can use custom item renderer with flat data in an AdvancedDataGrid by creating a new class and extending AdvancedDataGridItemRenderer. But when the data is hierarchical it does not work.
Is there some other class I need to extend for hierarchical data?
I just found your post on a 3-state checkbox and figured it out from that code. Thank you!!!
You have to use groupItemRenderer and create a new class and extend AdvancedDataGridGroupItemRenderer.
Awesome!
In your example in the May 9th post:
(Let me take an example. Suppose you have -
A
-A1
-A2
B
-B1
-B2)
You have: var children:ICollection = IHierarchicalCollectionView(
adg.dataProvider).getChildren(node);
How do you specifiy that you want the node B. I need to get the count of children in a specific GroupingCollection in my AdvancedDatGrid and then programmatically open the node if it is 1. Your help is very much appreciated! Please email me. Thank you!
Sameer, can you post an example of filtering all nodes in the hierarchy?
Got tricky when applying a text based filter based on datetime field from SQL Server…
item is returning a value of standard SQL Server datetime format…
the user is filtering on date such as ‘7/1/2008′ as text…
data shows different format and is filtering on that value.. not what is shown…
Sameer, I’m still having issues filtering the advgrid. Can you take a look?
http://s256908546.onlinehome.us/advgrid/index.html
Thanks
I tried filtering against my advanced data grid and it works great with the only difference that when I finish searching the children under my parent item are not expandable.
Any ideas how I can fix that???
Thanks in advance.
Here is my solution simply my children are IP’s so I just looked for all ips and that did the trickery….
private function searchParams(item:Object):Boolean{
var isMatch:Boolean = false;
var regEx:RegExp = /^([1-9][0-9]{0,2})+\.([1-9][0-9]{0,2})+\.([1-9][0-9]{0,2})+\.([1-9][0-9]{0,2})+$/;
if(item.displayValue.toUpperCase().search(txtLookUp.text.toUpperCase()) != -1 || item.displayValue.search(regEx) != -1){
isMatch = true;
}
if(this.reportType == ReportType.ByIP)
{
//DEBUG IP FIELD MAY BE DIFFERENT
if(item.ip.toUpperCase().txtLookUp(txtLookUp.text.toUpperCase()) != -1){
isMatch = true;
}
}
return isMatch;
}
Thanks for the code sample. There’s 1 problem that doesn’t appear in your sample, but does with real world data. That’s when a child node has content that a parent node doesn’t. In that case, if you have a node 2 levels deep that matches, it doesn’t show up because the parent node is hidden. Here’s my solution to that problem:
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.file){
if(browseFilter(node)){
hasValidChildren = true;
break;
}
}
return hasValidChildren;
}
else {
return String(xml.@path).indexOf(view.browseSearch.text) != -1;
}
}
This will do the actual recursion for each node, and hide it if it doesn’t have any matching children.
my datagrid generates a chart.i want to plot another chart based on the child nodes of my datagrid,which should come on clicking a bar.
eg.
chart1:
columnchart dataProvider=”{dg.dataProvider}” itemClick=”DrillDown(event)”
chart2:
columnchart dataProvider=”{AC}”
AC should contain the data of the child nodes of a group(that is represented as a bar in chart1)
hope i stated my problem clearly,please suggest your solution.
Thanks in advance
Hey guys,
I’ver merged Sean’s and Sameer’s code to filter children.
You can get the sample file at this link: http://computerarts.ca/_files/_flex/filtering.zip
When using the Data Management Service with a one-to-many lazy associated data in a HierarchicalData dataProvider, when I apply any filter function other then null, newly opened entities appear twice. This is a serious bug in FDS…
I was trying to use XML as dataprovider for advancedDataGrid. I tried using Steven’s code. It works like a charm, only that, when I do the search, it only searches child nodes. I want something which can search both parent and child nodes. I have tried
if((ObjectUtil.toString(item)).indexOf(searchText.text)!=-1)
nbsp;nbsp;nbsp;return true;
return false;
this shows up parent, but nothing shows up when I try to expand it. Any updates on this is greatly appreciated
Sounds like I’m running into a similar issue that Ram reported on Feb19. The filtering works great for child nodes, but children of matches get filtered out.
Example:
All Cars
Domestic Cars
Lincoln
Navigator
MTX
Foreign Cars
BMW
X5
M3
Mercedes
GL
SL
So, if I filter on “Mercedes” in this sample, I only get
All Cars
Foreign Cars
Mercedes
where I need to display
All Cars
Foreign Cars
Mercedes
GL
SL
Likewise, if I enter “All” I’d like to get the entire tree instead of just
All Cars
It seems that the filterFunction applies to each node individually, making them get filtered out of the tree if they don’t match the search pattern. Any suggestions on how to include all children of matching nodes?
-tri
Reposting the example tree, hopefully preserving indentation an hierarchy this time.
All Cars
Domestic Cars
Lincoln
Navigator
MTX
Foreign Cars
BMW
X5
M3
Mercedes
GL
SL
i was trying to use apply filter to ADG with HierarchicalData provider but when I try to refresh dataprovider an action script error occurs:
Error #1009: Cannot access a property or method of a null object reference.
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.collections::HierarchicalCollectionView/internalRefresh()[C:\Work\flex\dmv_automation\projects\datavisualisation\src\mx\collections\HierarchicalCollectionView.as:700]
at mx.collections::HierarchicalCollectionView/refresh()[C:\Work\flex\dmv_automation\projects\datavisualisation\src\mx\collections\HierarchicalCollectionView.as:681]
at views.questionary::QuestionaryExplorer/filterADGHD()[/usr/local/FilterSample/src/FilterWins/FilterWin1.mxml:438]
at FilterWins::FilterWin1/__searchTextADGHD_change()[/usr/local/FilterSample/src/FilterWins/FilterWin1.mxml:601]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.core::UIComponent/dispatchEvent()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\core\UIComponent.as:9051]
at mx.controls::TextInput/textField_changeHandler()[E:\dev\3.0.x\frameworks\projects\framework\src\mx\controls\TextInput.as:2202]
private function filterADGHD():void{
IHierarchicalCollectionView(adghd.dataProvider).filterFunction = browseFilter;
IHierarchicalCollectionView(adghd.dataProvider).refresh();
}
I forgot to say that function works fine but when it finishes and return control to IHierarchicalCollectionView(adghd.dataProvider).refresh(); is when error is dispatched.
Any ideas?
I have a xml:
var varxml:XML =
;
and then I create a new HierarchicalData object using the previous xml as parameter for constructor:
adgDataProvider = new HierarchicalData(varxml.node);
Then I want to filter by @label when typing in a text input control.
The problem is that when I try
IHierarchicalCollectionView(adghd.dataProvider).refresh();
the action script error occurs.
These are the functions:
private function filterADGHD():void{
// assign filter function to the AdvancedDataGrid’s dataProvider
IHierarchicalCollectionView(adghd.dataProvider).filterFunction = browseFilter;
// refresh the ADG’s dataProvider
IHierarchicalCollectionView(adghd.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.node){
if(browseFilter(node)){
hasValidChildren = true;
break;
}
}
return hasValidChildren;
}
else {
var string:String = xml.@label;
return (string.search(searchTextADGHD.text) >= 0);
}
}
The xml do not apprears on the previous post, here it is again less than and greater than simbols in html code:
<node label=”Questionary Categories” type=”root”>
<node label=”cat1″ type=”category” idQuestionaryCategory=”1″>
<node label=”New Questionary6″ type=”questionary” idQuestionary=”86″/>
<node label=”New Questionary5″ type=”questionary” idQuestionary=”77″/>
<node label=”dfgsdfg” type=”questionary” idQuestionary=”4″/>
<node label=”New Questionary” type=”questionary” idQuestionary=”51″/>
<node label=”quest1″ type=”questionary” idQuestionary=”1″/>
</node>
<node label=”mt0lg4t0HZ” type=”category” idQuestionaryCategory=”13″/>
<node label=”jpPq3cSEjK” type=”category” idQuestionaryCategory=”14″>
<node label=”yUcVD6mJGO” type=”questionary” idQuestionary=”18″/>
<node label=”New Questionary” type=”questionary” idQuestionary=”19″/>
</node>
<node label=”CxR8PFrOr2″ type=”category” idQuestionaryCategory=”15″/>
<node label=”XP3CUuh05R” type=”category” idQuestionaryCategory=”16″>
<node label=”New Questionary” type=”questionary” idQuestionary=”21″/>
<node label=”NvI7nzKguL” type=”questionary” idQuestionary=”20″/>
</node>
</node>
Also, i want to say that when i debug the call to the functions, the line
IHierarchicalCollectionView(adghd.dataProvider).refresh();
is called and enters to browseFilter function, i debug it step by step and it loops over all items but when it finishes and return to IHierarchicalCollectionView(adghd.dataProvider).refresh();
is when error occurs. I hope this description helps to understand what i’m trying to do and when the errors occurs,
Thanks!
My mail is ddominguez@gcpglobal.com
I have tried the example in
23. Steven – February 11, 2009
Hey guys,
I’ver merged Sean’s and Sameer’s code to filter children.
You can get the sample file at this link: http://computerarts.ca/_files/_flex/filtering.zip
and it works fine so i don’t know why my test do not works
i appreciate you send the example, i will try it and i hope it helps me to solve my problem.
How to do dynamic tree inside advanced datagrid.Please send the code
If The Tree is
A
A1
C1
B
B1
C2
I only want to show node starting with C, without parent Node, how can I achive this?
sameer, what is going on with the AdvancedDatagrid in the upcoming Flex 4? is there any new enhancements?
Sameer, is it possible to completely change the source dynamically at run-time?
I have an AdvancedDataGrid bound to a flat XML source.
The contents of myXML changes at run-time.
In the method where the contents of myXML changes, I refresh the GroupingCollection:
gcMyGC.refresh();
Doing this gets me the following error:
TypeError: Error #1009: Cannot access a property or method of a null object reference.
at mx.collections::HierarchicalCollectionView/internalRefresh()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\collections\HierarchicalCollectionView.as:709]
at mx.collections::HierarchicalCollectionView/collectionChangeHandler()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\collections\HierarchicalCollectionView.as:1068]
at flash.events::EventDispatcher/dispatchEventFunction()
at flash.events::EventDispatcher/dispatchEvent()
at mx.collections::GroupingCollection/refresh()[C:\work\flex\dmv_automation\projects\datavisualisation\src\mx\collections\GroupingCollection.as:449]
at…
I forgot to mention that since I’m using a flat data source I’m using a GroupingCollection:
mx:dataProvider
mx:GroupingCollection id=”gcMyGC” source = “{myXML.myElements}”
mx:grouping
mx:Grouping
mx:GroupingField name=”myGroupingField”/
/mx:Grouping
/mx:grouping
/mx:GroupingCollection
/mx:dataProvider
Hi Sameer.
I made a simple sample and sent it to you.
Figured it out.
In case this is useful to someone:
private function bindGrid():void
{
var objGrouping:Grouping = new Grouping();
objGrouping.fields = [new GroupingField("name")];
var objGroupingCollection:GroupingCollection = new GroupingCollection();
objGroupingCollection.source = agents.agent;
objGroupingCollection.grouping = objGrouping;
objGroupingCollection.refresh();
adgSales.dataProvider = objGroupingCollection;
}
Hi, its a great example. I was searching for placing elements in the row where a tree node(group) is formed and your example just solved my problem. I tried using the ArrayCollection through AS and everything was working fine. But when I tried the samething using an XML file as a dataprovider, I am not able to get the exact tree structure. Can you please let me know what should be the XML structure in such a case so that it forms the exact same tree structure as when using ArrayCollection.
My xml file is
2009-05-04T10:
27:48+05:30
2009-05-04T10:27:37+05:30
COMPLETED
Operation completed
2009-05-04T10:27:48+05:30
2009-05-04T10:27:36+05:30
I want to show only the children starting with tag….
subOperation tag
sorry not able to paste my xml file dont know hoe to format it
my xml looks like below
-return userID=”senthil-kumarv@hp.com”
–subOperation userID=”11″
—resActions dbid=”7″
—-endTime 2009-05-04T10:27:48+05:30
—subOperation userID=”12″
—subOperation userID=”13″
–resActions dbid=”6″
—endTime 2009-05-04T10:27:48+05:30
And i want to show the children having tag as subOperation
Hello everyone!
I updated my example in order to allow a filter on parent and children.
You can download the latest files here: http://computerarts.ca/_files/_flex/filtering_v2.zip
Thanks to my friend Marc-André for finding a solution!
Cheers
Steven
Hi Sameer… in my filterfunction, only the parent rows are coming through. It seems like the child rows don’t have the filterfunction applied to them. any ideas?
I am using a HierarchicalData tag as the source for my ADG. And I’m applying the filter as such…
IHierarchicalCollectionView(grid.dataProvider).filterFunction = statusFilter;
IHierarchicalCollectionView(grid.dataProvider).refresh();
I’ve figured it out.. thanks anyways..
I am building a basic ADG with a renderer showing the children.
A good example (not mine) is http://www.objectsatellite.com/html/FlexSolutions/ADGWithContainedADG/DataGridWithChildDataGrid.html
However when I apply a filter to the parent data (e.g name) then the children under the filtered rows do not show.
Any Ideas?
October 12, 2007 at 1:39 pm
Hey cool ! I didn’t now you finally started a blog .. Cheers !!
Nice post, Thanks