PDA

View Full Version : How do I properly filter httpservice results..


box86rowh
10-03-2007, 03:54 PM
Hi,
I am trying to use the flex tree in conjunction with the http service and my xml source. When I hook it up normal with the dataProvider of the tree being dataFinder.lastResult where dataFinder is my httpservice it works fine except it is showing more in the tree than I would like. I would like to be able to filter the results so that only some of the nodes show.
My markup is like this:
<groups>
<group id="1" name="foo">
<group id="2" name="foo child">
<contact id="23" name="fred">
</group>
</group>
</groups>
I would like the nodes that are named group to show in the tree but not the contact nodes..If I add a filter - dataFinder.lastResult.(name == "group") it only seems to filter the top level items and if i do a - dataFinder.lastResult..(name == "group") with the double dot, it gives me just the groups, but it loses the structure. Anybody have any ideas?
Jason

box86rowh
10-04-2007, 04:19 PM
still need help with this issue

drkstr
10-06-2007, 12:03 PM
I posted this awhile back, maybe it will help.

http://www.actionscript.org/forums/showpost.php3?p=651702&postcount=6

Best Regards,
...aaron

Jim Freer
10-09-2007, 02:59 PM
We have discussed this before: http://www.actionscript.org/forums/showthread.php3?t=143612.

Drkstr and dr. zeus suggested a data descriptor. I thought it might be a little tricky. Anyway, I’ve finally got around to trying them out. After some trial and error I came up with a fairly simple data descriptor for filtering XML elements for Trees. I have no idea how robust it is at this point but it seems to work for the problem discussed here.

The data descriptor solution has the advantage in that it is non-destructive to the dataProvider’s source.

ItreeDataDescriptor Class:


package
{
import mx.collections.ICollectionView;
import mx.collections.XMLListCollection;
import mx.controls.treeClasses.ITreeDataDescriptor;

public class FilteredTreeDataDescriptor implements ITreeDataDescriptor
{
// ---------------------------------------------------------------------
// 1. Filters a Tree's XML based dataProvider to be displayed.
//
// 2. Read nnly class ( addChildAt, removeChildAt not implemented. )
//
// 3. Constructor argument is an array of strings containing the XML
// element names that are to be included in the tree.
//
// 4. Function isBranch could be modified to change behavior. This
// class treats a node with no filtered children as a node even
// though it has filtered-out children.
// ---------------------------------------------------------------------

// ---------------------------------------------------------------------
// Private Member Variables
// ---------------------------------------------------------------------

private var mvFilterNames :Array;

// ---------------------------------------------------------------------
// Constructor
// ---------------------------------------------------------------------

public function FilteredTreeDataDescriptor
( avFilterNames :Array )
{
mvFilterNames = avFilterNames;

} // Constructor

// ---------------------------------------------------------------------
// addChildAt
// ---------------------------------------------------------------------

public function addChildAt
( avParent :Object,
avNewChild :Object,
avIndex :int,
avModel :Object = null )
:Boolean
{
return false;

} // addChildAt

// ---------------------------------------------------------------------
// getChildren
// ---------------------------------------------------------------------

public function getChildren
( avNode :Object,
avModel :Object = null )
:ICollectionView
{
var lvFilterName:String;
var lvXmlListNew:XMLList = new XMLList();

var lvXmlList:XMLList = avNode as XMLList;
if( lvXmlList )
{
for each( lvFilterName in mvFilterNames )
{
lvXmlListNew += lvXmlList.child( lvFilterName );
} // for each
return new XMLListCollection( lvXmlListNew );
} // if

var lvXml:XML = avNode as XML
for each ( lvFilterName in mvFilterNames )
{
lvXmlListNew += lvXml.child( lvFilterName );
} // for each

return new XMLListCollection( lvXmlListNew );

} // getChildren

// ---------------------------------------------------------------------
// getData
// ---------------------------------------------------------------------

public function getData
( avNode :Object,
avModel :Object = null )
:Object
{
if( mvFilterNames.indexOf( ( avNode as XML ).name() ) == -1 )
return null;

return avNode;

} // getData

// ---------------------------------------------------------------------
// hasChildren
// ---------------------------------------------------------------------

public function hasChildren
( avNode :Object,
avModel :Object = null )
:Boolean
{
var lvFilterName:String;

var lvXmlList:XMLList = avNode as XMLList;
if( lvXmlList )
{
for each( lvFilterName in mvFilterNames )
{
if( lvXmlList.child( lvFilterName ).length() > 0 )
return true;
} // for each

return false;

} // if

var lvXml:XML = avNode as XML;
for each( lvFilterName in mvFilterNames )
{
if( lvXml.child( lvFilterName ).length() > 0 )
return true;
} // for each

return false;

} // hasChildren

// ---------------------------------------------------------------------
// isBranch
// ---------------------------------------------------------------------

public function isBranch
( avNode :Object,
avModel :Object = null )
:Boolean
{
return hasChildren( avNode, avModel );

} // isBranch

// ---------------------------------------------------------------------
// removeChildAt
// ---------------------------------------------------------------------

public function removeChildAt
( avParent :Object,
avChild :Object,
avIndex :int,
avModel :Object = null )
:Boolean
{
return false;

} // removeChildAt

} // class FilteredTreeDataDescriptor

} // package


Example use of ItreeDataDescriptor Class


<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
layout="absolute"
creationComplete="onCreationComplete()"
>
<mx:Tree
id="Tree1"
width="100%"
height="100%"
labelField="@name"
dataDescriptor="{new FilteredTreeDataDescriptor(['group','organization'])}"
/>
<mx:Script>
<![CDATA[
import FilteredTreeDataDescriptor;

private function onCreationComplete
()
:void
{
var lvXml:XML =
<groups>
<group id="1" name="foo">
<team id="1" name="team child">
<contact id="8" name="bill"/>
</team>
<group id="2" name="foo child">
<contact id="23" name="fred"/>
</group>
<organization id="5" name="organization child">
<contact id="45" name="mary"/>
</organization>
</group>
</groups>;

Tree1.dataProvider = lvXml.children();

} // onCreationComplete

]]>
</mx:Script>
</mx:Application>


Jim
http://freerpad.blogspot.com/

Jim Freer
10-09-2007, 04:39 PM
I’ve already found a flaw. The “getChildren” function reorders the children in the order of the filtered elements.

On second thought, I’ve just added a feature: It now organizes the nodes by element name by the order given in the filter array!

Jim
http://freerpad.blogspot.com/

box86rowh
10-09-2007, 07:50 PM
Jim, that worked like a charm! You are the man!
Jason