View Full Version : XML in Datagrid
ackerchez
03-23-2009, 10:20 AM
I'm having a problem with my datagrid that I am hoping someone can help with. I have done this before and I'm sure that the solution is pretty simple but I cant get it to work.
I am using php to build xml code which gets sent back to flex fine. The structure of the xml is as follows:
<root>
<section label="Biology" id="1">
<student>
<firstname>s1</firstname>
<lastname>s1</lastname>
</student>
</section>
<section label="Chemistry" id="2">
<student>
<firstname>s2</firstname>
<lastname>s2</lastname>
</student>
<student>
<firstname>John</firstname>
<lastname>Smith</lastname>
</student>
</section>
</root>
I am trying to put this xml (which I converted to an xmllist upon receiving it from php) into a data grid and display certain fields.
<mx:DataGrid x="253" y="345" dataProvider="{roster}">
<mx:columns>
<mx:DataGridColumn headerText="Section" dataField="@label"/>
<mx:DataGridColumn headerText="First Name" dataField="firstname"/>
<mx:DataGridColumn headerText="Last Name" dataField="lastname"/>
</mx:columns>
</mx:DataGrid>
In this scenario I am able to display the label in one of the columns but the other two are coming up blank. I have also tried to do "student.firstname" and "student.lastname" but that also is coming up blank.
Can someone please help me here with referencing the child nodes?
Thanks!
ackerchez
03-23-2009, 10:21 AM
The xml is not formatted with tags or anything because the forum gave me issues posting with them.
wvxvw
03-23-2009, 10:26 AM
Wrap your code with or or or tags, whichever is appropriate.
for more info on the BBcodes used in the forum click in the "Posting Rules" (bottom-left of this page). Or simply follow this link: http://www.actionscript.org/forums/misc.php3?do=bbcode
ackerchez
03-23-2009, 10:55 AM
Thanks, I made the change. Any recommendations on the solution to my problem?
wvxvw
03-23-2009, 11:28 AM
The number of items in "section" and the number of students per student is different... so, how did you want to display it? (i.e. DataGrid allows you only for flat display, meaning that you have only 1 array / list / collection that consists of patterned items items, but your data structure isn't like that, you have a 2 dimensional array - so, you either need to use AdvancedDataGrid / OLAPDataGrid controls for what you want, or use custom item renderers that will adjust themselves to the sort of data you're feeding them.
I'll try to make an example with custom item renderers.
wvxvw
03-23-2009, 12:11 PM
<?xml version="1.0"?>
<mx:Application
xmlns:mx="http://www.adobe.com/2006/mxml">
<mx:DataGrid x="253" y="345" variableRowHeight="true">
<mx:dataProvider>
<mx:XMLList>
<section label="Biology" id="1">
<student>
<firstname>s1</firstname>
<lastname>s1</lastname>
</student>
</section>
<section label="Chemistry" id="2">
<student>
<firstname>s2</firstname>
<lastname>s2</lastname>
</student>
<student>
<firstname>John</firstname>
<lastname>Smith</lastname>
</student>
<student>
<firstname>John</firstname>
<lastname>Smith</lastname>
</student>
</section>
</mx:XMLList>
</mx:dataProvider>
<mx:columns>
<mx:DataGridColumn
headerText="Section"
dataField="@label"/>
<mx:DataGridColumn
headerText="First Name"
dataField="@label">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Script>
<![CDATA[
public override function set data(value:Object):void
{
var names:Array = [];
XML(value).student.firstname.text().(names.push(to XMLString()));
firstName = names.join("\r");
}
]]>
</mx:Script>
<mx:String id="firstName"/>
<mx:Text id="firstNameText" text="{firstName}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn
headerText="Last Name"
dataField="@label">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Script>
<![CDATA[
public override function set data(value:Object):void
{
var names:Array = [];
XML(value).student.lastname.text().(names.push(toX MLString()));
lastName = names.join("\r");
}
]]>
</mx:Script>
<mx:String id="lastName"/>
<mx:Text id="lastNameText" text="{lastName}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
</mx:Application>
ackerchez
03-23-2009, 01:38 PM
Hey, I tried working with the code that you provided there and I am getting an error. "Access of undefined property firstName"
Just to see that I get this straight, it is the fact that there can be multiple sections and multiple students within those sections that is messing up the use of the regular datagrid control?
Can you explain how the XML data can be used in the AdvancedDataGrid control? I tried that and it didn't workout right there either.
wvxvw
03-23-2009, 02:18 PM
Just don't modify it before you compile... you probably removed
<mx:String id="firstName"/>
or tried to access firstName outside the item renderer it belongs to.
>> Just to see that I get this straight, it is the fact that there can be multiple sections and multiple students within those sections that is messing up the use of the regular datagrid control?
You have to understand that DataGrid control may only display this sort of data structure:
[value0][value1]...[valueX]
[value0][value1]...[valueX]
...
[value0][value1]...[valueX]
While your data cannot be structured in this way easily - it looks like this:
[value0][value1]...[valueX]
--------------[value1]...[valueX]
...
[value0][value1]...[valueX]
--------------[value1]...[valueX]
...
[value0][value1]...[valueX]
--------------[value1]...[valueX]
...
See this page:
http://livedocs.adobe.com/flex/3/langref/mx/controls/AdvancedDataGrid.html
for ADG. I don't have an enterprise edition of FB, so, I cannot really use this component.
BTW. Look into this thread:
http://www.actionscript.org/forums/showthread.php3?t=201362
it deals with the very similar problem.
ackerchez
03-23-2009, 02:31 PM
Thanks, that code worked, with one problem. I see that I am only getting one student per section being displayed and not the second student in the second section. Any idea why?
As this is the first time I have had to use custom item renderers, can you explain what your code did? from what I can make of it, it looks like you are using AS to dig into the XML and convert the child nodes to strings and then displaying those strings. Am I correct? What does this help me? (Sorry if these seem like really simple and obvious questions to you, I am just trying to learn it a little better).
Thanks for all your help!!
wvxvw
03-23-2009, 03:00 PM
>> Thanks, that code worked, with one problem. I see that I am only getting one student per section being displayed and not the second student in the second section. Any idea why?
Just don't modify it - it is an example. Compile it as it is, then, try to understand what was different in your code that caused that problem.
>> As this is the first time I have had to use custom item renderers, can you explain what your code did? from what I can make of it, it looks like you are using AS to dig into the XML and convert the child nodes to strings and then displaying those strings. Am I correct? What does this help me? (Sorry if these seem like really simple and obvious questions to you, I am just trying to learn it a little better).
It creates 2 different inline components that are used as item renderers. Each inline component is a VBox that has custom public field firstName and custom public field firstNameText that is the reference to the Text component.
Those inline components override the data setter which is called by DataGrid when it populates the columns - thus they receive the data, they know is connected to them. They parse it and display as a single piece of text. Though, you can alter that behavior and have multiple Text components inside the item renderer, actually, you cann add those automatically, based on number of entries found in the data that is needed to be displayed by the item renderer etc.
ackerchez
03-23-2009, 03:15 PM
I didn't modify anything at all, i just put it into the application. I still see that only one student is being displayed
wvxvw
03-23-2009, 05:12 PM
I don't know what to tell you... occasionally, I've even tried this with different SDKs, and this is the picture I can see:
ackerchez
03-23-2009, 07:26 PM
I don't know what to tell you... occasionally, I've even tried this with different SDKs, and this is the picture I can see:
In the picture you provided you actually have a repeated student for some reason. I actually just copied the code in again and I am still only getting one student per section. Do you think I need a loop of some sort? I checked all the variables and I am getting both students in the "Chemistry" section coming in. I don't understand??
wvxvw
03-23-2009, 08:21 PM
The second John Smith appears 2 times in the data provider, that's why he appears 2 times in the datagrid...
I don't think this may be the issue with SDK version, but, are you by any chance using version less than 3?
ackerchez
03-23-2009, 08:46 PM
The second John Smith appears 2 times in the data provider, that's why he appears 2 times in the datagrid...
I don't think this may be the issue with SDK version, but, are you by any chance using version less than 3?
No, I'm using Flex Builder and using SDK version 3.2. The custom item renderer should function as a middle man for changing the data format into a compatible format right? (meaning that both child nodes of the second section should be passing through right?).
As a side issue, I did a trace on the "firstName" and I am getting this back:
s1
s1
s2
John
I don't understand why I am seeing s1 twice, after checking the XML I see that it is only coming back once. Any ideas?
wvxvw
03-23-2009, 08:50 PM
>> No, I'm using Flex Builder and using SDK version 3.2. The custom item renderer should function as a middle man for changing the data format into a compatible format right?
No. Item renderer visualizes the data.
>> meaning that both child nodes of the second section should be passing through right
Mmm... not really sure what do you mean... item render is created once per data chunk - so, each item renderer receives only 1 piece of data that it has to display. So, probably no, because each renderer in my example receives data only once (we never modify the dataprovider).
BTW, can you tell what is the exact SDK build you're using?
There should be a flex-sdk-description.xml file in your SDK in the root folder
with this sort of content:
<?xml version="1.0"?>
<flex-sdk-description>
<name>Flex 3</name>
<version>3.0.0</version>
<build>477</build>
</flex-sdk-description>
(this is an old one, apparently, you'll probably have something newer)
ackerchez
03-23-2009, 09:30 PM
>> No, I'm using Flex Builder and using SDK version 3.2. The custom item renderer should function as a middle man for changing the data format into a compatible format right?
No. Item renderer visualizes the data.
>> meaning that both child nodes of the second section should be passing through right
Mmm... not really sure what do you mean... item render is created once per data chunk - so, each item renderer receives only 1 piece of data that it has to display. So, probably no, because each renderer in my example receives data only once (we never modify the dataprovider).
BTW, can you tell what is the exact SDK build you're using?
There should be a flex-sdk-description.xml file in your SDK in the root folder
with this sort of content:
<?xml version="1.0"?>
<flex-sdk-description>
<name>Flex 3</name>
<version>3.0.0</version>
<build>477</build>
</flex-sdk-description>
(this is an old one, apparently, you'll probably have something newer)
The version that I am using is
<?xml version="1.0"?>
<flex-sdk-description>
<name>Flex 3.2</name>
<version>3.2.0</version>
<build>3958</build>
</flex-sdk-description>
if each item renderer is only receiving data once, could that be why the second student is not coming up for me? It is strange a little and I don't understand because when i did a trace within the script tag, I see that all the xml nodes are going through. Does the item renderer need some kind of flush between nodes?
just as an update - when I did a trace on the "names" array that is created within the function I get the following
"s1
s1
s2,John" I don't know where the comma is coming from but can it be the reason that I am not seeing "John" in my grid (since it comes after the comma)?
wvxvw
03-23-2009, 11:33 PM
Item renderer is a facory... it meas that you create several item renderers, not only one. The first "s1" you see is a null-item renderer, it's not displayed, but that's how DG works...
Sorry, I don't have this build on my working machine, so I can't test it right now. It seems like there's something messed up with
<mx:DataGrid x="253" y="345" variableRowHeight="true">
(so you don't see the whole item renderer, just a "top" of it). I'll check it tomorrow, and we'll see if that's the version problem.
ackerchez
03-24-2009, 07:44 AM
Item renderer is a facory... it meas that you create several item renderers, not only one. The first "s1" you see is a null-item renderer, it's not displayed, but that's how DG works...
Sorry, I don't have this build on my working machine, so I can't test it right now. It seems like there's something messed up with
<mx:DataGrid x="253" y="345" variableRowHeight="true">
(so you don't see the whole item renderer, just a "top" of it). I'll check it tomorrow, and we'll see if that's the version problem.
Ok, i got it to work. However, I see that the second student is displayed on the same row as the original student student for the second section.
Is there a way to put each student on a new row?
wvxvw
03-24-2009, 10:20 PM
OK, I've compiled it with all milestone builds starting with 3.0 and through to the latest 4.0 build... Apparently, you either copied something wrong, or are using some unique SDK that has this bug... For me it displays students each separate name on the new line... So, sorry, I just cannot reproduce your problem :(
ackerchez
04-01-2009, 09:30 AM
OK, I've compiled it with all milestone builds starting with 3.0 and through to the latest 4.0 build... Apparently, you either copied something wrong, or are using some unique SDK that has this bug... For me it displays students each separate name on the new line... So, sorry, I just cannot reproduce your problem :(
Hey wvxvw,
I've been working with this and I still can't get the data to display on individual rows. I took a screenshot so you can see what I mean. The highlighted portion is the area that I am wondering about. As you can see the entries are on seperate lines but within the same row. Any idea as to why? Here is the code that I put in:
<mx:DataGridColumn
headerText="First Name"
dataField="@label">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Script>
<![CDATA[
public override function set data(value:Object):void
{
var names:Array = [];
XML(value).student.firstname.text().(names.push(to XMLString()));
firstName = names.join("\r");
//trace (names);
}
]]>
</mx:Script>
<mx:String id="firstName"/>
<mx:Text id="firstNameText" text="{firstName}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
<mx:DataGridColumn
headerText="Last Name"
dataField="@label">
<mx:itemRenderer>
<mx:Component>
<mx:VBox>
<mx:Script>
<![CDATA[
public override function set data(value:Object):void
{
var names:Array = [];
XML(value).student.lastname.text().(names.push(toX MLString()));
lastName = names.join("\r");
}
]]>
</mx:Script>
<mx:String id="lastName"/>
<mx:Text id="lastNameText" text="{lastName}"/>
</mx:VBox>
</mx:Component>
</mx:itemRenderer>
</mx:DataGridColumn>
</mx:columns>
</mx:DataGrid>
Thanks!
wvxvw
04-01-2009, 12:10 PM
Sure, and this is because you have multiple <stunent> entries per <section> entry... So, either you put all the students belonging to a single section into a single row, or you format your XML differently...
I'd think of something like this:
<student section="Chemistry" firstName="John" lastName="Smith"/>
<student section="Biology" firstName="John" lastName="Doe"/>
....
and then:
var xml:XML =
<data>
<section label="Biology" id="1">
<student>
<firstname>s1</firstname>
<lastname>s1</lastname>
</student>
</section>
<section label="Chemistry" id="2">
<student>
<firstname>s2</firstname>
<lastname>s2</lastname>
</student>
<student>
<firstname>John</firstname>
<lastname>Smith</lastname>
</student>
<student>
<firstname>John</firstname>
<lastname>Smith</lastname>
</student>
</section>
</data>;
var resultList:XMLList;
xml.section.student.(deepToFlat(valueOf(), parent()));
function deepToFlat(studentXML:XML, sectionXML:XML):void
{
var node:XML = <student
firstName={studentXML.firstname}
lastName={studentXML.lastname}
section={sectionXML.@label}/>
if (!resultList) resultList = XMLList(node);
else resultList += node;
}
trace(resultList.toXMLString());
// <student firstName="s1" lastName="s1" section="Biology"/>
// <student firstName="s2" lastName="s2" section="Chemistry"/>
// <student firstName="John" lastName="Smith" section="Chemistry"/>
// <student firstName="John" lastName="Smith" section="Chemistry"/>
ackerchez
04-01-2009, 02:20 PM
I actually have my XML formatted the way that you do for in your second code post. So why should I be having this issue?
I haven't done anything to flatten the XML structure - is that the issue? That the first code structure that you typed wouldn't need flattening but the second one would?
wvxvw
04-01-2009, 02:29 PM
mmm... nope. What my last example does - it converts the XML from one structure to another, the latter is OK to use with DataGrid, but your DataGrid will look like this:
Chemistry | John | Smith
Chemistry | John | Doe
Biology | John | ...
ackerchez
04-01-2009, 03:35 PM
mmm... nope. What my last example does - it converts the XML from one structure to another, the latter is OK to use with DataGrid, but your DataGrid will look like this:
Chemistry | John | Smith
Chemistry | John | Doe
Biology | John | ...
I see, so if I wanted it to be something like this (all on separate rows):
Chemistry | John | Smith|
| John | Doe|
Biology | Jane | Johnson|
Then I would need to structure the XML to be more like the example that you had before?
wvxvw
04-01-2009, 05:13 PM
Your last example is not possible with DataGrid... because in order to use DataGrid control you have to ensure that each cell has a corresponding value (in your case you're trying to omit cells for <section> column...).
So, you have several ways to solve it:
- display all the students belonging to one section in the same row.
- restructure the XML in a way every student will have a @section attribute.
- use another control, that has this option... (OLAPDataGrid / Tree)
|
vBulletin® v3.8.4, Copyright ©2000-2009, Jelsoft Enterprises Ltd.