10 Replies Latest reply on Apr 29, 2008 12:37 PM by speedy_man

    DataGrid does not display XML data

      Hello, and thanks for reading this...
      I am having a problem displaying XMLList data in a DataGrid.
      The data is coming from a Tree control, which is receiving it from a database using HTTPService.
      The data is a list of "Job Orders" from a MySQL database, being formatted as XML by a PHP page.
      If it would be helpful to see the actual XML, a sample is here:

      All is going well until I get to the DataGrid, which doesn't display the data, although I know it is there as I can see it in debug mode. I've checked the dataField property of the appropriate DataGrid column, and it appears correct.

      Following is a summary of the relevant code.

      ...An HTTPService named "get_all_job_orders" retrieves records from a MySQL database via PHP...
      ...Results are formatted as E4X:
      HTTPService resultFormat="e4x"

      ...An XMLListCollection's source property is set to the returned E4X XML results:
      ...The "order" node is what is being used as the top-level of the XML data.
      <mx:XMLListCollection id="jobOrdersReviewXMLList" source="{get_all_job_orders.lastResult.order}"/>

      ...The "jobOrdersReviewXMLList" collection is assigned to be the dataProvider property of a Tree list, using the @name syntax to display the nodes correctly, and a change event function is defined to add the records to a DataGrid on a separate Component for viewing the XML records:
      <mx:Tree dataProvider="{jobOrdersReviewXMLList}"

      ...Here is the relevant "jobPosForm" code (the Job Positions Form, a separate Component based on a Form) :
      ...A variable is declared:
      public var positionsArray:XMLList;
      ...The variable is initialized on CreationComplete event of the Form:
      positionsArray = new XMLList;

      ...The Tree's change event function is defined within the "jobPosForm" Component.
      ...Clicking on a Tree node fires the Change event.
      ...This passes an event object to the function.
      ...This event object contains the XML from the selected Tree node.
      ...The Tree node's XML data is passed into the positionsArray XMLList.
      ...This array is the dataProvider for the DataGrid, as you will see in the following block.
      public function addTreePositionsToDG(event:Event):void{
      this.positionsArray = selectedNode.positions.position;

      ...A datagrid has its dataProvider is bound to positionsArray.
      ...(I will only show one column defined here for brevity.)
      ...This column has its dataField property set to "POS_TITLE", a field in the returned XML record:
      <mx:DataGrid width="100%" variableRowHeight="true" height="75%" id="dgPositions"
      dataProvider="{positionsArray}" editable="false">
      <mx:DataGridColumn width="25" headerText="Position Title" dataField="POS_TITLE"/>

      In debug mode, I can examine the datagrid's dataProvider property, and see that the correct XML data from the Tree control is present. However, The datagrid does not display the data in any of its 6 columns.

      Does anyone have any advice?
      Thanks for your time.
        • 1. Re: DataGrid does not display XML data
          ntsiii Level 3
          You can't bind to XMLList. It does not dispatch the necessary events. You can bind to XML, or probably better in your case, wrap the XMLList in an XMLListCollection.

          • 2. Re: DataGrid does not display XML data
            speedy_man Level 1
            Thanks for the reply.
            Since I posted earlier, I tried changing the variable "positionsArray" to type XMLListCollection. I got the same results: no data is displayed in the dataGrid.

            Maybe someone can suggest a resource for DataGrid dataProvider? I've tried the Flex help, and I have already purchased five Flex books; none appear to have the particulars I need on feeding external data into a DataGrid.

            • 3. Re: DataGrid does not display XML data
              ntsiii Level 3
              trace(XMLListCollection.toXMLString(), to be sure you have the structure you think you have.

              Post a few nodes.
              • 4. Re: DataGrid does not display XML data
                speedy_man Level 1
                Thank you.
                I have verified the XML structure by placing a breakpoint and then debugging. Looking at the positionsArray variable results, I get exactly what you can see on the XML output page link I posted earlier and again at the end of this post.

                I'm beginning to think that a Datagrid cannot handle this kind of complex XML, that is, XML that has attribute tags. All examples for Datagrids that I have found use simple open/close tags for each node, with NO attributes assigned inside the tags. I output my MySQL data formatted this way using the example for a tree control in the Adobe Flex 2 training book, which uses lots of attributes for the tree control's dataprovider.

                I am currently looking at using a LabelFunction for the DatagGrid columns, but it is also balking at accessing any attribute tags. So maybe there is a certain syntax used to get at these tags, or the Flex DataGrid simply cannot do it.

                Again, the link to the XML is here:

                And here is the Adobe example I modeled my output after:

                Thank you for taking the time to look at this...
                • 5. Re: DataGrid does not display XML data
                  ntsiii Level 3
                  No, DataGrid can handle attributes, I use attributes and child tags intermixed regularly.

                  I can't seem to hit the xml link from this client.

                  The syntax for attributes id dataField="@myAttribute". You need a labelFunction only if your data is nested beneath the "item" nodes. You can directly access attributes and first level child nodes.

                  Post a few nodes of your xml and post the DataGridColumn declarations.

                  • 6. Re: DataGrid does not display XML data
                    ntsiii Level 3
                    Ok, I see your XML from here now.

                    Yes, you will need a labelFunction() to access the positions.position nodes.

                    What does your labelFunction look like?

                    • 7. Re: DataGrid does not display XML data
                      speedy_man Level 1
                      Good morning,
                      All I have for a labelFunction is a skleteon:
                      private function myFunction(item:Object,column:DataGridColumn):String{
                      //return ?????

                      I am reading through documentation on this function, but so far do not know how to return XML attributes using it.
                      Thank you again for looking at this. I will be spending another day on this problem, I think!
                      • 8. Re: DataGrid does not display XML data
                        ntsiii Level 3
                        private function myFunction(item:Object,column:DataGridColumn):String{
                        var xmlItem:XML = XML(item);
                        var xmlPosition:XML = xmlItem.positions[0];
                        return xmlPosition.@POS_TITLE;

                        I have several full examples on www.cflex.net. Search for labelFunction.

                        • 9. Re: DataGrid does not display XML data
                          speedy_man Level 1
                          Thank you for your reply.
                          I tweaked your function a little to get it working, as it was not displaying anything in the DataGrid:

                          private function myFunction(item:Object,column:DataGridColumn):String{
                          var xmlItem:XML = XML(item);
                          //trace(xmlItem.toXMLString()); //COMMENTED OUT.
                          var xmlPosition:XML = xmlItem.positions[0];
                          //trace(xmlPosition.toXMLString()); //COMMENTED OUT.
                          //return xmlPosition.@POS_TITLE; //COMMENTED OUT.
                          trace(xmlPosition.position.@POS_TITLE); //THIS IS MY ADDITION.
                          return xmlPosition.position.@POS_TITLE; //THIS IS MY ADDITION.

                          You can see how I burrowed in one more node deeper to get at the node I want: the "position" node, which represents the "positions" details part of each individual customer "job" order.
                          Unfortunately, Flex then returns this to the DataGrid:
                          Repair writerLine Mechanic

                          Notice how the first two records are concatenated. I guess this is logical. But it looks like I will have to use some kind of "loop" to separate these two values into two records on the DataGrid.

                          This is all rather cumbersome. I am hoping to stumble on some way to simply pass the Tree control's selected node into a DataGrid, and have it bound so the user can select an order from the DataGrid to update. I can then send this back to the MySQL database. At this point, I'm not even sure the methods I am using here will achieve this, as I seem to be separating the returned XML data into Arrays, ArrayCollections, XMLLists, XMLLIstCollections... I can't seem to get from point A to Point B in a simple and efficient manner. I am using too many objects here, I feel.

                          I am going to look at the examples you pointed to for help/inspiration. Thanks again for all your time and effort.
                          • 10. Re: DataGrid does not display XML data
                            speedy_man Level 1
                            Hello again,
                            I came up with a method of populating the DataGrid from the selected Item of a Tree Control which displays complex XML data and XML attributes. After the user clicks on a Tree branch, I call this function:

                            public function addTreePositionsToDG(event:Event):void{
                            //Retrieve all "position" nodes from tree.
                            //Loop thru each Position.
                            //Add Position data to the positionsArray Array Collection.
                            //The DataGrid dataprovider is bound to this array, and will be updated.
                            positionsArray = new ArrayCollection();
                            var selectedNode:Object=event.target.selectedItem;//Contains entire branch.
                            for each (var position:XML in selectedNode.positions.position){
                            var posArray:Array = new Array();
                            posArray.PK_POSITIONID = position.@PK_POSITIONID;
                            posArray.FK_ORDERID = position.@FK_ORDERID;
                            posArray.POS_TITLE = position.@POS_TITLE;
                            posArray.NUM_YOUTH = position.@NUM_YOUTH;
                            posArray.AGE_1617 = position.@AGE_1617;
                            posArray.AGE_1821 = position.@AGE_1821;
                            posArray.HOURS_WK = position.@HOURS_WK;
                            posArray.WAGE_RANGE_FROM = position.@WAGE_RANGE_FROM;
                            posArray.WAGE_RANGE_TO = position.@WAGE_RANGE_TO;
                            posArray.JOB_DESCR = position.@JOB_DESCR;
                            posArray.DES_SKILLS = position.@DES_SKILLS;



                            So, I just had to manually go through the selected Tree node, copy each XML attribute into a simple Array, then ADD this Array to an ArrayCollection being used as the DataProvider for the DataGrid. It's not elegant, but it works and I don't have to use a Label Function, which was getting way too complicated. I still think that Flex should have an easier way of doing this. There probably is an easier way, but the Flex documentation doesn't provide an easy path to it.

                            I want to thank you, Tracy, for the all the help. I checked out the examples you have at www.cflex.net and they are very helpful. I bookmarked the site and will be using it as a resource from now on.