Complex DataGrid filterFunction in Flex/Air

Premarin For Sale Acomplia No Prescription Buy Tulasi No Prescription Buy Online Vantin Buy Female Viagra Online Amaryl For Sale Ashwagandha No Prescription Buy Soma No Prescription Buy Online Cystone Buy High Love Online Femara For Sale Mevacor No Prescription Buy Zyloprim No Prescription Buy Online Crestor Buy Glucophage Online Purinethol For Sale Amitriptyline No Prescription Buy Prednisone No Prescription Buy Online Wellbutrin Buy Yerba Diet Online Lasix For Sale Tramadol No Prescription Buy Effexor No Prescription Buy Online Depakote Buy Cialis Jelly Online

So I need to add robust user controlled filtering options in the application I am working on. This problem has dogged me for a month or two, with my co-workers politely insisting on more and better ways to filter their data. This is completely understandable. When you are staring down a datagrid that is virtually 12 feet long, getting to what you actually want to see is important.

This 2006 article from Bruce Phillips was a big help in the basic concept of multiple input filtering. As is his normal style, it is littered with good references to the source material from his research. This is only considering two filter parameters, however, and I need to consider n parameters, that will probably shift as the needs of the end user grow.

The problem is that each new filtering parameter exponentially increases the complexity of the filterFunction. I can see the pattern, but I haven't quite reached the epiphany that I need to break it down into one of those tight little functions I see real programmers creating (unfortunately, I haven't seen any that address my specific problem).

I thought I'd share my naive, and perhaps confusing filterFunction. It would be great to hear how others approach this problem, and come up with a concise solution.

This function utilizes a TextInput to get text search input from the user. It uses
a series of CheckBoxes for various status condition to generate an array [ 1, 0, 1, 1 ]
to represent their on/off state. It also uses two combo boxes to filter by staff members
as well as clients.

filterFunction:

private function filterCases(item:CaseVO):Boolean
{
	//is the item visible or hidden
	var result:Boolean = false;
	//array of CheckBox.selected property values
       // in handy ones and zeroes. This is returned from a function
       // that takes the actual CheckBoxes as input and gives me this.
	var case_mask:Array = [ 1, 0, 1, 1 ];
        //a couple VOs to verify the selectedItem in the ComboBoxes.
	var client:PersonVO;
	var expert:PersonVO;
	//array iteration variable
	var i:int;
 
	var dateFormat:DateFormatter = new DateFormatter( )
	dateFormat.formatString = 'MM/DD/YY'
 
	//text search
	if ( caseGrid.filter.caseNumInput.text.length > 0 )
	{
		var searchResult:Boolean = ( ( String( '0' + item.case_id.toString() ).search( caseGrid.filter.caseNumInput.text ) >= 0 ) ||
										( item.style.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) >= 0 )  );
		if( item.description )
		{
			searchResult = searchResult || ( item.description.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) >= 0 )
		}
 
		if ( item.client_id )
		{
			searchResult = searchResult || ( personProxy.personFromId( item.client_id ).fullName.toLowerCase().search( caseGrid.filter.caseNumInput.text.toLowerCase() ) >= 0 )
		}
 
		if ( item.date_of_accident )
		{
			searchResult = searchResult || ( dateFormat.format(item.date_of_accident).search( caseGrid.filter.caseNumInput.text ) >= 0 )
		}
 
		for ( i = 0; i < case_mask.length; i++ )
		{
			if ( caseGrid.filter.client.selectedItem is PersonVO )
			{
				client = caseGrid.filter.client.selectedItem
 
				//is an expert selected for filtering also?
				if ( caseGrid.filter.expert.selectedItem is PersonVO && searchResult)
				{
					expert = caseGrid.filter.expert.selectedItem;
					//filter for client, expert, and status
					if ( (case_mask[i] && item.status == String( i + 1 ) )
							&& item.client_id == client.id
							&& item.expert_id == expert.id && searchResult  )
						result = true;
				}
				else
				{
					//filter for client and status
					if ( (case_mask[i] && item.status == String( i + 1 ) )
							&& item.client_id == client.id && searchResult  )
						result = true;
				}
			}
			else if ( caseGrid.filter.expert.selectedItem is PersonVO )
			{
				expert = caseGrid.filter.expert.selectedItem;
				for ( i = 0; i < case_mask.length; i++ )
				{
					//filter for expert and status
					 if ( (case_mask[i] && item.status == String( i + 1 ) )
					 		&& item.expert_id == expert.id && searchResult  )
					 	result = true
				}
 
			}
			else
			{
				//filter for client and status
				if ( (case_mask[i] && item.status == String( i + 1 ) )
						&& searchResult  )
					result = true;
			}
		}
	}
	//see if a client is selected for filtering
	else if ( caseGrid.filter.client.selectedItem is PersonVO )
	{
		client = caseGrid.filter.client.selectedItem
		for ( i = 0; i < case_mask.length; i++ )
		{
			//is an expert selected for filtering also?
			if ( caseGrid.filter.expert.selectedItem is PersonVO )
			{
				expert = caseGrid.filter.expert.selectedItem;
				//filter for client, expert, and status
				if ( (case_mask[i] && item.status == String( i + 1 ) )
						&& item.client_id == client.id
						&& item.expert_id == expert.id  )
					result = true;
			}
			else
			{
				//filter for client and status
				if ( (case_mask[i] && item.status == String( i + 1 ) )
						&& item.client_id == client.id  )
					result = true;
			}
		}
	}
	//client isn't selected, check the expert filter.
	else if ( caseGrid.filter.expert.selectedItem is PersonVO )
	{
		expert = caseGrid.filter.expert.selectedItem;
		for ( i = 0; i < case_mask.length; i++ )
		{
			//filter for expert and status
			 if ( (case_mask[i] && item.status == String( i + 1 ) )
			 		&& item.expert_id == expert.id  )
			 	result = true
		}
 
	}
	//finally, filter for the status
	else
	{
		for ( i = 0; i < case_mask.length; i++ )
		{
			//filter for status
			if ( case_mask[i] && item.status == String( i + 1 ) )
				result = true;
		}
	}
 
	return result
}

You can see that I am repeating myself from the top down to the final else statement, cutting the filter parameters down like a layer cake. It works, and is relatively quick on a grid with 1500 or so items. This just screams "REFACTOR ME" every time I see it.

Related Posts

Django Authentication from Flex, Flex – Preventing DataGrid scrolling when the dataprovider is updated., Actionscript string replacement and international currency., Django Authorization from Flex/AIR via PyAMF, Form Validation for the Lazy Programmer in Flex

2 Responses to “Complex DataGrid filterFunction in Flex/Air”


  1. 1 LogeshKumar

    I didn’t understand the code. what you explain.

    Thanks,
    Logesh

  2. 2 Joel

    I barely understand it myself. There has to be a better way, I just haven’t stumbled across it yet.

Leave a Reply