DataGrid not appropriate dataProvider value - apache-flex

I have an ArrayCollection filled with 'o' objects. This AC should be the dataProvider of a DataGrid. After setting the dp: dgMT.dataProvider=acDataGrid the DataGrid contains only the last item of the arrayCollection.
Code:
[Bindable]
public var acDataGrid:ArrayCollection = new ArrayCollection();
protected function ddlLanguage_changeHandler(event:IndexChangeEvent):void{
gcTranslate.headerText=Globals.acLanguages.getItemAt(ddlLanguage.selectedIndex,0).toString();
Globals.acActValues=convertXmlToArrayCollection(File.applicationDirectory.resolvePath("xmls"+File.separator+Globals.acFileNames.getItemAt(ddlLanguage.selectedIndex,0)));
Globals.acDataGrid.removeAll();
var o:DataGridObject = new DataGridObject();
var i:int=0;
var angol:Object;
for each(angol in Globals.acValues){
o.en=angol.value;
o.name=angol.name;
if(i<Globals.acActValues.length && o.name==Globals.acActValues.getItemAt(i,0).name){
o.translation=Globals.acActValues.getItemAt(i,0).value;
}
else{
o.translation="";
Globals.acActValues.addItemAt("",i);
}
acDataGrid.addItemAt(o,i);
trace("NAME: "+acDataGrid.getItemAt(i,0).name+" VAL:"+acDataGrid.getItemAt(i,0).en+"TRANS: "+acDataGrid.getItemAt(i,0).translation);
// the values are different!
i++;
}
dgMT.dataProvider=acDataGrid;//setting the dataProvider
}
How could I reach that the DataGrid's rows are filled with the correct values?
Thank you!

You're instantiating o just once, outside of the for loop. Which means your just changing the values of that instance's properties and adding that same instance to the dataprovider over and over. You should instead create a new instance on every iteration.
To fix this, simply move the instantiation of o inside the for loop:
for each(angol in Globals.acValues){
var o:DataGridObject = new DataGridObject();
...
}

Related

DataGrid column value not showing with labelFunction

I have a Spark DataGrid that I'm using a labelFunction with. However it's not showing any results.
var c3:GridColumn = new GridColumn("Date Added");
c3.width = 150;
//c3.dataField = "date";
c3.labelFunction = getFormattedDateNoTimeGrid;
public function getFormattedDateNoTimeGrid(item:Object, column:GridColumn):String
{
var rawDate:String = item.date;
trace("Date:" + rawDate);
return rawDate;
}
With the previous code it shows nothing but the label function is called and all the dates correctly trace out. If I remove the dateField line the column is not empty but it's not the value returned by the label function. Basically the label function is not showing the value it is supposed to.
What a pain. Flash Builder "helped" me create a item renderer for my grid column that had this function in it:
override public function prepare(hasBeenRecycled:Boolean):void {
lblData.text = data[column.dataField];
}
That function overrides the functionality of the dataField and labelFunction. I removed it and all is well. Thanks everyone for all your help.

Ensure Spark DataGrid item is visible

Is there a way to make sure the selected item is visible in the Spark DataGrid?
.
Context
I have a data grid bound to an array collection. I receive remotely a service that gives me a ID (string) of an object that is in the collection. Using just the string I loop through the collection to find the item that matches the string. I find the object by it's ID. Now I have the object I want to select in the datagrid. I can set the
dataGrid.selectedItem = object;
Now I need to make sure it's visible. I do not have the row or column index.
.
Update
Using the answer below I've complimented it with this function:
/**
* Ensures the item is visible (for spark data grid)
**/
public function ensureItemIsVisibleInSparkDataGrid(datagrid:spark.components.DataGrid, item:Object):void {
var list:IList = datagrid.dataProvider;
var length:int = list.length;
var itemFound:Boolean;
var object:Object;
var index:int;
for (var i:int;i<length;i++) {
object = list.getItemAt(i);
if (object==item) {
itemFound = true;
index = i;
break;
}
}
if (itemFound) {
datagrid.ensureCellIsVisible(index);
}
}
Yes, it's called ensureCellIsVisible(). You need to know that row and column of the item in question. To get this to work you'd need to listen for the selectionChange event then calculate the row and column of the currently selected item.

Object to arraycollection then to datagrid

Say, linedataColl is an AC that contains 200+ of rows extract from CSV and in my design, I wish to additem into SuperDataCollection object by object but the only problem was I'm unable to see any data display in "S" which is a datagrid. What wrong with my code?
var superDataCollection:ArrayCollection = new ArrayCollection();
var dc:ArrayCollection = new ArrayCollection();
var di:Object = new Object();
for(var aa:int=0; aa<5;aa++){
di.username = linedataColl[aa].username;
di.email = linedataColl[aa].email;
dc.addItem(di);
superDataCollection.addItem(dc);
s.dataProvider = dc;
}
Don't set the dataProvider within the for loop. You only need to set it once, and the datagrid will detect changes to the ArrayCollection you specify as a dataProvider.
The best thing to do is set it after you completely build up the ArrayCollection 'dc'.
Perhaps your problem will be fixed by this...
}
s.dataProvider = dc;

Assign Xml Values to dynamically created components

xml values are stored in 'arr' array collection. depending on the length of the array stored, the below described components are created and assign those values to relevant components dynamically.
For Example:
AdvanceSearch.mxml is one component, and another components as advanceSearchAtom.mxml. within 'advanceSearchAtom' has some sub components as textbox, combo box etc,. we can add many advanceSearchAtom.mxml inside 'AdvanceSearch.mxml'.
var container : AdvanceSearch;
var adv : advanceSearchAtom;
for(var i:int=0;i<arr.length;i++) {
adv = new advanceSearchAtom();
adv.field.text = arr[i].field;
adv.value.selectedIndex = arr[i].value;
container.addChild(adv);
}
Please let me know if anybody come across this type of problem. if any relevant link is appreciable. Thanks in advance
You didn't mention it, but I guess the problem is that you're getting null reference error (1009) on the following lines:
adv.field.text = arr[i].field;
adv.value.selectedIndex = arr[i].value;
Am I right?
This is because field and value are not yet created. As per the default component instantiation, Flex creates the children only when it is required - i.e., when it is to be displayed.
You can either listen to the creationComplete event of the AdvanceSearchAtom component and update the values from there; or have Binadble public variables in the AdvanceSearchAtom class, bind them to field.text and value.selectedIndex and assign xml values to those variables in the loop.
Using creation complete:
public var container:AdvanceSearch;
public var searchItems:Array = [];
public var arr:Array;
//assuming that arr has been initialized with xml values.
var adv:AdvanceSearchAtom;
for(var i:int=0;i<arr.length;i++) {
adv = new AdvanceSearchAtom();
adv.addEventListener(FlexEvent.CREATION_COMPLETE, onAtomCreated);
container.addChild(adv);
searchItems.push(adv);
}
public function onAtomCreated(e:Event):void
{
var adv:AdvanceSearchAtom = e.currentTarget as AdvanceSearchAtom;
if(!adv)
return;
var index:Number = searchItems.indexOf(adv);
adv.field.text = arr[index].field;
adv.value.selectedIndex = arr[index].value;
}
Using data binding:
Inside AdvanceSearchAtom.mxml
<mx:TextInput id="field" text="{textValue}"/>
<mx:ComboBox id="value" selectedIndex="{comboIndex}"/>
In the script block of AdvanceSearchAtom.mxml
[Bindable]
public var textValue:String;
[Bindable]
public var comboIndex:Number;
var adv:AdvanceSearchAtom;
In the AdvanceSearch class:
for(var i:int=0;i<arr.length;i++) {
adv = new AdvanceSearchAtom();
container.addChild(adv);
adv.field.text = arr[i].field;
adv.value.selectedIndex = arr[i].value;
}

Unwanted binding

The situation is simple. I have a datagrid that gets its data from a webservice.
When data from the webservice is retrived it calls the following function:
private function onListReg():void
{
arrRegOld = WSAutoreg.list.lastResult as ArrayCollection;
arrReg = WSAutoreg.list.lastResult as ArrayCollection;
dgReg.dataProvider = autoreglist;
}
dgReg is the Datagrid. the arr variables are ArrayCollections defined like so:
private var arrRegOld:ArrayCollection = new ArrayCollection;
[Bindable]
private var arrReg:ArrayCollection = new ArrayCollection;
The intent is when I hit a update button, it compares arrRegOld with arrReg and see if any values have changes. The problem is whenever I change values on the Datagrid it changes on both the dataProvider and on both ArrayCollections.
Does anyone know why is this happening? What should I do so that the binding applies only to one ArrayCollection?
Appreciate any tip.
- Mike
Your lists are sharing the same objects, if you modify the first element from arrReg you will see the modification also in arrRegOld - it is not related to binding. You need to clone the objects. You have several choices:
a) Implement a clone method for your objects (recommended)
b) Use a generic method like this one:
private function clone(source:Object):*
{
var array:ByteArray=new ByteArray();
array.writeObject(source);
array.position=0;
return(array.readObject());
}
and call arrRegOld = clone (arrReg); after arrReg = WSAutoreg.list.lastResult as ArrayCollection;

Resources