Flex 3 Using an ArrayCollection to Populate Both a Datagrid and a ComboBox - apache-flex

I use this arrayCollection to populate a Flex 3 Datagrid. I'd also like to use this arrayCollection to populate a comboBox with the Name node.
In the arrayCollection, I've got the Name listed twice. I've got two rows in the Datagrid.
If I set the ComboBox's labelfield to Name, then the Name will be listed twice in the ComboBox menu. Is there a way to use this arrayCollection and have each Name listed only once in the comboBox?
I can always make another loop and array collection for the Name, but I was wondering if there were a better way.
var i:uint;
for (i=0; i<myArray.length; i++){
myDGArray = [
{Name: myArray[i].Name, Subject: 'Math:', Pass: myArray[i].math_pass, Fail: myArray[i].math_fail},
{Name: myArray[i].Name, Subject: 'Reading:', Pass: myArray[i].reading_pass, Fail: myArray[i].reading_fail}
]
}
myAC=new ArrayCollection(myDGArray);
Thank you.
-Laxmidi

I'm a bit confused. Based on your code sample, the name will be listed twice in the ComboBox because the same name is used twice in your dataProvider.
You may want o consider converting your dataProvider to two separate ListCollectionView objects, provide different filtering on each object and use those each as se[separate dataProviders.
In psuedo code this is how I'd do it:
public var comboBoxCollection : ListCollectionView = new ListCollectionView(myAC );
public var dataGridCollection : ListCollectionView = new ListCollectionView(myAC );
The apply filtering on the comboBoxCollection to filter out entries with duplicate names. More info on collection filtering in the docs.

Related

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.

Flex : How to hide a row in AdvancedDataGrid?

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"];
}

flex 3 and using name/value pairs

Does anyone have any recommendations for working with name/value pairs in Flex?
Context:
I want to create a Flex UI for updating a database table. I want the UI to contain the field name(read only) and current field value (which will be editable). Im using the WebService component to retrieve the field value and then asssigning it to an object with the field name hardcoded e.g.
private function resultHandler(event:ResultEvent):Object
{
var resultsObj:Object;
resultsObj = {
name:event.result.name as String,
This approach however is adding the dependency that the table structure/field names will never change. Using the object type also requries that i write my own algorithm to sort the output.
I'm not sure I understand the issue.
If you want to avoid dependency of the properties returned from the event at this point, simply use the event.result object, which is already an associative array.
As for sorting, we would need more context on what you are attempting to sort.
That's pretty simple. Don't use for each in loop. Use For-In Loop
Demo is shown below.
var dicEntry:Object = new Object();
dicEntry["Name"] = "Raj";
dicEntry["sal"] = 10000;
dicEntry["age"] = 33;
for(var key:Object in dicEntry)
{
trace("Object Key: "+key+" Object Value: +dicEntry[key]);
}
That's it.

flex multiple array collections with a single datasource

How can I populate multiple datagrids in flex with a single datasource that is filtered differently for each datagrid. I'm assigning the event.result from my remote object call to three different array collections, each with its own filter function. When I assign and refresh the filter functions, they each affect all array collections. So, the results of the last array collection refresh end up in all three datagrids.
You probably need to use ObjectUtil.copy on your event result to have 3 separate ArrayCollections, one for each DataGrid... otherwise they all point at the same memory location of the single ArrayCollection and any changes made to it will be reflected in all DataGrids.
var AC1:ArrayCollection = event.result as ArrayCollection;
var AC2:ArrayCollection = ObjectUtil.copy(AC1) as ArrayCollection;
var AC3:ArrayCollection = ObjectUtil.copy(AC1) as ArrayCollection;
I would make copies of your data provider, ie:
var myDataArray:Array; // this contains your original data.
dataGrid1.dataProvider = new ArrayCollection(myDataArray.concat());
dataGrid2.dataProvider = new ArrayCollection(myDataArray.concat());
dataGrid3.dataProvider = new ArrayCollection(myDataArray.concat());
The solutions that have been provided may not behave as you might wish they would. An ArrayCollection technically consists of a model and a "view" into the model. In my understanding, both the solutions that have been provided create a copy of the model. This means if you add an item to one ArrayCollection it won't show up in another regardless of whether it would match that ArrayCollection's filter. Usually you want it to be a part of the model of the other ArrayCollections as well but only be visible if the added item passes the respective ArrayCollection's filter. You can share the "model" amongst ArrayCollections while having separate views into the model like so:
var collection1:ArrayCollection = new ArrayCollection();
var collection2:ArrayCollection = new ArrayCollection();
collection2.list = collection1.list;
var collection3:ArrayCollection = new ArrayCollection();
collection3.list = collection1.list;
Now you can add an item to any of the three collections and it will show up in the others. However, you can have separate filters and sorts on each individual ArrayCollection and that won't affect what's viewable in the others. You can read more about this here:
http://aaronhardy.com/flex/collections-and-chaining-for-separate-presentation/

Resources