How to filter all nodes of a Flex Tree component

Flex logoIf you have ever tried to display filtered data in a Flex component, you’ll likely be aware that you can use an XMLListCollection object as the data source and that you can apply a filter function to that collection. The component only then displays the filtered data. However if you have tried this with a Tree component, you’ll have discovered that it doesn’t work. The filter is only applied to the top-level node(s) in the collection. The filter isn’t recursively applied to child nodes.

There is a an open bug related to this problem in the Flex Bug and Issue Management System. It is currently targeted to be fixed for Flex 3.4.0. In the meantime though, there is a simple work-around that I’ll describe here.

When rendering its nodes, a Tree object relies on a helper class that implements one of the ITreeDataDescriptor or ITreeDataDescriptor2 interfaces. By default it is an instance of DefaultDataDescriptor, but one is free to supply the tree with a different implementation. By overriding the tree’s data descriptor with one that supports filtering, the tree’s content can be easily filtered. The simple Flex SWF below demonstrates this point. Try selecting/ unselecting the checkboxes on the right and you’ll see that the tree’s content changes accordingly.

This movie requires Flash Player 9

The key to how it works is that the tree calls the data descriptor’s getChildren() method for each node. The filter function can therefore be called at this point and we only return to the tree the set of children that we want displayed.

My implementation of the ITreeDataDescriptor is far from complete. I have only implemented those methods needed to demonstrate the point, though it implements the required functionality just fine. The DefaultDataDescriptor is more complex, as it implements all the methods, plus it uses some clever caching mechanisms. I may implement a full replacement class at some stage that will support drag and drop for example, but for now that is left as an exercise for any reader who needs such functionality.

You can download the full FlexBuilder project source code for the above SWF here.

16 thoughts on “How to filter all nodes of a Flex Tree component

  1. Great post. I also (unwittingly) found the bug in using the XMLListCollection and filtering the subnodes when passing to a filterFunction. I plan to look over your solution in more depth tonight. Will the same approach work when you have subnodes of subnodes and want to filter on a value in the n-th subnode? For example:


    etc etc…

    Would this approach allow me to search for all products that are bright red AND expensive? Or something along these lines? See, Im interested in using XML to be able to filter subnodes by various filter values in order to be able to allow my users to have a variety of filters available.


  2. Well none of my xml was displayed… basically it looked like

    root product name="ball" price value="24.95" color value="green" purchases date value="2/2/2009" date value="5/7/2009" product name="yoyo" price value="10.95" color value="bright red" purchases date value="2/2/2009" date value="5/7/2009" ... root

    So if I wanted to find all products purchased in a date range and also cost more than $10 and were named yoyo. This is the type of solution Im trying to find. When your data is packaged so that there are multiple n-subnodes and those subnodes all contain subnodes that also contain data… etc Thanks!

  3. This script was a life saver. (Cuz If I would’ve spent another night working until sun-up, my fiancee would’ve killed me) As is, it works great for 1 level, but I needed to filter a tree with an unknown number of sub-branches as a user types in text into a textInput object. I finally came up with a working filter function and wanted to share that here:

    <mx:TextInput id="filterMenuInput" change="if(filterMenuInput.text){openAllTreeNodes(menuTree); menuTree.invalidateList();}else{closeAllTreeNodes(menuTree);}"/>

    private function filterMenuTree(node:Object):ICollectionView{
    var str:String = filterMenuInput.text.replace(/\s/g,"\\s");
    var re:RegExp = new RegExp(str, "i");
    return new XMLListCollection(node.*.(@label.match(re) || descendants().(@label.match(re)).length()>0));

    private function openAllTreeNodes(tree:Tree):void {
    tree.openItems = tree.dataProvider[0].parent().descendants();

    private function closeAllTreeNodes(tree:Tree):void {
    tree.openItems = [];

  4. Thanks for that. I thought there might be a recursive filtering bug on XMLListCollection as I came across a recursive sorting bug in XMLListCollection yesterday. I wish I had used an ArrayCollection! I believe they don’t suffer the same problems.

    In a style similar to your solution I overrode the getChildren() method in a subclass of DefaultDataDescriptor to apply a sort and filter function to the children collection. Which seems like an elegant workaround for a quite annoying bug…

  5. Thanks for the idea.

    I made a child from DefaultDataDescriptor with two overwritten functions:

    override public function getChildren(node:Object, model:Object = null):ICollectionView {
    if (filter == null)
    return super.getChildren(node, model);
    return filter(node);

    override public function isBranch(node:Object, model:Object = null):Boolean {
    return getChildren(node, model).length > 0 ;

    It fixes appearing of the open triangles by parents of the filtered nodes

    P.s.: It’s only for XML, of course.

  6. Thanks for the example. Helped me save time and energy researching filtering tree nodes.

    For those who need to enable drag behaviour, just need to implement

    public function getData(node:Object, model:Object=null):Object { return node; }

  7. One thing bothers me about the solution: each time getChildren is triggered, a new XMLCollection is created. Isn’t this a memory issue? Aren’t we creating here a memory leak?
    In such cases I prefer to cache the resulted array or something like that. Any simpler idea?

  8. i have a question.

    If i have several childrens, how could i filter that? because, now only the first children level is filtered.
    My tree has 3 levels of hierarchy, and i need filter the 3rd level. (node 3)
    node 1 –
    node 2 –
    node 3.

    Anu idea? Thanks in adevance

  9. hi,

    i have implemented the tree filtering without any problems, but i am having difficult time getting rid of first level node.

    for example if u tick off Red and Green –> the Yellow node would disappear instead of changing to a different Icon.


  10. I am developing a similar example and had a problem with scrollbar’s parent container. When I expand the tree, it creates the verticalscroll, but if I filter the tree to have a few nodes to disappear scrollbar, the scrollbar remains the same size, and if I scrolling, happens some issue in the layout tree ..

    I tried to call invalidateDisplayList in parent’s container but it did not fixed the problem.

    any suggestions?


  11. There is bug , when u filter with keyword that is not there in a xml, it goes blank , please suggest a solution

  12. Thanks a lot for this post. It took me a while to find a solution for my problem. :)

  13. hi Arthur,
    the workaround is to force your tree open and close once when you filtered your tree. try add:

    yourtree.expandItem( yourtreedata,false);
    yourtree.expandItem( yourtreedata,true);

    I am using 4.6 sdk, but seems the bug still exists. Won’t it be solved in version 3.4? Anyway, thanks to David, it still helps after so many years.

Comments are closed.