Copy link to clipboard
Copied
I have a datagrid in a Flex project, the data grid has an XML file as the source (contents below), now due to the way it is formatted (I cannot change this) some of the data I want to display is inside a tag that isnt at the initial array level. Here is the file:
<?xml version="1.0" encoding="utf-8" ?>
<Categories>
<Category>
<CategoryName>Cat 1</CategoryName>
<CategoryLink>http://www.google.com</CategoryLink>
<CategoryData>
<CategoryDescription>This is the description of category 1</CategoryDescription>
<CategoryHeader>My Category Title 1</CategoryHeader>
<CategoryNumber>1</CategoryNumber>
</CategoryData>
</Category>
</Categories>
I need to display CategoryName, CategoryLink, CategoryData.CategoryDescription, CategoryData.CategoryNumber.
Now I blindly dropped the datagrid into the project and bound it to the data source, I get the following returned for CategoryData:
[object CategoryData_type]
Not much use, but with what appears to be a hack I changed the code for the column to read dataField="CategoryData.CategoryDescription", and hooray it works. I didnt realise at the time that this was wrong, and when I dropped in an itemEditor things went wrong. When the datagrids load they display the correct data, but then when you try to edit any of the child property fields you get the following error:
ReferenceError: Error #1069: Property CategoryData.CategoryDescription not found on valueObjects.Category_type and there is no default value.
I have looked up the error and I realise that it means that there is no value for CategoryData.CategoryDescription, but if I can display it why can i not edit it! What do I have to do to make this work?
Anyway, here is the code, it shows the default bound datagrid, a second datagrid with the hack applied, and a third hacked datagrid with an itemRenderer and itemEditor on the number columns
Can you please take a look and tell me what I did wrong, well more to the point, if there is a doc that explains how to deal with XML like this then please point me at it.
I did try changing the return type for ANY of the columns, but this fails, I also tried a labelFunction, but again I can get the [object CategoryData_type] to display, but I get the null reference exception as the datagrid loads if I try to get to the child props.
Here is the Flex code:
<?xml version="1.0" encoding="utf-8"?>
<s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
xmlns:s="library://ns.adobe.com/flex/spark"
xmlns:mx="library://ns.adobe.com/flex/mx"
xmlns:categories="services.categories.*"
minWidth="955" minHeight="600">
<fx:Script>
<![CDATA[
import mx.controls.Alert;
import mx.events.FlexEvent;
protected function dataGrid_creationCompleteHandler(event:FlexEvent):void
{
getDataResult.token = categories.getData();
}
protected function lftest(item:Object, column:GridColumn):String
{
var t:String = item.CategoryData;
return t;
}]]>
</fx:Script>
<fx:Declarations>
<s:CallResponder id="getDataResult"/>
<categories:Categories id="categories"
fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
showBusyCursor="true"/>
<!-- Place non-visual elements (e.g., services, value objects) here -->
</fx:Declarations>
<s:DataGrid id="dataGrid" x="10" y="10" width="684"
creationComplete="dataGrid_creationCompleteHandler(event)" editable="true"
requestedRowCount="4">
<s:columns>
<s:ArrayList>
<s:GridColumn width="100" dataField="CategoryName" headerText="CategoryName"></s:GridColumn>
<s:GridColumn width="100" dataField="CategoryLink" headerText="CategoryLink"></s:GridColumn>
<s:GridColumn width="180" dataField="CategoryData" headerText="CategoryData"></s:GridColumn>
</s:ArrayList>
</s:columns>
<s:typicalItem>
<fx:Object CategoryData="CategoryData1" CategoryLink="CategoryLink1"
CategoryName="CategoryName1"></fx:Object>
</s:typicalItem>
<s:AsyncListView list="{getDataResult.lastResult}"/>
</s:DataGrid>
<s:DataGrid id="dataGrid2" x="10" y="147" width="684" editable="true" requestedRowCount="4">
<s:columns>
<s:ArrayList>
<s:GridColumn width="100" dataField="CategoryName" headerText="CategoryName"></s:GridColumn>
<s:GridColumn width="100" dataField="CategoryLink" headerText="CategoryLink"></s:GridColumn>
<s:GridColumn width="180" dataField="CategoryData" headerText="CategoryData"></s:GridColumn>
<s:GridColumn dataField="CategoryData.CategoryDescription" headerText="Desc"></s:GridColumn>
<s:GridColumn dataField="CategoryData.CategoryHeader" headerText="Head"></s:GridColumn>
<s:GridColumn dataField="CategoryData.CategoryNumber" headerText="Num"></s:GridColumn>
</s:ArrayList>
</s:columns>
<s:typicalItem>
<fx:Object CategoryData="CategoryData1" CategoryLink="CategoryLink1"
CategoryName="CategoryName1"></fx:Object>
</s:typicalItem>
<s:AsyncListView list="{getDataResult.lastResult}"/>
</s:DataGrid>
<s:DataGrid id="dataGrid3" x="10" y="284" width="684" editable="true" requestedRowCount="4">
<s:columns>
<s:ArrayList>
<s:GridColumn width="100" dataField="CategoryName" headerText="CategoryName"></s:GridColumn>
<s:GridColumn width="100" dataField="CategoryLink" headerText="CategoryLink"></s:GridColumn>
<s:GridColumn width="180" dataField="CategoryData" headerText="CategoryData"></s:GridColumn>
<s:GridColumn headerText="Number">
<s:itemRenderer>
<fx:Component>
<s:GridItemRenderer>
<s:NumericStepper value="{data.CategoryData.CategoryNumber}" />
</s:GridItemRenderer>
</fx:Component>
</s:itemRenderer>
</s:GridColumn>
<s:GridColumn dataField="CategoryData.CategoryNumber" headerText="Number">
<s:itemEditor>
<fx:Component>
<s:GridItemEditor>
<s:NumericStepper value="{data.CategoryData.CategoryNumber}" />
</s:GridItemEditor>
</fx:Component>
</s:itemEditor>
</s:GridColumn>
</s:ArrayList>
</s:columns>
<s:typicalItem>
<fx:Object CategoryData="CategoryData1" CategoryLink="CategoryLink1"
CategoryName="CategoryName1"></fx:Object>
</s:typicalItem>
<s:AsyncListView list="{getDataResult.lastResult}"/>
</s:DataGrid>
</s:Application>
All and any advice welcome.
Shaine
Another suggestion that I'm going to try from a Hillel Coren blog post
http://hillelcoren.com/2008/09/21/flex-tip-convert-xml-to-arraycollection/
...
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
verticalAlign="middle" horizontalAlign="center"
initialize="init()">
<mx:Script>
<![CDATA[
import mx.utils.ArrayUtil;
import mx.rpc.xml.SimpleXMLDecoder;
import mx.collections.ArrayCollection;
[Bin
Copy link to clipboard
Copied
Ok, instead of fixing an existing problem, I will ask a simpler question.
How would I get this XML data (loaded from a local file) into a datagrid so that it can display all of the fields, and each field would be editable?
<?xml version="1.0" encoding="utf-8" ?>
<Categories>
<Category>
<CategoryName>Cat 1</CategoryName>
<CategoryLink>http://www.google.com</CategoryLink>
<CategoryData>
<CategoryDescription>This is the description of category 1</CategoryDescription>
<CategoryHeader>My Category Title 1</CategoryHeader>
<CategoryNumber>1</CategoryNumber>
</CategoryData>
</Category>
</Categories>
Thank you for any help you can offer, pointers etc, you can call me an idiot and tell me how easy it is, but I am just not seeing a solution right now
I know that category is an Array, I would ideally like Flash Builder to see the file as flat so it can display everything on a single row, or I would like to see category data as an object so that I can set a labelFunction on the column and return CategoryData.CategoryDescription as the value.
If this isnt ppossible at all that would be an acceptable answer, anything to stop the madness of knowing what I want and not being able to get to it! Thank you all!
Shaine
Copy link to clipboard
Copied
I refuse to believe that this is not possible 😕
There must be a way of accessing the values in CategoryData.CategoryDescription etc, what confuses me is that I can see the values in the debugger, but I have no idea of the syntax to load them into variables
Anyway, as it's now Monday, if you get a chance to have a look and come up with anything, I will be looking out for you
Thanks
Shaine
Copy link to clipboard
Copied
One last try, I now know for sure that the data in the file is loading, I created a labelFunction on the CategoryDescription column that looks like this:
protected function dispData(item:Object, column:GridColumn):String
{
var t:Object = item.CategoryData;
var s:String = item.CategoryData.CategoryDescription;
return s;
}
Because it returns s, which I now know is undefined (which is the problem!) I managed to get a debug output. As you can see the value of t is the categorydata, and it appears to have the 3 values I need to get access to, but I have no idea how to do this. I also changed the function to read:
protected function dispData(item:Object, column:GridColumn):String
{
var t:Object = item.CategoryData;
var s:String = t.CategoryDescription;
return s;
}
But this undefines t and s! Very confused
this test2 (@d2e10a1)
item valueObjects.Category_type (@91f8a51)
[inherited]
column spark.components.gridClasses.GridColumn (@d61b239)
t valueObjects.CategoryData_type (@91f8c11)
[inherited]
_cacheInitialized_isValid false
CategoryDescription "This is the description of category 1"
CategoryHeader "My Category Title 1"
CategoryNumber "1"
_changedObjects mx.collections.ArrayCollection (@d5d9e41)
_changeWatcherArray [] (@cfab061)
_dminternal_model _CategoryData_typeEntityMetadata (@d4286a1)
_doValidationCacheOfCategoryDescription null
_doValidationCacheOfCategoryHeader null
_doValidationCacheOfCategoryNumber null
_doValidationLastValOfCategoryDescription null
_doValidationLastValOfCategoryHeader null
_doValidationLastValOfCategoryNumber null
_internal_CategoryDescription "This is the description of category 1"
_internal_CategoryHeader "My Category Title 1"
_internal_CategoryNumber "1"
_invalidConstraints [] (@ca50fd9)
invalidConstraints_der <setter>
_isValid false
isValid_der <setter>
managingService <setter>
_managingService null
_model _CategoryData_typeEntityMetadata (@d4286a1)
_validationFailureMessages [] (@cfab0b1)
s undefined
As always all help welcome.
Shaine
Message was edited after a oops moment by: ProcessEndNow
Copy link to clipboard
Copied
Don't know if you found an answer already?
Thought I'd pass on my solution that I use - I have an XML file in same format as yours
that I use to populate a dropdown list from a dataprovider that is an Array Collection filled by the XML fields.
To do that I use HTTPService on the local XML file.
If you need sample code let me know
Copy link to clipboard
Copied
Another suggestion that I'm going to try from a Hillel Coren blog post
http://hillelcoren.com/2008/09/21/flex-tip-convert-xml-to-arraycollection/
<?xml version="1.0" encoding="utf-8"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml"
verticalAlign="middle" horizontalAlign="center"
initialize="init()">
<mx:Script>
<![CDATA[
import mx.utils.ArrayUtil;
import mx.rpc.xml.SimpleXMLDecoder;
import mx.collections.ArrayCollection;
[Bindable]
private var _data:ArrayCollection;
private function init():void
{
var file = "<rows><row><col>Hello</col></row></rows>";
_data = convertXmlToArrayCollection( file );
}
private function convertXmlToArrayCollection( file:String ):ArrayCollection
{
var xml:XMLDocument = new XMLDocument( file );
var decoder:SimpleXMLDecoder = new SimpleXMLDecoder();
var data:Object = decoder.decodeXML( xml );
var array:Array = ArrayUtil.toArray(data.rows.row);
return new ArrayCollection( array );
}
]]>
</mx:Script>
<mx:DataGrid dataProvider="{ _data }"/>
</mx:Application>
Copy link to clipboard
Copied
I dont know how I missed this, and I am sorry, but thank you! I will pick this up again now and see what I can do, it is possible you just saved my life !
Thanks
Shaine
Copy link to clipboard
Copied
Okay - let me know if you need sample code for the HTTPService example
or if the other example works for you
Copy link to clipboard
Copied
The HTTP example might work better, but I have another more pressing webservice issue right now, and I'm not sure if it's Flash Builder or my .NET web service that is to blame! Feel free to take a look and fix that one instead if you like !! haha
Thank you though, appreciate your very valuable input.
Shaine