Posted on

SearchInput control

There’s a couple of projects I’ve been working on lately, one of which is the BugQuash QuashBoard, that require a search input. I decided to quit duplicating some of the work I’m doing and create a SearchInput control that extends the TextInput control and wraps the search logic into a reusable component.

The thought process went like this: I wanted a search field that when I typed, the datagrid (or whatever the data was displaying in) would filter out the rows that didn’t match the search terms. FilterFunctions do just that, but they don’t work on the DataGrid or List directly, they work on the dataProvider. The dataProvider must implement ICollectionView to have a filterFunction applied to it. You can figure this out by searching for filterFunction and finding that it is defined in ListCollectionView. ListCollectionView defines the function because it’s in ICollectionView, which ListCollectionView implements. I programmed to an interface, not an implementation.

So, I extended the TextInput class and added a public property called dataProviderToFilter:ICollectionView that will take the dataProvider it needs to work on, and another public property called propertiesToSearch:Array that is an Array of Strings identifying the properties of the objects used for each row. It uses a no-arg constructor, which makes it available to use in MXML as well, just like the TextInput.

<theflexguy:SearchInput id="searchTxt" width="100%"
	propertiesToSearch="{['artist','album','description']}"
	dataProviderToFilter="{my8TrackCollection}"/>

Since I will probably use this a number of times, I’ll share it with the world. Once again, it’s not as hard as it seemed, which should be your mantra for Flex development.

SearchInput.as
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
package com.theflexguy.controls
{
	import flash.events.Event;

	import mx.collections.ICollectionView;
	import mx.controls.TextInput;

	public class SearchInput extends TextInput
	{
		// dataProviderToFilter must implement ICollectionView so a
		//  FilterFunction can be applied to it.
		public var dataProviderToFilter:ICollectionView;

		// propertiesToSearch is an Array of property names as Strings
		public var propertiesToSearch:Array;

		private var _searchWords:Array;

		// Splits the search text up using spaces to get the "words",
		//  then sets the filterFunction
		private function searchTxt_changeHandler(event:Event):void
		{
			if (text != "")
			{
				// split up the input into individual "words", made 
				// upperCase so it's case insensitive
				_searchWords = text.toUpperCase().split(" ");

				// check to see if the last item is a 0 length String, this
				// would be the case if the last character typed was a space
				if (_searchWords[_searchWords.length - 1] == "")
				{
					// if it is "", remove it
					_searchWords.pop();
				}
				// set the filterFunction
				dataProviderToFilter.filterFunction = filterForSearch;
			}
			else
			{
				// the user removed the text so remove the filterFunction
				dataProviderToFilter.filterFunction = null;
			}

			// refresh the dataProvider
			dataProviderToFilter.refresh();
		}

		// Uses the searchWords array to search the summary and components
		//  fields of each row for each item in the array.
		private function filterForSearch(item:Object):Boolean
		{
			var match:Boolean = false
			for each(var s:String in _searchWords)
			{
				for each(var p:String in propertiesToSearch)
				{
					// check each property for the word using 
					// toUpperCase so it's case insensitive
					if (item[p].toString().toUpperCase().match(s))
					{
						match = true;
						break;
					}
				}
			}
			return match;
		}

		public function SearchInput()
		{
			super();
			addEventListener(Event.CHANGE, searchTxt_changeHandler);
		}

	}
}

Leave a Reply

Your email address will not be published. Required fields are marked *