Flex Filtering Long Lists

If you have a list box with a large number of items in it it can be hard for someone to find the item in the list that they need. One way around this is you add a filter on the list box.

Here's how it's done.

First off it best if you use an ArrayCollection as they provide a built in method of filtering. You can set up a filter function on an ArrayCollection that looks at every item and returns true or false if you want the item to be in the list. Refresh the list and every item is checked again. If you want the original list back just remove the filter function and refresh the list and all is back the way it was.

The other ingredient is a text field that that as you type takes the contents of the field and applys it as a filter on the list.

Here's the code.

view plain print about
1<?xml version="1.0" encoding="utf-8"?>
2<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="init()" viewSourceURL="srcview/index.html">
3
    <mx:Form>

4        <mx:FormHeading label="Select Suburb" />
5        <mx:FormItem label="Search" direction="horizontal">
6            <mx:TextInput id="filter" change="setFilter()" />
7            <mx:Text text="{locations.length} suburbs found" />
8        </mx:FormItem>
                    
9        <mx:FormItem label="Suburbs">
10            <mx:List dataProvider="{locations}" rowCount="10" width="300" labelFunction="locationPostcode" />
11        </mx:FormItem>

12    </mx:Form>

13    
14    <mx:Script>

15        <![CDATA[
16            import mx.collections.*;
17            
18            [Bindable] private var locations:ArrayCollection = new ArrayCollection();
19            
20            private var text:String = "
";        
21            private var loader:URLLoader;
22            
23            public function init():void {
24                // load postcode csv file
25
                this.loader = new URLLoader();
26                this.loader.dataFormat = "
text";
27                this.loader.addEventListener("
complete",this.loaded);
28                this.loader.load(new URLRequest("
postcodes.csv"));
29                
30                // sort by location
31
                var sort:Sort = new Sort();
32                sort.fields = [new SortField("
location")];
33                this.locations.sort = sort;
34                this.locations.refresh();
35                    
36                this.locations.filterFunction = filterLocation;
37            }
38            
39            // display suburb and postcode
40
            private function locationPostcode(data:Object):String {
41                return data.location + "
(" + data.postcode +")";
42            }
43    
44            // set up filter on location array collection
45
            private function setFilter():void {
46                this.text = filter.text;
47                this.locations.refresh();
48            }
49            
50            // called when postcode file loaded
51
            private function loaded(evt:Event):void {
52                var file:String = this.loader.data;
53                var lines:Array = file.split('
\r');
54                
55                // covert file into an array collection
56
                for (var i:Number = 1; i < lines.length; i++)
57                {
58                    var data:Array = lines[i].split('
,');
59                    var item:Object = new Object();
60                    
61                    item.postcode = data[0];
62                    item.location = data[1];
63                    
64                    this.locations.addItem(item);    
65                }
66            }
67    
68            // filter array collection by what user types
69
            private function filterLocation(item:Object):Boolean {
70                if (item.location.toLowerCase().indexOf(this.text) >= 0) {
71                    return true;    
72                }
73                else {
74                    return false;
75                }
76            }
77        ]]>
78    </mx:Script>
79</mx:Application>

The code reads an CSV file that contains a list of all suburbs/postcodes in Australia.

This technique can be easily expanded to search on multiple fields. For example you could have a list of locations and filter on the name, the address, the city and/or the postcode

Now you might think that this method is going to be a little slow. It's not! It can easily handle lists of 1,000 or 2,000 items and even up to 50,000 items without any noticeable performance issues. The postcode example contains more than 16,000 locations. Of course downloading and sorting data of that size may cause a little delay before the list box is populated.

Here's the running code (right click to view source and/or download):

Related Blog Entries

TweetBacks
Comments (Comment Moderation is enabled. Your comment will not appear until approved.)