Filtering an XMLListCollection using the filterFunction property and regular expressions

Here is another handy little tip that you see all over the web, how do I filter a data grid (or other list-based control) based on a user’s input? Or more specificially, how to I limit the items that show in a list based on what a user types.

Since I already created a simple XML document of Countries/States, I thought I’d create a basic form that lets a user type in the first few characters of a state name and have the DataGrid filter its results. You’ll also notice that I had to do some not-so-tricky E4X filtering to extract only the American state names.

Full code after the jump.

View MXML

<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" verticalAlign="middle" backgroundColor="white">

    <mx:Script>
        <![CDATA[
            private function filterFunc(item:Object):Boolean {
                return item.text().match(new RegExp("^" + stateName.text, "i"));
            }
        ]]>
    </mx:Script>

    <mx:XML id="dp" source="countries_states.xml" format="e4x" />

    <mx:XMLListCollection id="xmlListColl" source="{dp.country.(@name == 'United States of America').state}" filterFunction="filterFunc" />

    <mx:VBox>
        <mx:HBox width="100%">
            <mx:Label text="Name:" />
            <mx:TextInput id="stateName" width="100%" change="xmlListColl.refresh()" />
        </mx:HBox>

        <mx:DataGrid id="dataGrid" dataProvider="{xmlListColl}">
            <mx:columns>
                <mx:DataGridColumn id="codeCol" dataField="@code" headerText="Abbr:" width="60" />
                <mx:DataGridColumn id="nameCol" dataField="*" headerText="Name:" width="240" />
            </mx:columns>
        </mx:DataGrid>
        <mx:Label text="Filtered: Showing {xmlListColl.length} record(s)" visible="{stateName.text.length > 0}" />
    </mx:VBox>

</mx:Application>

View source is enabled in the following example.

20 thoughts on “Filtering an XMLListCollection using the filterFunction property and regular expressions

  1. The written filter function in this example has a serious limitation – it only filters items from top level of hierarchy in XMLListCollection

  2. Hi Peter,

    I’m currently doing a filter function in an application. My understanding is that when you try to filter a specific dataField you can do this: “if (item.origin == “WA”)” “origin” is a specific column on a datagrid column. But what if I want to store that datafield column in a variable?

    for example: var custom_datafield:String = “origin” ;
    and do this: if (item.custom_datafield == “WA”) — I am not getting any returned records and it did not give me errors as well. I need your expertise on this.
    Are there any other way to do this?

    In case you are wondering why I need to store the dataField name into a variable is because I am creating a datagrid component that will accept any XML file using only one datagrid and one filter functionality.

    Thanks,
    Arnold

    1. If you want to use a variable to specify which column you want to filter on, use [].

      E.g.
      return item[filterField] == cbFilterL1Select.text;

      where filterField is string in which you store the column name.

      Thanks,
      Istvan

  3. Is the fact that only the top level of hierarchy in the XMLListCollection is filtered using filterFunction a bug?

    Like JabbyPanda said that is a HUGE limitation. Is there somework around for this? Is there a way to assign a filterFunction on each level of the XMLListCollection hierarchy?

  4. Seconding Frogmo’s request for a workaround to the filterFunction’s deficient filtering. I think they just used ListCollections on flat hierarchies and when they added the XML counterpart, they forgot expand the filterFunction’s functionality.

  5. Has a bug report been filed for the top level filtering problem? I haven’t been able to find any information on it.

  6. From one Peter to another, thanks. However, I keep getting an error, “TypeError: Error #1006: value is not a function.” I’m not sure why this pops up. I originally tried applying this code to a working filterFunction that matched characters exactly, but when that didn’t work, I recreated an app from scratch, following the example above, but I still get the “…not a function” error. Any clues why this would show up?

  7. Hey Peter,
    You are just superb…………you don’t know how much you help me in every ways in flex development by posting so many working examples. They are very much self -explainatory and useful for everyone. Thanks a ton buddy…………….May god bless you all the happiness in the world…

    Cheers…

  8. Hi Peter,

    I’m new in Flex development and trying to find some examples where Data grid ( or Advance data grid ) can be filtered based on Start date and End date selection . I could not able to find something related on your sit e. Can you please provide sample example .

    Thanks,
    Rishi

  9. Hi Peter, I’m having the same problem as the “other Peter”, I’m getting this error:

    TypeError: Error #1006: value is not a function.

    It is dispatched as soon as my HTTPService returns succesfull and executes this code:

    xmlList.source = result.children()

    Which dispatches internally in the following order:
    at mx.collections::XMLListCollection/set source() >
    at mx.collections::ListCollectionView/set list() >
    at mx.collections::ListCollectionView/http://www.adobe.com/2006/flex/mx/internal::reset() >
    at mx.collections::ListCollectionView/internalRefresh() >
    at views.bkmgr::AddResourcesView/equipFilterFunc()

    The filter function is exactly:


    private function equipFilterFunc(item:Object):Boolean
    {
    return item.text().match(new RegExp("^" + txtin_searchFilter.text, "i"));
    }

    I’m running FB 4.5.1, thanks in advance!

Comments are closed.