9 Replies Latest reply on Apr 2, 2007 7:06 AM by csawall

    Set Combobox value based on Datagrid selectedItem

    csawall Level 1
      I have been searching the forums and google for some time now and I'm not sure how do this. I populate a datagrid from a httpservice call to a php script. The datagrid is displaying perfectly. I also populate two comboboxes from the same httpservice with specific values. When I select a row in the datagrid, I'd like the value of the combobox to change to that which corresponds to the value from the datagrid.

      I also have a few TextInput fields mixed in with the comboboxes and I'm able to set those to the datagridname.selectedItem.item. I would like to do the same for the comboboxes.

      The reason is so that I can edit users in a group within a database. The comboboxes are for the specific groups that are allowed to all users.

      Please let me know if any other information is necessary. I didn't think any of my current code would help with this question. Any examples would be great, I just couldn't find any....

      Thanks in advance for your time.

      Chris
        • 1. Re: Set Combobox value based on Datagrid selectedItem
          ntsiii Level 3
          If I understand correctly, you want to set the selected item of the combo boxes to match the selected item in the dataGrid?

          There are two ways. If you have an exact *reference* to the item you want to select, you can set the comboBox selectedItem to that reference.

          If you have a key value, then you have to loop over the cbo dataProvider and compare the value you are looking for to the value of the item.property that contains the values.

          Tracy
          • 2. Re: Set Combobox value based on Datagrid selectedItem
            csawall Level 1
            Yes, I would like the combobox to change values to that of what is seleted in the datagrid. I am sure you are leading me in the right direction, just not sure if I follow yet...

            Here's what I have, maybe you can help me out a little more if you'd be so kind.

            First I make a call to a PHP script to pull data out of MySQL.

            <mx:HTTPService id="getUsers" url="https://site/flextest/getusers.php" useProxy="false" method="GET"/>

            Here are is my part of my Panel with fields and comboboxes and the DataGrid. I have 4 other TextInput fields and another ComboBox.

            <mx:Panel width="250" height="315" left="5" layout="absolute" title="User Details">
            <mx:HBox x="10" y="27" width="210">
            <mx:Label text="Username" width="65"/>
            <mx:TextInput id="adm_username" width="137" text="{dgUserDetails.selectedItem.uname}"/>
            </mx:HBox>
            <mx:HBox x="10" y="55" width="210">
            <mx:Label text="Group" width="65"/>
            <mx:ComboBox id="adm_usergroup" width="137" dataProvider="{getUsers.lastResult.allusers.group}" labelField="teamname"/>
            </mx:HBox>
            <!----- SNIP ----->
            <mx:Panel>
            <mx:DataGrid id="dgUserDetails" right="5" dataProvider="{getUsers.lastResult.allusers.user}" height="315" click="viewUser()">
            <mx:columns>
            <mx:DataGridColumn headerText="Username" dataField="uname"/>
            <mx:DataGridColumn headerText="Group" dataField="team"/>
            <!----- SNIP ----->
            </mx:columns>
            </mx:DataGrid>

            The "viewUser()" function just enables/disables a few LinkButtons. If they don't just a user, then I let them add one. If they choose a user, I take away the Add User function.

            As you can see, I populate the TextInput fields and they work fine. I populate the Combobox with a list of available groups. I'd like that list to remain, but change to the group associated to the user I select in the DataGrid.

            I think I explained everything, but please feel free to ask me for any other info.

            Thanks,
            Chris

            • 3. Re: Set Combobox value based on Datagrid selectedItem
              ntsiii Level 3
              Ahh, yes.
              First, I advise against binding directly to lastResult and instead use a result handler funtion, mainly becasue it is hard to debug, but also becasue you often want to take some other action when the data arrive. You can keep the binding to the DG if you want for now, but I advise against it.

              Second, set resultFormat="e4x" in the http service tag. It defaults to object, which causes flex to convert the xml into a nested object structure. e4x xml is much easier to work with. You might not even need to modify the binding expression.

              Create an instance(global) variable to be the dataProvider of the combo box:
              [Bindable]private var _xlcGroups:XMLListCollection;

              Create a change event handler on the DataGrid:
              private function onChangeUser(oEvent:Event):void {
              var xmlUser:XML = XML(oEvent.target.selectedItem); //the Users dataProvider item
              var xlGroups:XMLList = xmlUser.groups.group; //this depends on your xml structure
              _xlcGroups = new XMLListC0llection(xlGroups)
              trace(xlcGroups .toXMLString() ); //so you can see exactly what you have
              ......

              Now, bind the combo box to the instance variable:
              dataProvider="{xlcGroups}"

              Post a bit of your xml if you need help with the e4x expressions.
              Tracy
              • 4. Re: Set Combobox value based on Datagrid selectedItem
                csawall Level 1
                Thanks Tracy. I am going to test out what you put down. I do have a few questions. What does the underscore do when setting the variable? I see you set _xlcGroups, but in the trace and dataprovider, you refer to it without the underscore. Also, the oEvent could be any name, right? And the target in xmlUser.... is that the name of the datagrid or where i want the data to be displayed?

                Also, you set the dataprovider for the combobox to the xlcGroups, which should display the data pulled from the httpservice call, right? It looks like it. But my real question is how does it get set from the my httpservice call, like I'm doing now? I need all the groups to be displayed at all times (so a new user could be added). But I want it to change to the selected item in the datagrid as well. That may be what you're showing, I just want to be sure. Like I said, I'm going to test it out.

                The following is an example of part of the xml that's pulled back.

                <allusers>
                <user>
                <uname>userid</uname>
                <team>alpha</team>
                <status>active</status>
                </user>
                <group>
                <teamname>alpha</teamname>
                <status>active</status>
                </group>
                <statusops>
                <status>active</status>
                </statusops>
                </allusers>

                Thanks again for all the help so far.

                Chris



                • 5. Re: Set Combobox value based on Datagrid selectedItem
                  ntsiii Level 3
                  The underscore is just a convention for private instance variables(properties). the missing underscors in my code are typos, all should be the same.
                  oEvent can be any name.

                  "target" is a property on the event that contains areference to to component that raised the event, in this case, the dataGrid.

                  Still not enough xml to understand the structure. My example assumed that "groups" was a node under user, but apparently this is not so.

                  How is a set of groups associated with a specific user?

                  Tracy
                  • 6. Re: Set Combobox value based on Datagrid selectedItem
                    csawall Level 1
                    Tracy - Thanks. For the XML. Picture that each <user> and <group> section happens multiple times. Under <user> there is a <team>, which is actually the group. I know a little confusing, but I'm working with an existing DB. So for each user there is a <uname>, <team> and <status> (plus a few other details). This correlates the user and group (uname and team). The <group> section will list all the groups, each repeated section will have <teamname> and <status>. Where teamname is the group name, which is really the same as team. I know, confusing. But I hope I'm making it make sense. I created the <group> section so that I could pull back all of the group names to populate the combobox.

                    I plan on testing your idea soon. I've just been busy today.

                    I appreciate you taking the time on this with me.

                    Chris
                    • 7. Re: Set Combobox value based on Datagrid selectedItem
                      csawall Level 1
                      Tracy - I'm still confused about the "target". You said:

                      "target" is a property on the event that contains areference to to component that raised the event, in this case, the dataGrid.

                      So, would that be the ID of the datagrid? I changed my datagrid to "click="onUserChange(oEvent)"" and I changed the following two lines as well:

                      var xmlUser:XML = XML(oEvent.dgUserDetails.selectedItem); //the Users dataProvider item
                      var xlGroups:XMLList = xmlUser.allusers.group; //this depends on your xml structure

                      Sorry for all the questions, but as I'm sure you can tell, I'm new to this. I try to do as much research as I can before I post. Guess I better buy a book....

                      Please let me know if you can still help me out.

                      Chris
                      • 8. Re: Set Combobox value based on Datagrid selectedItem
                        csawall Level 1
                        Tracy - I think I'm progressing, but I'm still running into problems. I've changed the httpservice to call an eventhandler, which in turn I use in the datagrid to populate it. I'm sure I might need to change something, but it is working.... Once I get it all working, I'll stop using lastResult and build event handlers, now that I'm starting to get a better grasp on it.

                        I do get an error though, stating: "Data binding will not be able to detect changes to XMLList "user", need an XML instance." Also, I can't seem to get "trace" to work. I'm guessing it should be popping up a window? If I do an alert popup, it does show the data.

                        [Bindable]private var myData:XMLList;
                        private function test(oEvent:ResultEvent):void {
                        myData = XMLList(oEvent.result);
                        trace(myData.toXMLString());
                        mx.controls.Alert.show(myData);
                        }

                        <mx:HTTPService id="getUsers" url="https://server/flex/getusers.php" resultFormat="e4x" result="test(event)" useProxy="false" method="GET"/>

                        <mx:DataGrid id="dgUserDetails" right="5" dataProvider="{myData.user}" height="315" click="onChangeUser(event)">
                        <mx:columns>
                        <mx:DataGridColumn headerText="Username" dataField="uname"/>
                        <mx:DataGridColumn headerText="Group" dataField="team"/>
                        <mx:DataGridColumn headerText="Status" dataField="status"/>
                        <mx:DataGridColumn headerText="Last Login" dataField="llogin"/>
                        <mx:DataGridColumn headerText="Count" dataField="lcount"/>
                        </mx:columns>
                        </mx:DataGrid>


                        Now, onto the user editing fields. I'm still trying to figure out how to use this example you gave me. I understand the xmlUser var and I think I understand the xlGroups var. Not sure how it should work though. It looks as though xlGroups tries to get the group from allusers under the user name?

                        [Bindable]private var _xlcGroups:XMLListCollection;
                        private function onChangeUser(oEvent:Event):void {
                        var xmlUser:XML = XML(dgUserDetails.selectedItem); //the Users dataProvider item
                        var xlGroups:XMLList = xmlUser.allusers.group; //this depends on your xml structure
                        _xlcGroups = new XMLListCollection(xlGroups)
                        trace(_xlcGroups.toXMLString() ); //so you can see exactly what you have
                        }

                        Let me try to give a better example of the XML.

                        <allusers>
                        <user>
                        <uname>user1</uname>
                        <level>6</level>
                        <status>active</status>
                        <team>alpha</team>
                        <llogin>0000-00-00 00:00:00</llogin>
                        <lcount>0</lcount>
                        </user>
                        <user>
                        <uname>user2</uname>
                        <level>6</level>
                        <status>active</status>
                        <team>alpha</team>
                        <llogin>2007-03-26 11:31:53</llogin>
                        <lcount>128</lcount>
                        </user>
                        <user>
                        <uname>user3</uname>
                        <level>1</level>
                        <status>active</status>
                        <team>bravo</team>
                        <llogin>2006-02-17 20:08:23</llogin>
                        <lcount>3</lcount>
                        </user>
                        <group>
                        <teamname>alpha</teamname>
                        <teamlead>user2</teamlead>
                        <teamstatus>active</teamstatus>
                        </group>
                        <group>
                        <teamname>bravo</teamname>
                        <teamlead>user3</teamlead>
                        <teamstatus>active</teamstatus>
                        </group>
                        <statusops>
                        <status>active</status>
                        </statusops>
                        <statusops>
                        <status>inactive</status>
                        </statusops>
                        </allusers>

                        And here is a more detailed view of the user editing panel. Again, I always want the comboboxes to display the data returned from the httpservice call. But I want to change the value when the user is selected.

                        <mx:Panel width="250" height="315" left="5" layout="absolute" title="User Details">
                        <mx:HBox x="10" y="27" width="210">
                        <mx:Label text="Username" width="65"/>
                        <mx:TextInput id="adm_username" width="137" text="{dgUserDetails.selectedItem.uname}"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="55" width="210">
                        <mx:Label text="Group" width="65"/>
                        <mx:ComboBox id="adm_usergroup" width="137" dataProvider="{getUsers.lastResult.allusers.group}" labelField="teamname"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="83" width="210">
                        <mx:Label text="Level" width="65"/>
                        <mx:TextInput id="adm_level" width="137" maxChars="1" text="{dgUserDetails.selectedItem.level}"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="111" width="210">
                        <mx:Label text="Status" width="65"/>
                        <mx:ComboBox id="adm_activestatus" width="137" dataProvider="{getUsers.lastResult.allusers.statusops}" labelField="status"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="137" width="210">
                        <mx:Label text="Password" width="65"/>
                        <mx:TextInput id="adm_password" width="137" enabled="true" backgroundDisabledColor="#C0C0C0" displayAsPassword="true" change="adm_chkusr(adm_password)"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="165" width="210">
                        <mx:Label text="Confirm" width="65"/>
                        <mx:TextInput id="adm_confirm" width="137" enabled="false" backgroundDisabledColor="#C0C0C0" displayAsPassword="true" change="adm_chkusr(adm_confirm)"/>
                        </mx:HBox>
                        <mx:HBox x="10" y="205" width="210">
                        <mx:HBox width="50%">
                        <mx:LinkButton id="adm_clruser" label="Clear" click="clearviewUser()"/>
                        </mx:HBox>
                        <mx:HBox width="50%">
                        <mx:LinkButton id="adm_moduser" label="Modify User" enabled="false"/>
                        </mx:HBox>
                        </mx:HBox>
                        <mx:HBox x="10" y="233" width="210">
                        <mx:HBox width="50%">
                        <mx:LinkButton id="adm_deluser" label="Delete User" enabled="false"/>
                        </mx:HBox>
                        <mx:HBox width="50%">
                        <mx:LinkButton id="adm_adduser" label="Add User" enabled="false"/>
                        </mx:HBox>
                        </mx:HBox>
                        </mx:Panel>

                        Thanks again for your time. I look forward to your response as this is driving me crazy.

                        Regards,
                        Chris
                        • 9. Set Combobox value based on Datagrid selectedItem
                          csawall Level 1
                          Ok. I have the answer. Assuming that comboboxes are already pre-populated via a httpservice call, but you want to change the selectedIndex based on a selected item in a datagrid, this is the AS code I finally came up with. Thanks Tracy for the responses and some code to base my work on.

                          [Bindable]private var _xmlUserAdmin:XML;
                          private function test(oEvent:ResultEvent):void {
                          _xmlUserAdmin = XML(oEvent.result); // used to populate the datagrid
                          //(see my previous post, but change out "myData")
                          trace(_xmlUserAdmin.toXMLString());
                          //mx.controls.Alert.show(_xmlUserAdmin);
                          }
                          private function onChangeUser(oEvent:Event):void {
                          var xmlUser:XML = XML(dgUserDetails.selectedItem); //the Users dataProvider item
                          for ( var i:Number=0; i<_xmlUserAdmin.group.length(); i++ ) { //loop over the items in the dataProvider
                          //get the current item.data value
                          var sDataValueCurGRP:String = _xmlUserAdmin.group .teamname.valueOf();
                          //compare desired value to current item.data value
                          if ( sDataValueCurGRP == xmlUser.team ) {
                          //set the seletedIndex of the combo box
                          adm_usergroup.selectedIndex = i;
                          }
                          }
                          for ( var j:Number=0; j<_xmlUserAdmin.statusops.length(); j++ ) {
                          var sDataValueCurSTS:String = _xmlUserAdmin.statusops[j].status.valueOf();
                          if ( sDataValueCurSTS == xmlUser.status ) {
                          adm_activestatus.selectedIndex = j;
                          }
                          }
                          }

                          Chris