5 Replies Latest reply on Jul 26, 2006 10:23 PM by jpwrunyan

    Problem with selectedItem (DataGrid) when dataProvider is XML

    jpwrunyan Level 1
      I have a problem.
      I want to load my DataGrid with data from XML returned via Struts. I have set up a test environment for the time being and I can LOAD the data into the grid just fine, but when I want to refer to it after it is loaded (with selectedItem) I am having all sorts of problems. Namely, I can't access any of the data in selectedItem. I can't even seem to make it show up in a string... the only way I can access values is individually using :

      selectedItem["@attribute"] which is NOT what I want to do...
      can anyone tell me what I am doing wrong? Is there no way I can convert the xml to an object (or is that even the problem)?

      Here is code to show exactly what I mean:
      <?xml version="1.0"?>
      <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" layout="vertical" creationComplete="doDummySearch()">
      <mx:Script>
      <![CDATA[
      import mx.utils.ArrayUtil;
      import mx.controls.Alert;
      //this dummyXML is in place of the response from the server for now...
      private var dummyXML:XML =
      <root>
      <dummyData priority='0' dealerCode='A00-1023' phoneNo='0343442323' />
      <dummyData priority='1' dealerCode='B00-1033' phoneNo='0343442323' />
      <dummyData priority='0' dealerCode='DER-0666' phoneNo='0343442323' />
      </root>
      private function doDummySearch():void {
      search_dg.dataProvider = dummyXML.children();

      }

      private function select():void {
      var s:String = "";
      s+=search_dg.selectedItem["@dealerCode"]+"\n";
      s+="all data: \n";
      for each (var entry:* in search_dg.selectedItem) {
      s+=entry+"\n";
      }
      s+="^-why is this blank?\n";
      s+="selectedItem.toString(): "+search_dg.selectedItem.toString()+" <-why is this blank?";
      mx.controls.Alert.show(s, "selected data:");
      }
      ]]>
      </mx:Script>
      <mx:DataGrid id="search_dg" />
      <mx:Button label="select item" click="select()" />

      </mx:Application>
        • 1. Re: Problem with selectedItem (DataGrid) when dataProvider is XML
          raghunathrao
          I think there are 2 ways to work around this problem. One is to parse the incoming XML into an ArrayCollection and then bind the the arrayCollection to the datagrid, rather than the XMl itself.

          When an XML is bound directly to a datagrid, the datagrid is intelligent enough to display the individual nodes (XML Objects). But when you get the selectedItem, it just throws the XML object back at you.

          So, the other way is that, if you really want to extract data out of it, you can hardcode and use like
          s+="Dealer Code = "+search_dg.selectedItem["@dealerCode"]+"\n";
          s+="Priority = "+search_dg.selectedItem["@priority"]+"\n";
          s+="Phone No. = "+search_dg.selectedItem["@phoneNo"]+"\n";

          The toString() does not work here because e.g.
          var test:XML = <type name="Joe">example</type>;
          trace(test.toString()); //returns - example
          but
          trace(test.toXMLString()); //returns - <type name="Joe">example</type>

          So use it as
          s+="selectedItem.toString(): "+search_dg.selectedItem.toXMLString()
          to get the desired effect...

          But I still think parsing the incoming XML into an ArrayCollection is the best way
          • 2. Re: Problem with selectedItem (DataGrid) when dataProvider is XML
            raghunathrao Level 1
            Or even better, you can use the new E4X support in Flex, to directly read from the XML
            See this example
            -------------------------
            main.xml
            -------------------------
            <?xml version="1.0"?>
            <mx:Application xmlns:mx=" http://www.adobe.com/2006/mxml" xmlns="*" layout="vertical" >
            <mx:Script>
            <![CDATA[
            private function select():void {
            var s:String = "";
            s+="Symbol = "+search_dg.selectedItem.Symbol+"\n";
            s+="Quantity = "+search_dg.selectedItem.Quantity+"\n";
            s+="Price = "+search_dg.selectedItem.Price+"\n";
            s+="Value = "+search_dg.selectedItem.Value+"\n";

            mx.controls.Alert.show(s, "selected data:");
            }
            ]]>
            </mx:Script>
            <mx:XML format="e4x" id="portfolioModel" source="portfolio.xml" />
            <mx:DataGrid id="search_dg" dataProvider="{portfolioModel.security}">
            <mx:columns>
            <mx:DataGridColumn dataField="Symbol" headerText="Symbol"/>
            <mx:DataGridColumn dataField="Quantity" headerText="Quantity"/>
            <mx:DataGridColumn dataField="Price" headerText="Price"/>
            <mx:DataGridColumn dataField="Value" headerText="Value"/>
            </mx:columns>
            </mx:DataGrid>
            <mx:Button label="select item" click="select()" />
            </mx:Application>
            --------------------------------
            portfolio.xml
            --------------------------------
            <portfolio>
            <security>
            <Symbol>MSFT</Symbol>
            <Quantity>10000</Quantity>
            <Price>20.56</Price>
            <Value>1</Value>
            </security>
            <security>
            <Symbol>IBM</Symbol>
            <Quantity>3000</Quantity>
            <Price>80.21</Price>
            <Value>1</Value>
            </security>
            <security>
            <Symbol>ADBE</Symbol>
            <Quantity>10000</Quantity>
            <Price>32.56</Price>
            <Value>1</Value>
            </security>
            <security>
            <Symbol>GOOG</Symbol>
            <Quantity>3000</Quantity>
            <Price>380.21</Price>
            <Value>1</Value>
            </security>
            </portfolio>
            • 3. Problem with selectedItem (DataGrid) when dataProvider is XML
              jpwrunyan Level 1
              I think the idea you first mentioned about setting the xml into an ArrayCollection will work best for my purposes. I don't want to hardcode the property values from the xml because I am basically passing the selectedItem of the DataGrid to a variety of components which I want individually to choose what data they use. But the thing is, these components are also taking data from non-xml sources so ... anyway, it's a morass. I gotta get the XML to change into a normal Object for component re-usability.

              I also thought, even if I set the DataGrid to take XML data, maybe I can just construct an Object from selectedItem using the attributes property. That way I can pass all values from the XML without knowing (hard-coding) what the value attribute name is... I'll let you know how it goes. E4X was supposed to be an improvement in my life but I am finding it still to be counter-intuitive and difficult. I wish you could just do something like Object(xml) or Array(xmlList) and have the conversion done for you perfectly.

              By the way, this is illustrated by the example in your second reply. When you read xml into a Model everything is very easy. However, I can't use your second model example because the data is going to eventually come from an HTTPRequest (Struts) and come into Flex as XML, get sliced and diced, then sent off as sub-XML objects to the various controllers in the application.
              • 4. Re: Problem with selectedItem (DataGrid) when dataProvider is XML
                ntsiii Level 3
                Aargh, I hate mx:Model. Mostly because i was unable to predict how Flex was going to convert it into objects. But there was a utility function in 1.5 , something like xmlToObject, maybe something still exists in 2.0. If I can find it i'll post it here.

                " I gotta get the XML to change into a normal Object for component re-usability."
                Why not just stay XML?

                Tracy
                • 5. Re: Problem with selectedItem (DataGrid) when dataProvider is XML
                  jpwrunyan Level 1
                  Like I said, if I stay in XML then I have to explicitely decide what attributes are in the object in order to pass them/access them. I have to use String literals ("@attributeName").
                  The more time I have spent thinking about it, I COULD restructure my components all to use XML data but I don't want to impose that on other programmers. (for example, make my controls look for ["@label"] instead of .label).
                  It would also be nice to make my components capable of taking either XML or Object as a dataProvider and then automatically convert XML into Object. I guess I could also try doing it the other way around, just make all Objects into XML. Again, it just comes down to taste. For example, I prefer labelField="label" to labelField="@label".
                  I feel strongly that Object gives better compatability. This may be a bias.