logo

Flex: How To Filter a View On User Input

Getting back to the accounts demo - the eagle-eyed might have noticed I added a "search" box above the view. As you can see below, as you type in a string the content of the DataGrid/view change to show only the entries matching that string.

 ScreenShot002

It's not really searching, as such. I guess it's more like filtering than searching.

How Does It Do That?

As with lots of things Flex it is relatively simple to filter a data grid. The grid's content comes from its "dataProvider". In this case that's the XML returned from Domino to represent each document in the database. The XML looks like this:

<documents>
        <document unid="CB609D90B0103EF886257623007EBFC5">
                <date>09/01/2009</date>
                <description>Nuka Cola</description>
                <direction>incoming</direction>
                <category>Sponge</category>
                <amount>1025.00</amount>
        </document>
        <document unid="90479C82FDDFB71186257624000A7CBE">
                <date>09/01/2009</date>
                <description>Sexy nightwear</description>
                <direction>outgoing</direction>
                <category>Clothes</category>
                <amount>3333.00</amount>
        </document>
        ....
</documents>

What we need to do is look at the XML and produce a subset of it, which contains the string being filtered on. Not as difficult as you might think. You don't even have to do any looping! It can all be done with E4X.

If you're going to get in to Flex then you really need to get yourself familiar with both how it handles XML and how to use E4X.

To find matching rows from the above XML format we can use the following ActionScript:

var token:String = fldFilter.text.toUpperCase();

var hits:XMLList = xmlDocuments.(
        child('amount').toUpperCase().indexOf(token) === 0 || 
        child('description').toUpperCase().indexOf(token) != -1
);

if (hits.length() > 0) {
        viewExpenses.dataProvider = hits;
}

What this does is take the string the user entered (in to a TextInput element with id "fldFilter") and looks inside the xmlDocuments object (which represents the XML for the grid) for matches. To find matches it uses the E4X syntax to compare the values of certain child elements. In this case we're look for document with a description that contains the string anywhere in it or where the amount matches the input exactly.

Once we have our slimmed-down XML we can apply it as the dataProvider of the grid, whose ID is "viewExpenses".

Simple, no?

I've missed out the key-down handling logic, which sets a timer to know when you're done typing etc but you get the point? What I'm wanting to show is how easy it is to use E4X to subset the XML in a DataGrid/view.

Tomorrow I'll show how to take it one step further and add a little wow factor at the same time.

Proper Searching?

As noted, this isn't really searching the database and the filter box isn't meant to replace any search box which might end up appearing at the very top right of the page.

In the accounts app the view just happens to show all documents in one go, so the filtering can be expected to behave a little like searching. If you're grid doesn't show all backend documents then you might want to think about how you convey this to the user. Alternatively you might want the filter box to send a request back to the server to do a search/filter there and fetch back a completely new set of XML. Again, not hard to do.

Related Reading

  • The search box itself is based on the "fancy search field" I talked about a few weeks back.
  • The key-press-handling timer code for performing the filtering as you type is borrowed from this org chart demo.

Comments

    • avatar
    • Palmi
    • Tue 1 Sep 2009 06:29 AM

    Great Tip , E4X is new to me . thanks for this info.

  1. Nice post. This will come in handy. Thanks much!

  2. Yep, great post. Thanks

    • avatar
    • Marcin
    • Thu 3 Sep 2009 07:05 AM

    The "right" way to do this is to use Collections and the filtering built into those. Basically you create an XMLListCollection to use as your data provider which wraps your doucments - eg. provider = new XMLListCollection(xmlDocuments.document); Then you use the filterFunction property of a collection (which comes from the ICollectionView interface - ArrayCollection has this same interface too) to create a filtering function.

    The filtering function takes an item (ie. a single XML node) and returns a boolean whether it should be included or not. In this function you do your test against the value of the text field.

    When the text field changes you just call provider.refresh() which causes the filtering function to be reapplied.

    Here's a quick and dirty example I wrote just to make sure it works.. http://pastebin.com/m3c448f34

    • avatar
    • Jake Howlett
    • Thu 3 Sep 2009 09:54 AM

    Hi Marcin. Thank you! I didn't know about that method. Much cleaner! Going to retrofit it to my code as soon as I get the chance.

    Your approach fixes an issue with my approach, whereby edited a "document" updated the selectedItem in the "view"'s dataProvider. If you edited a document when looking at the filtered view it would appear to update in the front end but when you clear the filter it reverts to the original dataProvider (a different XML object) where the values remain unchanged. Naturally a full refresh of the app would bring the saved values from the server, but I guess your approach avoids this?

    Thanks again, I love to learn best/better practice as I go. At least now we've given people two approaches and more food for thought...

    Jake

    • avatar
    • Marcin
    • Thu 3 Sep 2009 04:56 PM

    I've been doing Flex for over 2 years and only really discovered that recently when studying for my certification exam. :)

    There's a whole bunch of fancy stuff you can do with collections, data grids and Data Services where a lot of the paging and data fetching is auto-magic. Might be possible to do something with Domino via Java and BlazeDS, but that's getting into non-trivial territory!

  3. Hey,

    i created a Flex Library (DataFilterLib) that take care of all the filtering process, completly in MXML.

    This library is free, you can find the project details there:

    http://code.google.com/p/flex-datafilterlib/

    If you want to have a look at the examples, they are all there (source available):

    http://www.flex-tutorial.fr/DataFilterLib/examples/

    Check the examples online if you want to see how to filter on multiple criterias, using different Flex UI Components (CheckBox, Slider, List, ...).

    Thanks,

    Fabien

    http://www.flex-tutorial.fr

    • avatar
    • alfredo
    • Wed 27 Jan 2010 04:50 AM

    My Datagrid has an Arraycollection not an XML as dataprovider.

    How can i implement this?

    Thank you!

  4. Excellent Work...How to get this code....

Your Comments

Name:
E-mail:
(optional)
Website:
(optional)
Comment:


About This Page

Written by Jake Howlett on Tue 1 Sep 2009

Share This Page

# ( ) '

Comments

The most recent comments added:

Skip to the comments or add your own.

You can subscribe to an individual RSS feed of comments on this entry.

Let's Get Social


About This Website

CodeStore is all about web development. Concentrating on Lotus Domino, ASP.NET, Flex, SharePoint and all things internet.

Your host is Jake Howlett who runs his own web development company called Rockall Design and is always on the lookout for new and interesting work to do.

You can find me on Twitter and on Linked In.

Read more about this site »

Elsewhere

Here are the external links posted on the same day.

More links are available in the archive »

More Content