ArrayCollection with multiple filter functions


Lately I have been working a lot with complex forms and data filters. If you have some four or five forms, each affecting the same data collection and each having between 5 and 10 filter criteria, you'll start feeling you're no longer in control of your situation.

The ArrayCollection class has a built-in filtering mechanism, where you pass a function reference to the filterFunction property in order to filter out the items that don't satisfy the function's criteria. This is extremely useful, but if you need to filter on more than one criterion you'll have to complicate the filter function more and more. I don't know why, but It gives me the same chills on my spine as hardcoding does.

The solution was to extend the ArrayCollection and add the option to provide an array of function references as filters. The final result is the AND between each evaluated filter function. It's one of those situations when writing some few extra lines of code really pays off.

Here's the class code:

package eu.rotundu.collections
{
 
import mx.collections.ArrayCollection;
 
public class ArrayCollectionExtended extends ArrayCollection
{
	private var _filterFunctions:Array;
 
	public function ArrayCollectionExtended( source:Array = null )
	{
		super(source);
	}
	public function set filterFunctions( filtersArray:Array ):void
	{
		_filterFunctions = filtersArray;
		this.filterFunction = complexFilter;
	}
	public function get filterFunctions():Array
	{
		return _filterFunctions;
	}
 
	protected function complexFilter( item:Object ):Boolean
	{
		var filterFlag:Boolean = true;
		var filter:Function;
		for each(filter in filterFunctions)
		{
			filterFlag = filter( item );
			if( !filterFlag )
				break;
		}
		return filterFlag;
	}
}
 
}

And here's how you use it:

someArrayCollection.filterFunctions =
	[ 	filterByVendor, filterByPrice,
		filterByTime, filterByEventType,
		filterByKeywords
	];	
 
someArrayCollection.refresh();

You can download the source code.

You can also run a working example or view its source code.

Information and Links

Join the fray by commenting, tracking what others have to say, or linking to it from your blog.


Other Posts

Write a Comment

Take a moment to comment and tell us what you think. Some basic HTML is allowed for formatting.

Reader Comments

That’s very useful and posted just at the right time … thank’s

Well – I tried it, but it doesn’t work for me. When I add a second filterFunction to the filterFunctions array the filtered ArrayCollection is always empty. Do you have any ideas. ? (Each filterFunction applied as usual works)

Rico,

Normally you should have no problem with this.
Your problem can be:
1. your filter functions exclude each other’s results when applied. Keep in mind that the an element in the collection must satisfy ALL the filters at the same time.
2. you didn’t call ArrayCollection.refresh() after you added a new filter function to the array. You must always do that after changing filters. (just like the normal filterFunction in ArrayCollection).

If none of the above are the reason, post your code so I can be of more help.

.peace

Hello my friends :)
;)

Could you create an application to see it used in a working environment ? I have not been able to implement your class successfully so fare unfortunately…

@Sep

Hi,

I’ve updated the post with a link to a simple working example plus source code.

cheers!

Hello All,
Kind of new to the whole Flex thing. This is exactly what I’m looking for. Has anyone tried to us this through a remote object call(I’m using coldfusion)?

I’m trying to make my app as dynamic as possible. The new ArrayCollectionExtended collection seems to be changing the way you assign the data to the collection type. I don’t get an error, just a blank datagrid. The data doesn’t seem to get assigned properly.

Does Anyone have any ideas on how to assign the data to the ArrayCollectionExtended collection properly?

Below is what I have, I think I’m close, I just need that missing link.

Thanks for any help anyone can give me.

@Chris,

Hi, download the demo application source and take a look inside. It should be straightforward even if your data is not hard coded (as mine was) and it comes from CF (or anything else).
Post your code if you need more specific help.

.peace

Hi Cristian,
I’ve been working with your demo, I think I’m missing just a little piece.
;

;

Ok, posted a screen shot of what I have. I’ve broken it down to this very specific step.
http://chrismauger.com/flexfiltering/

Back to you Chris,

Try this workaround:

dataAr = new ArrayCollectionExtended( (e.result as ArrayCollection).source);

Avoid using “e.result as ArrayCollectionExtended”. It seems it always returns null. I will find an answer to this soon, but right now I don’t have much time for it.

cheers!

Cristian,
That worked great! Thanks so much!

Christian,
Thank you, thank you, thank you. I have been dreading a multiple filter function for a GIS app I am building. I talked with Simeon at the summit and we only though of very ugly ways to do this. Great solution and very elegant. I will be blogging your effort and singing kudos from the mountain tops. THANK YOU SO MUCH!
Adrian

Adrian,

hehe…you’re welcome, you’re welcome, you’re welcome :) I’m glad you found it useful…
Thanks for visiting, Cheers!

Cristi

[...] That’s right, you can now apply multiple filters on a collection.  The core to this solution was created by Cristian Rotundu and can be found at: http://blog.rotundu.eu/flex/arraycollection-with-multiple-filter-functions/#comment-50. [...]

Quick question:
Why do you check for filterFlag being true in the line
filterFlag = (filterFlag && filter( item ));

If filterFlag is false, won’t it break out of the loop and return false anyway?

Hi Gareth,

Yup, you are absolutely right! In that line, the second “filterFlag” is redundant; it’s just a residue from a previously abandoned approach.

Thank you for pointing that out to me, I will make the correction.

Cheers!

@Christian,
No problem. I completely understand about the code residue. There have been many times I’ve gone back in to code a few months later to see the remnants of previous attempts at something. I just thought it was doing something and didn’t want to screw something up if I removed it :) . Very useful snippet, by the way. Thanks for posting it.

My arrayCollection for the comboBox is dynamic and does not have a data field. I can’t seem to make the changes to get it to work. How would I change the functions to make it work with just the labelField?

Hi Duane,

Simply modify the ChangeHandler of each ComboBox, particularly this line:

selectedType = cbProductType.selectedItem.label;

Or, instead of “label” or “data” you can have any property of the object stored in your collection.

If this doesn’t clear things up (maybe I didn’t get you right) post your code with the problem so I’ll have a better chance in helping you.

hi cristian, i have a datagrid that is populated by a cfquery through remote objects and i want to filter it using 2 combos and a slider could you please post an example that uses cfcs instead of hard coded data. been struglling with this all week now.please help.

hi i have finally understood how to use your snippet but i have one problem. my filtering combo boxes get data dynamically from a cfc so i neither have a data field or label field so when i try to filter the datagrid there is no change . i think its the same problem that Duane had so i tried the work around you gave him but there is still no change. am stuck.help!!!

hi Arthurnasius

Normally you should have no problem with this. The sample I gave to Duane is from an application that uses CF…
Post your code I will try to help you.

Cheers!

hi i have sent my code to your email address please help me figure out what is missing.thanks

Hi Arthurnasius,

I went through your code, nothing seems to be wrong, at least from what concerns the ArrayCollectionExtended and the related methods.
You may have some other problems that I cannot see from your fragments.

Here are some questions and tips to help you find your problems:

1. does your collection receive any data from the server? check that.
2. if so, how does the “filters not working” issue manifest?
(a) Does it eliminate all your items from the DataGrid?
(b)Or it simply does nothing and you can see all of them?
3. debug your app and place breakpoints in all your filter functions. First see if they are even executed, then see what value they return.
4. make sure you’re comparing the correct properties for the item in the filter functions. Check the values and the result of the filter function.
5. check for the values of the “selected[***]” variables and if they get the correct values in the change handlers.
6. i found this method in your code
public function filterAC():void { dataAr.filterFunction=cityFilterFunc dataAr.refresh();
}
I hope you’re not using it anywhere, because you’d be canceling the collection’s filters array.

7. if still no result, use one filter at a time and make sure there is no filter that always returns false. Keep in mind that all filters must be true for a certain item to have it displayed in the DataGrid (it’s an AND operation between each function).

8. make sure no other methods interfere with your collection.

That’s the best I can give you now. Let me know how these help you.

peace

hello my collection does not receive data from a web server. the “filter not working” issue manifests in a way that it simply does nothing and i see all the info in the datagrid. am still at the same point i was in 2 days ago.

Did you try all the steps below?
Please add answers to each point enumerated before. This way I can have a better image of your situation.

also, sorry about the “web server”, I meant server in the generic way of referring to server side, i don’t know how “web” got there :) The idea was to check that the data DOES indeed get into your collection.

hi i just realize when i comment out the return false; statement i get an error on each of the filter functions saying “Function does not return a value” any thoughts?

i removed the following function
public function filterAC():void { dataAr.filterFunction=cityFilterFunc dataAr.refresh();
}, i made sure that am comparing the correct properties for the item in the filter functions. but there is still no change. i have never debugged an app be4 how is it done

One other thing i left out is that the comboboxes get data from cfcs not hardcoded array.

Cristian, I posted back on 6/21 about the dynamic arrayCollection. I still haven’t got the code working. As you requested I am posting the key elements of my code for help purposes. Thanks.

[Bindable] private var linkCol:ArrayCollectionExtended = new ArrayCollectionExtended;
[Bindable] private var storeCol:ArrayCollection = new ArrayCollection;
private var selectedName:String = “– All Stores –”;

public function onResult(event:ResultEvent):void {
linkCol = new ArrayCollectionExtended((event.result as ArrayCollection).source);
StoreName(linkCol);
}
public function handleCreationComplete():void {
var promotion:String;
displayLinks.getAllDisplayLinks(promotion);
linkCol.filterFunctions =
[
filterByName
]
linkCol.refresh();

}
private function StoreName(tempCol:ArrayCollection):void
{
var tempObject:Object = tempCol[0];
storeCol.addItem(tempObject.storeTitle);
storeCol.addItem(‘– All Stores –’);

for (var i:int = 0;i<tempCol.length;i++)
{
for(tempObject in tempCol)
{
if (storeCol.contains(tempCol[i].storeTitle) == false)
{
storeCol.addItem(tempCol[i].storeTitle);
}
}
}
var sortA:Sort = new Sort();
sortA.fields = [new SortField (null, true) ];
storeCol.sort=sortA;
storeCol.refresh();
}

private function filterByName( item:Object ):Boolean
{
if ( item.storeTitle == selectedName || selectedName == “– All Stores –” )
return true;
return false;
}

private function storeNameChangeHandler():void
{
if( cbStoreName.selectedItem != null )
selectedName = cbStoreName.selectedItem.label;
linkCol.refresh();
}

It cut of the flex code. Here it is again.

Here is the flex without the opening and closing tags:

RemoteObject id=”displayLinks” destination=”ColdFusion” source=”bin-release.cfc.displayFlexLinks” showBusyCursor=”true”
method name=”getAllDisplayLinks” result=”onResult(event)” fault=”onFault(event)”
RemoteObject

ComboBox id=”cbStoreName” dataProvider=”{storeCol}” prompt=”Sort By Store” width=”150″

DataGrid width=”100%” height=”100%” dataProvider=”{linkCol}”
columns
DataGridColumn dataField=”promotionType” headerText=”Promotion Type” width=”100″
DataGridColumn dataField=”storeDesc” headerText=”Offer” width=”275″ wordWrap=”true”
DataGridColumn dataField=”storeTitle” headerText=”Store Name” width=”175″
columns
DataGrid

You guys *really* have to start learning to use the debugging tool in Flex Builder. It really is invaluable in situations like these. It makes debugging infinitely simpler as you can step through your code.

@Duane Hardy,
To debug what is happening, I would throw some breakpoints in your handleCreationComplete and filterByName functions and step through them. Make sure to display the “item” variable (or item.storeTile and selectedName), just so you can see what the code “sees”. This should show anything that is amiss, either in your logic or the way you are calling your functions.

I would also suggest something similar for Arthurnasius Amanyire, but I haven’t seen his code so I wouldn’t know where to place breakpoints (but at least placing them in your filter functions, and the place that is *calling* your filter functions would be a good start).

hi guys i have tried everything, the debug shows that my filterFunctions are fine. i have tried following the instructions in the code step by step and i cant find where am going wrong. am out of ideas.

Arthurnasius, Duane

You said that the collection receives data and the data shows in your DataGrid.
You also said that your “filterFunctions” are fine. They must be more than just that.
Have you seen the way they work on different items?
Have you carefully watched the values these functions return for items that meet the condition or for those that don’t?
From your description it appears that all of them, ALWAYS return true.
There’s also the case when you don’t setup the filter functions properly and the functions are never executed. That’s why debugging the functions will clear things.

To sum everything up, this app cannot fail if:

1. you DO have the data in the collection
2. you DO set up the filter functions array and you DO call refresh() after that
3. you CAN confirm that the filter functions execute for every item (breakpoints, debugging)
4. you DO have the correct comparison in the filter functions (obj properties, values, logical operators, etc) and…
5. you CAN confirm that by watching the returned values for each filter function and for each item in the collection
6. you DO write your changeHandlers right, assign new values for the “selected[***]” variable and call refresh on the collection to trigger the filters again.

i tried using only one filterfunction which is the slider because i hardcoded it exactly like yours though different ranges and it still didn’t work.

@Arthurnasius,
What does the data show in your filterFunction when you are running through it? Can you post the filter function? If you can see the compared values in your filterFunction (when you are debugging), any that are returning false should be hidden from view.

hi guys am sorry for disturbing you. i have failed to make this filter solution work for me and yet everything is the same except may data is coming from a database through cfc. could it be because am using flex builder 2.0.1? please help me.thanks

Hi,
It shouldn’t be a problem if you use Flex Builder 2, at least not with this component.

There is an error in the code example at the top of the page.

for each(filter in filterFunctions)
Should be:
for each(filter in _filterFunctions)
There is a missing underscore.

After that fix, everything worked great.
Thanks for a great script.

No, it is correct as it is. filterFunctions is using the accessor to get its value (from _filterFunctions), not accessing the private variable _filterFunctions directly (bad practice)

It’s strange that the code didn’t work for using the accessor. I will have to look into this more. Thanks.

Hi, I finally got it to work. Thanks, for the solution.

Can someone test this scenario/possible bug to see if it’s just just me.

(1) Took an array of 48 records

(2) Applied a filter, it filters out properly

(3) Set it back to default, the array should read 48 as it did before I applied the first filter but it always seems to drop 1 out of the array.

(4) I have .length bound to a label to keep track, it shows 47,

record [35] always seems to get dropped.

@K,

You may want to provide more details for this one: array content, filter function.
One thing’s for sure, it doesn’t have anything to do with the number of records (the scenario did not reproduce).
I suspect your filter function is doing something wrong there.

Cheers

Thanks for testing…

I back tracked my code, the problem was one of MY HSliders…

It works great now.

When i copied the code to my project something goes wrong, it didn’t work at all, shown correct answer only for single filter in a queue. But I make some correction in the ArrayCollectionExtended as follows:

protected function complexFilter( item:Object ):Boolean
{
var filterFlag:Boolean = false;
var filter:Function;
for each(filter in filterFunctions)
{
filterFlag = filter( item );
if( filterFlag )
break;
}
return filterFlag;
}
I changed default flag tu false and seek ‘true’ filter answer, then break. Everything works fine for me now.

Cheers
Kuba

@Kuba

You probably have your filter functions returning true where they should be returning false. Here’s the logic behind the code and why normally you should have no need to change it :)

The initial assumption is positive, we give a chance to all filter functions, but if proven wrong at some point by one of them, we break the loop and return ‘false’, since we no longer care about what the other functions return: 1 AND 0 AND x AND y AND z is hopelessly stuck to 0 no matter who you know up there and what strings you can pull :)

Cheers!

Sure thing now ;)
Thanks for answer

Christian, thanks for sharing this extension! Works great.

Don Kerr
Manager, Space City Adobe User Group

Hi,

I have a problem to use this very useful package. Hope someone can help me.

I get my data from a xml file via HTTPService and use TileList for the render. In my exemple i use 2 filters but they have no effect when i use it.
(TileList is filled correctly with my data)

I try to add some debuging line (trace) in the filter function but nothing appear.

Thanks in advance !

Here a part of the script:

import mx.rpc.events.ResultEvent;
import eu.rotundu.collections.ArrayCollectionExtended;
import mx.collections.ArrayCollection;

private var selectedMinAge:int = 18;
private var selectedMaxAge:int = 50;
private var selectedEyes:String = “all”;

[Bindable]
public var dptestCollection:ArrayCollectionExtended = new ArrayCollectionExtended;

private function creationCompleteHandler():void
{
/* setup the filters array: in order to take effect
* you must call refresh() on the collection
*/
dptestCollection.filterFunctions =
[
filterByAge, filterByEyes
];

dptestCollection.refresh();
}

private function resultHandler(evt:ResultEvent):void
{
dptestCollection = new ArrayCollectionExtended( (evt.result.dptest.row as ArrayCollection).source);
}

// Age filter
private function filterByAge( item:Object ):Boolean
{
if( selectedMinAge item.age )
return true;
return false;
}

// Eyes filter
private function filterByEyes( item:Object ):Boolean
{
if( item.eyes == selectedEyes || selectedEyes == “all” )
return true;
return false;
}

// Change handlers, nothing new here
private function ageChangeHandler():void
{
selectedMinAge = hsAge.values[0];
selectedMaxAge = hsAge.values[1];

dptestCollection.refresh();
}

private function eyesChangeHandler():void
{
if( cbEyes.selectedItem != null )
selectedEyes = cbEyes.selectedItem.data;

dptestCollection.refresh();
}

Hi Michael,

here’s where I think your problem is:

you add the filters to the collection in the creationCompleteHandler but then in the resultHandler you recreate the object. Everytime you recreate the dptestCollection you must set its properties again (filters in this case). Makes sense, right?

Cheers!
Cristian

Yes it does… I moved dptestCollection.filterFunctions in the resultHandler function and
all works great !

Thanks so much Cristian !

Great Class thanks.

The strange thing is that why I instantiate ArraycollectionExtended:

staffResult= new ArrayCollectionExtended();

the actual object, staffResult, is null after this line of code. Strange. ANy ideas

hi there, would you try the next thing :
myArray.filterfunction= filterFunction(myVar:Number)
This would make it possible to reuse the same filterfunction for different arrays
greetings from Belgium
PS we are not at war :)

@frederic

It may be the fact that I traveled for 14 hours to see a two hours concert…but I read your comment five times now and I’m not sure I understand it…
“This would make it possible to reuse the same filterfunction for different arrays”
What the class wants to do is to avoid complicating (by hardcoding) one single filter function in order to filter a collection by multiple criteria. This is because at some points in the collection’s life you may only want some of the filters active, switch them on and off at runtime, etc.

Again, I apologize if what you said has a different meaning :) …I’d be happy if you gave us more details about your point of view.

Cheers,
Cristian

P.S. Belgium rocks!

[...] really like the options I was presenting. After I got back I did a couple google searches and found this example. I think Cristian did a great thing here by extending the functionality of the ArrayCollection to [...]

thanks Christian – this really helped
I liked you comment ‘feeling you are no longer in control of your situation’ – which sums up multiple filtering perfectly. This function certainly puts the situation in control.

Thanks! I’m glad you’ve found it useful.

.peace

Hi – great idea.

Hope you don’t mind, but I butchered your code for an project where I couldn’t subclass ArrayCollection and came up with an alternative:

// setting the complex filterfunction
var cff:ComplexFilterFunction = new ComplexFilterFunction([
filterByPrice,
filterByType,
filterByCondition,
filterByVendor]);
productsCollection.filterFunction = cff.filterFunction;

// the ComplexFilterFunction class
package
{
public class ComplexFilterFunction
{
private var _filterFunctions:Array;

public function ComplexFilterFunction(filtersArray:Array)
{
_filterFunctions = filtersArray;
}

public function filterFunction( item:Object ):Boolean
{
var filterFlag:Boolean = true;
var filter:Function;
for each(filter in _filterFunctions)
{
filterFlag = filter( item );
if( !filterFlag )
break;
}

return filterFlag;
}
}
}

Thanx from Turkiye :)

Hi Cristian,
i used your code in my app to filter items in TileList and its work fine with litle prob.
the problem is i cant use DefaultTileListEffect i’ll try to send the code any help will be great thanx.

<![CDATA[
import eu.rotundu.collections.ArrayCollectionExtended;

import mx.rpc.events.ResultEvent;
import mx.collections.ArrayCollection;
[Bindable]
public var productsCollection:ArrayCollectionExtended = new ArrayCollectionExtended;
[Bindable]
public var secilenKategori:String;
public function secimSorguGonder():void{
secimSorgu.send();
currentState=”;
markalar.send();
}
[Bindable]
public var secilenUrun:Object;
private function detaylariGoster(event:Event):void{
currentState=’detaylar’;
secilenUrun=new Object();
secilenUrun=event.currentTarget.selectedItem;
buyukResim.source=(secilenUrun.resim);
aciklama1.text=(secilenUrun.aciklama1);
aciklama2.text=(secilenUrun.aciklama2);
markaD.text=(secilenUrun.marka);
parabirimi.text=(secilenUrun.parabirimi);
fiyat.text=(secilenUrun.sonkullanici);
kdv.text=” + %”+(secilenUrun.kdv)+” KDV”;
}
import mx.formatters.NumberBase;
import mx.effects.easing.Elastic;
import mx.effects.Move;
import mx.effects.DefaultTileListEffect;
private var selectedMinPrice:Number = 0;
private var selectedMaxPrice:Number = 5000;
private var selectedType:String = “all”;
private var selectedCondition:String = “all”;
private var selectedVendor:String = “TÜM MARKALAR”;

private function sonucIsleyici(event:ResultEvent):void{
productsCollection = new ArrayCollectionExtended( (event.result.SONUCLAR.urun as ArrayCollection).source);
creationCompleteHandler();
}
private function creationCompleteHandler():void
{
/* setup the filters array: in order to take effect
* you must call refresh() on the collection
*/
productsCollection.filterFunctions =
[
filterByPrice, filterByVendor
]
productsCollection.refresh();
}

// your classic filter functions
private function filterByPrice( item:Object ):Boolean
{
if( selectedMinPrice item.sonkullanici )
return true;
return false;
}

private function filterByType( item:Object ):Boolean
{
if( item.productType == selectedType || selectedType == “all” )
return true;
return false;
}

private function filterByCondition( item:Object ):Boolean
{
if( item.productCondition == selectedCondition || selectedCondition == “all” )
return true;
return false;
}

private function filterByVendor( item:Object ):Boolean
{
if( item.marka == selectedVendor || selectedVendor == “TÜM MARKALAR” )
return true;
return false;
}

// change handlers, nothing new here
private function productPriceChangeHandler():void
{
selectedMinPrice = hsProductPrice.values[0];
selectedMaxPrice = hsProductPrice.values[1];
productsCollection.refresh();
}

private function productVendorChangeHandler():void
{
if( cbProductVendor.selectedItem != null ){
selectedVendor = cbProductVendor.selectedItem.etiket;
productsCollection.refresh();
}
}
[Bindable]
public var markaXml:ArrayCollection;

private function init():void {
resimler.setStyle(“itemsChangeEffect”, DefaultTileListEffect);
}
]]>

Hi Erol,

Thanks for visiting and for using the component.

Before anything I need to see what steps have you attempted in order to solve the problem…where exactly you got stuck. Otherwise just pasting your source code will not help anyone.

My first question is: have you tried debugging your application? And if so, do you have a rough idea where things tend to go the wrong way?

.peace

P.S. sorry for late response but my wordpress is configured to moderate any comments containing large portions of source code or links.

Hi Cristian,

I have try to debug. i have seen some xml nodes and null abjects so on but i didnt understand what goes on :(

the filter is working fine but itemChangeEffect not.

i try out the out of script block and bind it to tile list but no success

i mean i dont know how to read the debuging screen and where to put the break points.
Have nice day / night

!CORRECTION!
i try put mx:defaulttilelisteffect to out of script block and bind it to tile list but no success

I’ll try to take a closer look at your code this weekend. I will focus on that DefaultTileListEffect problem you mentioned.

.peace

Thanx :)

[...] I made my own “workaround” which involved some redundant and crappy coding So the next step was some basic googling. It didn’t take long to find a solution by Cristian Rotundu. It can be found here [...]

[...] and very useful hack to apply filter function directly to data source not in the control, you can stop by here. Okay, once you know that everything in Flash Player is Object and every object has own properties, [...]

Hey, I’m having a problem with this..
When I type the dataProvider (in my case for a TileList) manually, it works fine.
However, I want to make the list dynamically. I have this variable which is datatyped as an ArrayCollection, which is filled with info from an external XML-file. My question is: how can I get the data from the ArrayCollection variable to the ArrayCollectionExtended variable? I have tried some things, but ended up with errors #1120, #1119 and #1118…

Just wanted to let you know that it works like a charm. Thanks again for putting out such a valuable class to the commmunity

[...] to filter data inside the collection). The first and only valid solution I found was that one from Cristian Rotundu, he has extended ArrayCollection class providing a filterFunctions properties which accepts an [...]

Good implementation, anyway I implemented my own solution by using the decorator pattern.
If you are interested you can read about it on by blog: http://www.daveoncode.com/2009/03/30/arraycollection-filterfuntion-with-multiple-filter-functions-using-decorator-pattern/

Thank you ;-)

@Maarten
Try this ‘safe copy’ method from one ArrayCollection to another.
var newCollection:ArrayCollectionExtended =
new ArrayCollectionExtended( ObjectUtil.copy(resultCollection.source) as Array ).
….. configure filters, etc….

@daveoncode
Thanks for sharing! Good work, it’s nice to see alternatives showing up. My intention was to stay in the ‘quick and simple’ realm for this one.

Thank you all for stopping by

.peace

@Cristian
thank you so much! It works :)

I really like this simple idea of extending the ArrayCollection. It gave me the opportunity to dynamically add Filters while they come from the UI with addFilterFunction(p_function:Function):void

Flex and its ArrayCollections and Arrays rock! ;-)

Cheers

Good idea, but I am having some trouble implementing it. The data I recieve remotely is not being copied into the new array with ArrayCollectionExtension properties. I don’t get any error, I just get a blank grid. Please help!!

Here is part of my code:

import mx.utils.ObjectUtil;
import mx.collections.*;

This is great! Any ideas how to implement this to filter a grid as you type in a textbox?

Hey Chris,

I think I already have a DataGrid component with built-in filtering around. I’ll post a link to it very soon.
Thanks for visiting!

peace,
Cristian

I just came across this too: http://code.google.com/p/flex-datafilterlib/ for those interested. Looking forward to see the example. Thanks Cristian!

Nice idea but I’ve got a question. Let’s say that we need the comboboxes on the example to be dynamically populated from the filtered arrayCollection. For example when you move the right thumb to narrow down the price, after a little while you are left with “computers” and “electro” type of items only. It would be appropriate if the values of the corresponding combobox would be narrowed down automatically (at the same time), so that when the user clicked on it she would see only “computers” and “electro”. Is this possible? I hope that my description is clear. Thanks.

Hi Cristian,
Thank you so much for this post. It helped me sort out a very complex searching functionality.
I would never have figured out how to do an “and” search on multiple fields without your excellent solution.

This was a big help, thanks for posting!

Hi cristian,

I have populate data grid with data as arraycollection..can you help me how can i filter on datagrid on multiple criteria..how can i apply your codes on arraycollection?

[...] can be done in a more professional way, creating an ArrayCollectionExtended Class as explained in this tutorial, but afterwards I had some problems passing the data from MySQL into the new [...]

Social comments and analytics for this post…

This post was mentioned on Twitter by nwebb: Two approaches to multi-field filtering of an ArrayCollection in ActionScript 1. http://bit.ly/rgxAi 2. http://bit.ly/123XYF...

Great work. I have a related question. Would it be possible to use two different filter functions on the same ArrayCollection to show seperate filter results in two different datagrids. For example if I wanted to show one datagrid filtered by time and the other by name but both based on the same arraycollection. Thanks in advance.

Hi there
I am too new this and find it very very interesting. When I try to import the project in IDE i get error. So I decided to handcode it all. I have started with new mxml file. How i do creat the class? When i creat the class i don’t get the same putput as yours. Appreciate your help in this.
Thank you
Krish

Grrreat! I wonder how to make this thing to work with external XML instead of ‘Objects’ array. Anyone tried? Thanks in advance!