Flex : How to hide a row in AdvancedDataGrid? - apache-flex

I have an AdvancedDataGrid with a ArrayCollection as its dataProvider. For instance i have a CheckBox that allows me to show or hide certain rows in the AdvancedDataGrid.
Any idea how i could do that?

My suggestion would be to use your data provider's filterFunction property. Basically, you can give your data provider a function that will determine whether a given item in the ArrayCollection is excluded or not (if an item is excluded, it won't be displayed in the AdvancedDataGrid, in essence making it "invisible"). The docs for filterFunction can be found here.
What I'd suggest then is that checking the checkbox sets a property on the object in your data provider, which is then used by your filter function to include/exclude rows. Some (very rough) pseudocode follows:
private function checkboxClickHandler( event:MouseEvent ):void
{
/*
Based on the MouseEvent, determine the row
in the data grid you're dealing with
*/
myDataProvider[someIndex].checkboxFlag = myCheckBox.selected;
myDataProvider.refresh(); // calling refresh() re-applies the filter to
// account for changes.
}
private function myDataProviderFilterFunction( item:Object ):Boolean
{
// assuming we want the item to be filtered if checkboxFlag is true
return !item["checkboxFlag"];
}

Related

Flex: Filter HierarchicalData child rows

I have an ArrayCollection of objects used as the source for a HierarchicalData object. My object looks roughly like this:
ObjectName (String)
SubCollection (ArrayCollection)
I am using the HierarchicalData in an AdvancedDataGrid to display the data in a grouped format.
I am able to filter the data in the ArrayCollection using a filterFunction. What I want to do now is also filter the records in the SubCollection as well so that only the items that match the filter are displayed in the AdvancedDataGrid.
Can anyone tell me how I can filter the child rows in a HierarchicalData?
This answer isn't a direct answer to your question, but it should help with some of the background. Essentially I am in the same position as you, where I need to show a specific data set depending on what type of parent node I have.
In this case, starting with an override to HierarchicalData.getChildren(node:Object):Object this will give you access to filter the first level children, and will also give you the ability to call a filtered method for sub-children to any n-th level.
You then use your extended class as the source to the ADG.
A pseudo-code example:
Class MyCollection extends HierarchicalData
override public function getChildren(node:Object):Object
{
if (node is a TopLevelObject)
(node.children as ArrayCollection).filterFunction = filterSub;
node.children.refresh();
else if (node is a SubCollectionObject)
(node.children as ArrayCollection).filterFunction = filterGrandChildren;
node.children.refresh();
// - OR -
//a more complex process of allowing the sub-node to determine it's filter
return node.filterSubCollectionGrandChildren();
return node;
}

Flex List limit number of elements

Is it possible to define a property to limit the number of elements which will appear in a mx:List ? I've read about setting the property rowCount, but I don't see any effect.
Can a filter be applied to accomplish this? My intention was to avoid removing the items from the list/array collection, but simply "hide" them. Can this be done?
You can "hide" items from display in a List-based class, without modifying your underlying source data, by using a Collection class, such as an ArrayCollection, and filtering the data.
Read these docs on Collection filtering.
To quote:
You use a filter function to limit the data view in the collection to
a subset of the source data object. The function must take a single
Object parameter, which corresponds to a collection item, and must
return a Boolean value specifying whether to include the item in the
view. As with sorting, when you specify or change the filter function,
you must call the refresh() method on the collection to show the
filtered results. To limit a collection view of an array of strings to
contain only strings starting with M, for example, use the following
filter function:
public function stateFilterFunc(item:Object):Boolean
{
return item >= "M" && item < "N";
}
A different option is to use a new arraycollection and get your limited items from your big arraycollection :
//get first 10 elements
myArrayCollection = new ArrayCollection( myBigArrayCollection.toArray().slice(0,9) );
if you want to work with pagers, you could hold a counter where you keep track of what page the user is on, and get the next elements from you big array collection. example:
//this is just a (very) simple example
//page = integer (counter) for knowing which page the user is on
page = 0;
page_low = page*10;
page_high = page_low + 9;
myArrayCollection = new ArrayCollection( myBigArrayCollection.toArray().slice(page_low,page_high) );
(still using a filter is a more elegant solution)

Adobe Flex arraycollection

I want to use single collection object to two different UI components. 1. Datagrid and 2nd is chart component. I dont want to change anything inside the arraycollection object but I want to use it at the same time with two different component with minor changes. I know we can use filter function some how but not sure how to apply filter to arraycollection object so that one component (datagrid) can use the original arraycollection object and second component (chart) used the modified one.
Thanks,
If you use the same ArrayCollection as the dataProvider for two different components, then any filter or sort applied to that ArrayCollection will show up in both components.
What you want to do cannot be done.
However, you can create multiple ArrayCollections based on the same source and apply filters to them differently. Conceptually something like this:
public var arrayCollection1 : ArrayCollection = new ArrayCollection();
public var arrayCollection2 : ArrayCollection = new ArrayCollection();
protected function onIGotTheArray(value:Array):void{
arrayCollection1.source = value;
arrayCollection2.source = value;
dataGrid.dataProvider = arrayCollection1;
chart.dataProvider = arrayCollection2;
}
Now you can apply a filter to the first arrayCollection without affecting the second arrayCollection, or vice versa.
This is the preferred approach in my experience.

Alternative to data binding

As an alternative to binding an array collection to a data grid's data provider, could I assign the array collection as the data provider to the data grid on it's creation and everytime the array collection is updated execute invalidateProperties(); invalidateList(); to re-render the data grid?
Does my described approach make sense?
Does my described approach make sense?
Sort of. If you have an arrayCollection ( ac) defined using a get/set method, there is no reason you can't set the dataPRovider on your DataGrid in the set method, every time the data is changed.
If you do that, then you most likely will not have to update the properties or displayList of the DatGrid, because the mere fact of replacing the dataProvider will do it for you.
Something like this:
private var _ac : ArrayCollection;
public function get ac():ArrayCollection){
return this._ac;
}
public function set ac(value:ArrayCollection){
this._ac = value;
this.dataGrid.dataProvider = this.ac;
}
Bingo, every time that the ac value is updated, so will the dataProvider on the DataGrid.

When is the right point (from the life cycle view) to set data provier for LIST container on Flex 3

I'm making a LIST container with my own item renderer to display xml file.
Now, I'm overriding the public override function set data(value:Object):void method in my item renderer, the problem is that this function been called many times(!!) (more then the data provider length).
Maybe I'm not setting the data provider right, here is how I do it:
First declare bindable property:
[Bindable]
private var _listDataProvider:XMLListCollection;
Then, creating LIST object:
<mx:List id="list" dataProvider="{_listDataProvider}" itemRenderer="myItemRenderer" />
Then, loading the xml (with urlLoader) and in the result doing:
_listDataProvider = new XMLListCollection(xml..Person);
The XMLListCollection build-up ok (I can see it in debug).
What am I doing wrong?????
Thanks guys...
It looks right to me, I have a feeling the Flex 3 List and related dataProvider components will set the data a few times for each item renderer the first round (inefficiencies in the framework). The first time, they might set it to null (is that happening?), then the next time they might set it to the value.
To get around this, just do something like:
public function set data(value:Object):void
{
if (super.data == value)
return;
super.data = value;
}
That should do the trick.

Resources