PDA

View Full Version : Dynamic DataGrid


ackerchez
04-22-2009, 02:53 PM
Hey All,

I'm having an issue that I was hoping someone can help me out with.

I need to populate a datagrid based on XML being returned to Flex. The structure of the XML is as follows:

<root>
<lab id="2" title="Chemical Materials">
<assignment assignmentid="2" name="s2 s2" grade="B"/>
<assignment assignmentid="4" name="s1 s1" grade="C"/>
<assignment assignmentid="6" name="John Smith" grade="B"/>
</lab>
<lab id="8" title="BioChem">
<assignment assignmentid="3" name="s2 s2" grade="F"/>
<assignment assignmentid="5" name="John Smith" grade="D"/>
</lab>
</root>


When this XML gets returned to Flex I need to throw it into a Datagrid for diaplay. The catch is there can be any number of columns in the datagrid becasue the assignments can be of different quantities.

Here is the code that I am using to make the grid:

private function getGradebookSectionDb(event:ResultEvent):void{
var gradebookBySection:XMLList = event.result.lab;

var cols:Array=new Array;

for (var i:int=0;i<gradebookBySection.length();i++){
var col:DataGridColumn=new DataGridColumn();
col.headerText=gradebookBySection[i].@title.toXMLString();
col.dataField=gradebookBySection[i].children().@grade.toXMLString();
cols.push(col);
gradebookDatagrid.columns=cols;
gradebookDatagrid.visible=true;
}


When I do this, the columns get created from the XML very nicely but there is no data showing up in the columns. I would like to get the grade to show up in the columns but for some reason nothing comes up. When I do a trace on the "col.datafield" I get the right information coming back in the trace but nothing shows up in the column.

I would have just assigned the XML as a datapovider to the datagrid but as the amount of assignments returned can change, I saw this as my only option.

Can anyone help me with this?

Thanks!

JeTSpice
04-22-2009, 06:22 PM
are you able to use the advancedDataGrid? if so, you can use the tree display inside the advancedDataGrid like so:

http://livedocs.adobe.com/flex/3/html/help.html?content=advdatagrid_06.html

This would put the assignments in separate rows, not columns, like you specified.

If it is imperative to have a new column for each assignment, then the XML might need some restructuring, or perhaps someone else knows of a way to restructure it as it is brought into the client.

ackerchez
04-23-2009, 09:37 AM
are you able to use the advancedDataGrid? if so, you can use the tree display inside the advancedDataGrid like so:

http://livedocs.adobe.com/flex/3/html/help.html?content=advdatagrid_06.html

This would put the assignments in separate rows, not columns, like you specified.

If it is imperative to have a new column for each assignment, then the XML might need some restructuring, or perhaps someone else knows of a way to restructure it as it is brought into the client.

Hi JetSpice,

I am a little unfamiliar with the AdvancedDataGrid, and I wasn't able to get that much out of reading the adobe doc. Can you give me an example as to how you would set this up with the advancedDataGrid? I'm a little lost.

Additionally, as I have been working with this I think that I will want to display the name information also. I have no idea how to pull all these pieces from that XML into one grid that would have columns append to it as needed. Do you have any recommendations?

Can any other members help out?

Thanks!

chadzilla
04-23-2009, 01:48 PM
Here is an example of an advanced datagrid...this is what I would use instead of a regular datagrid...the values are hard codded in for this example, but I could work up an example pulling from an XML file if you need that.

<?xml version="1.0"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml">

<mx:Script>
<![CDATA[
import mx.collections.ArrayCollection;

[Bindable]
private var dpFlat:ArrayCollection = new ArrayCollection([
{Myclass:"Chemical Materials", Name:"John Smith",
Assignment:"Lab1", Grade:"B"},
{Myclass:"Chemical Materials", Name:"Bill Williams",
Assignment:"Lab1", Grade:"C"},
{Myclass:"Chemical Materials", Name:"Sara Jones",
Assignment:"Lab1", Grade:"A"},
{Myclass:"Chemical Materials", Name:"John Smith",
Assignment:"Lab2", Grade:"D"},
{Myclass:"Chemical Materials", Name:"Bill Williams",
Assignment:"Lab2", Grade:"B"},
{Myclass:"Chemical Materials", Name:"Sara Jones",
Assignment:"Lab2", Grade:"C"},
{Myclass:"BioChem", Name:"Dan Brown",
Assignment:"Lab1", Grade:"D"},
{Myclass:"BioChem", Name:"Bill Williams",
Assignment:"Lab1", Grade:"B"},
{Myclass:"BioChem", Name:"Sara Jones",
Assignment:"Lab1", Grade:"C"},
{Myclass:"BioChem", Name:"Dan Brown",
Assignment:"Lab2", Grade:"A"},
{Myclass:"BioChem", Name:"Bill Williams",
Assignment:"Lab2", Grade:"A"},
{Myclass:"BioChem", Name:"Sara Jones",
Assignment:"Lab2", Grade:"F"},

]);
]]>
</mx:Script>

<mx:Panel title="AdvancedDataGrid Control Example"
height="75%" width="75%" layout="horizontal"
paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">

<mx:AdvancedDataGrid id="myADG"
width="100%" height="100%"
initialize="gc.refresh();">
<mx:dataProvider>
<mx:GroupingCollection id="gc" source="{dpFlat}">
<mx:grouping>
<mx:Grouping>
<mx:GroupingField name="Myclass"/>
<mx:GroupingField name="Assignment"/>
</mx:Grouping>
</mx:grouping>
</mx:GroupingCollection>
</mx:dataProvider>

<mx:columns>
<mx:AdvancedDataGridColumn dataField="Name"/>
<mx:AdvancedDataGridColumn dataField="Grade"/>
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Panel>

</mx:Application>

If you ever need examples of how components work...this is the best place I've seen.

http://examples.adobe.com/flex3/componentexplorer/explorer.html

another good thing is

http://www.adobe.com/devnet/flex/tourdeflex/
Tour de flex is an air app written by adobe that has examples of everything

ackerchez
04-23-2009, 02:10 PM
Hi Chadzilla,

Thanks for the response, I'll look over the code. Having an example using XML would be really helpful, if it isn't too much trouble do you think you can cook up an example?

Thanks a million!!

chadzilla
04-23-2009, 02:59 PM
Try this...the xml for this one is coded in, but it should be the same if you were getting it from an outside source.


<?xml version="1.0" encoding="utf-8"?>
<mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="vertical">

<mx:XML id="inputData" >
<Class>
<record id="Lab1" group="BioChem" student="Bill" Grade="A"/>
<record id="Lab1" group="BioChem" student="Sarah" Grade="B" />
<record id="Lab1" group="BioChem" student="Mark" Grade="C" />
<record id="Lab2" group="BioChem" student="Bill" Grade="C"/>
<record id="Lab2" group="BioChem" student="Sarah" Grade="B"/>
<record id="Lab2" group="BioChem" student="Mark" Grade="A"/>

<record id="Lab1" group="Chemical Materials" student="Mark" Grade="A" />
<record id="Lab1" group="Chemical Materials" student="Dave" Grade="B" />
<record id="Lab1" group="Chemical Materials" student="Megan" Grade="C" />
<record id="Lab1" group="Chemical Materials" student="Joe" Grade="D" />
<record id="Lab1" group="Chemical Materials" student="Katie" Grade="F" />
</Class>
</mx:XML>


<mx:AdvancedDataGrid creationComplete="gc.refresh()" width="600" height="219">
<mx:dataProvider>
<mx:GroupingCollection source="{inputData.record}" id="gc">
<mx:Grouping>
<mx:GroupingField name="@group" />
<mx:GroupingField name="@id" />
</mx:Grouping>
</mx:GroupingCollection>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn dataField="@student" />
<mx:AdvancedDataGridColumn dataField="@Grade" />
</mx:columns>
</mx:AdvancedDataGrid>
</mx:Application>

ackerchez
04-23-2009, 03:06 PM
So then I am better off not having it in a node-child relationship? before I was doing it with lab as the parent and then the assignments were the children of the lab. The example you gave removes that heirarchy...

chadzilla
04-23-2009, 03:15 PM
Correct...for this I would let the grouping function of the advanced datagrid set up the heirarchy

So I did a group of classes (biochem, chemical materials)
Then a sub group of labs (lab1, lab2, lab3 and so on)

ackerchez
04-23-2009, 03:27 PM
Correct...for this I would let the grouping function of the advanced datagrid set up the heirarchy

So I did a group of classes (biochem, chemical materials)
Then a sub group of labs (lab1, lab2, lab3 and so on)

Ah ha, interesting. I wouldn't have thought to do that at all, I thought that because it is a more complex data set it would be good to set up the data structure before sending it over.

I see what you did for the groups, now I guess I will just have to go back to the php and alter it to return the correct structure.

Thanks!!

ackerchez
04-26-2009, 09:46 AM
Hi Chadzilla,

Thanks for the help so far, let me update you on this issue.

I have reworked the php providing the xml for the AdvancedDataGrid to return a structure similiar to what you described and here is the new structure:


<root>
<assignment assignmentid="2" lab="2" title="Chemical Materials" studentid="22" name="s2 s2" grade="B"/>
<assignment assignmentid="4" lab="2" title="Chemical Materials" studentid="1" name="s1 s1" grade="C"/>
<assignment assignmentid="6" lab="2" title="Chemical Materials" studentid="5" name="John Smith" grade="B"/>
<assignment assignmentid="3" lab="8" title="BioChem" studentid="22" name="s2 s2" grade="F"/>
<assignment assignmentid="5" lab="8" title="BioChem" studentid="5" name="John Smith" grade="D"/>
<assignment assignmentid="5" lab="8" title="Biological Materials" studentid="5" name="John Smith" grade="B"/>
</root>


I have also worked the AdvancedDataGrid as you suggested and here is the result code for that:


<mx:AdvancedDataGrid x="39" y="92" id="adg1" creationComplete="gc.refresh()" designViewDataType="tree" width="555" height="328">
<mx:dataProvider>
<mx:GroupingCollection source="{getGradebookSection.lastResult.assignment}" id="gc">
<mx:Grouping>
<mx:GroupingField name="@title"/>
</mx:Grouping>
</mx:GroupingCollection>
</mx:dataProvider>
<mx:columns>
<mx:AdvancedDataGridColumn dataField="@name"/>
<mx:AdvancedDataGridColumn dataField="@grade"/>
</mx:columns>
</mx:AdvancedDataGrid>


Here is the weird part that I do not understand. When I use the XML and advancedDataGrid in a standalone application file (removed from the main app that I am working on), provide an XML ID, and load the AdvancedDataGrid from there is all works great. However, when I bring all the code into the main app and assign the source from the grouping collection to "{getGradebookSection.lastResult.assignment}" it all seems to get messed up and nothing displays in the grid. I have even tried to assign the lastresult to an XMLList variable and that too doesn't work.

UPDATE: I did some testing and I think the issue is with the creationComplete event. I think it is firing before the information is ready for it. I sent the refresh to fire on a button and it worked fine. Any idea how to fire the event at the right time?

UPDATE #2 - Solved IT!! I fired the refresh in the result handler from the HTTPService.

Any idea why?

Thanks!

JeTSpice
04-28-2009, 05:17 AM
...there's some weird thing with datagrids. when they get their data dynamically, they reset to default. i would lose all my styles, and then had to re-do them in ActionScript, which is less effective. This may be the same issue (or related) to yours.

I believe Flex was thought out with the idea in mind that it would make any database calls first, and then calculate the display second (which is affected by the type/kind/amount of data)