I'm trying to intercept the value that is taken from a DataGrid's GridColumn's itemRenderer and applied to the itemEditor, and vice-versa. I need to be able to format this value. However, my project is complex, so I may be focusing on the wrong idea in what I'm trying to accomplish. Please have a look and let me know if there's something else I could try.
I have a Spark DataGrid component (with ID dg) that I am dynamically populating from XML. I create an ArrayCollection from some nodes, and a regular Array from sub-nodes that is added as a property of the ArrayCollection. That ArrayCollection is then used as the dataProvider for the DataGrid.
Here is an example segment of a typical XML node and it's sub-nodes:
<item name="physOrderTable" text="" type="notes">
<cols>
<col id="0" text="Day/Time" />
<col id="1" text="Order Type" />
<col id="2" text="Physician's Orders" />
<col id="3" text="Physician's Signature" />
</cols>
<rows>
<row id="r0" name="" text="">
<col id="0"><![CDATA[Tues 15:24]]></col>
<col id="1"><![CDATA[General]]></col>
<col id="2"><![CDATA[BMP, CBC, Cardiac Enzymes, ABG, EKG STAT, NS@ 125 mL/hr, Blood Sugar AC & HS, 02 via NC to keep oxygen saturation above 97%]]></col>
<col id="3"><![CDATA[J. Nelms]]></col>
</row>
</rows>
</item>
Here is the code that reads through the XML and utilizes it:
protected function sparkDG_creationCompleteHandler(event:FlexEvent):void
{
trace("grid created");
var colsList:XMLList = xml.cols.col;
var rowsList:XMLList = xml.rows.row;
colAL = new ArrayList();
for(var i:Number = 0; i < colsList.length(); i++)
{
var gc:GridColumn = new GridColumn();
gc.maxWidth = 500;
gc.resizable = false;
gc.headerText = String(colsList[i].@text);
gc.dataField = "col";
gc.labelFunction = labelFunc;
colAL.addItem(gc);
}
for each(var row:XML in XML(value).rows.children())
{
var rowArr:Array = new Array();
for each(var col:XML in row.children())
{
if(col == "")
{
rowArr[Number(col.@id)] = "_";
}else{
rowArr[Number(col.@id)] = col;
}
}
colAC.addItem({
rowID: row.@id,
rowName: row.@name,
rowText: row.@text,
col: rowArr
});
}
dg.columns = colAL;
dg.dataProvider = colAC;
}//
So I build the header for the DataGrid first, telling it to use the "col" dataField, which corresponds to the .col property of the colAC ArrayCollection. That .col property is the array of values for each cell of that row.
Now this part of code is important, as it displays the relevant index of the .col array by using the .columnIndex:
private function labelFunc(item:Object, column:GridColumn):String
{
var displayText:String;
var valArr:Array = new Array();
if(column.dataField == "col")
{
valArr = item[column.dataField];
displayText = String(valArr[column.columnIndex]);
}
return displayText;
}//
This is the only method I've been able to use to achieve the desired result. This all works fine, if all I want to do is merely display information. But I need to be able to edit the values in each cell, and apply this back to the dataProvider, as I need to rebuild XML with the updated values later.
I have tried everything I can possibly think of to be able to do this. I built my own itemRenderer, then my own itemEditor, then scrapped them because it felt like I was re-inventing the wheel. But was I? I tried reading through the code for the DataGrid, GridColumn, and related classes, but I couldn't find any reference to the itemEditor beyond it being an IFactory. I have no idea where or how it tells that IFactory to be a text input or whatever it is.
Here is my issue:
When I turn on the DataGrid's editing, and double-click a cell, it takes the entire array of the col dataField for that column's cell, converts that array to a string, and displays the entire string in the edit text box. If I cancel the editing, or save the editing, it sets the string to the .col property. Then the labelFunction tries reading that string as an array, and it crashes. I was able to get the typeof the col dataField and converting it to an array if it's a string, but I shouldn't have to.
I need to have it display just the value of the cell for that particular row and column when the instance of the itemEditor is created. When that value is changed, I need it to apply back to that column's index in the .col array of the dataProvider. So, similarly to how it displays information in the labelFunction, I need to edit the information and send it back.
I've seen lots of custom itemEditors and itemRenderers for GridColumns, but these are hard-coded in the MXML. My grid is almost entirely dynamically created, so that's unfortunately not an option for me, as I won't even know how many columns or rows there will be when the DataGrid is created. I tried using rendererIsEditor, but that only seems to be on the MXML instantiation of the GridColumn, as there's only rendererIsEditable in the ActionScript, and it doesn't seem to work (or I don't know how to use it as intended).
If anyone knows of a way to accomplish this, even just something else I should look at, I would greatly appreciate it!