5 Replies Latest reply on Oct 27, 2009 1:55 PM by Flex harUI

    combobox cascade selection

    jKnistrum

      Hi,

       

      I'm doing my first attempt with FB4 and I'm stucked with this simple test below, I'm just trying to set one combobox contents on selections made on other one.

       

      I'm using PHP, the classes are very simple, well tested and the services return what is expected when I test them inside FB4.

       

      the problem is that only the first value returned is applyed to the secondo combo, all other values remain from the first selection I did.

       

      The second combox only updates its contents to the new when I click on it.

       

      Thanks for any ideas ....

       

       

      <?xml version="1.0" encoding="utf-8"?>
      <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                     xmlns:s="library://ns.adobe.com/flex/spark"
                     xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024"
                     minHeight="768" xmlns:countries="services.countries.*"
                     xmlns:statescountry="services.statescountry.*">
          <fx:Script>
              <![CDATA[
                  import mx.events.ListEvent;
                  import mx.events.FlexEvent;
                  import mx.controls.Alert;

       

                  protected function comboBox_creationCompleteHandler(event:FlexEvent):void
                  {
                      getDataResult.token = countries.getData();
                  }

       


                  protected function comboBox2_creationCompleteHandler(event:FlexEvent):void
                  {
                      getDataResult2.token = statesCountry.getData();
                  }

       


                  protected function comboBox_changeHandler(event:ListEvent):void
                  {
                     
                      getDataResult2.token = statesCountry.getDataC(comboBox.selectedItem.ID);
                                     
                     
                  }

       


              ]]>
          </fx:Script>
          <fx:Declarations>
              <s:CallResponder id="getDataResult"/>
              <countries:Countries id="countries"
                                   fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                                   showBusyCursor="true"/>
             
              <s:CallResponder id="getDataCResult"/>
              <statescountry:StatesCountry id="statesCountry"
                                           fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                                           showBusyCursor="true"/>
             
              <s:CallResponder id="getDataResult2"/>
              <!-- Place non-visual elements (e.g., services, value objects) here -->
          </fx:Declarations>
         
          <mx:ComboBox x="108" y="66" editable="true" id="comboBox"
                       creationComplete="comboBox_creationCompleteHandler(event)"
                       dataProvider="{getDataResult.lastResult}"
                       labelField="PrintableNameEN"
                       change="comboBox_changeHandler(event)"></mx:ComboBox>
         
          <mx:ComboBox x="108" y="163" editable="true" id="comboBox2"
                      
                       dataProvider="{getDataResult2.lastResult}"
                       labelField="Name"
                       creationComplete="comboBox2_creationCompleteHandler(event)"
                       >
             
          </mx:ComboBox>

       

      </s:Application>

        • 1. Re: combobox cascade selection
          Peter deHaan Level 4

          @jKnistrum,

           

          I believe you're running in to http://bugs.adobe.com/jira/browse/SDK-23838 (mentioned earlier in the forums also -- http://forums.adobe.com/message/2141489). You could probably work around it by using a Spark DropDownList (s:DropDownList) instead of the Halo/MX ComboBox (mx:ComboBox), or there is also a workaround in the previous bug that you could try.

           

          Peter

          • 2. Re: combobox cascade selection
            jKnistrum Level 1

            I'm not sure if it is the same problem.

             

            There the workaround was to reset the dataProvider and the set it twice to the combobox itself and to its dropdown

             

            <?xml version="1.0" encoding="utf-8"?> 
            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009
                            xmlns:s="library://ns.adobe.com/flex/spark
                            xmlns:mx="library://ns.adobe.com/flex/halo"> 

                 <fx:Script><![CDATA[
                     import mx.core.UIComponentGlobals;
                     import mx.core.mx_internal;
                     use namespace mx_internal;
                     
                     private function doit():void
                     {
                     cb.dataProvider = [ "Alex", "Peter", "Gordon", "Deepa" ];
                     }
                     
                 ]]></fx:Script>
                 
                 <mx:VBox>
                     <mx:Label text="{VERSION}" />
                     <mx:Button label="change dp" click="doit()" />
                     <mx:Button label="change dp workaround" click="doit(); cb.dropdown.dataProvider = cb.dataProvider" />
                     
                     <mx:ComboBox id="cb" dataProvider="['Steve', 'Joan', 'Lauren', 'Jason' ]" />
                 </mx:VBox>

            </s:Application>

             

             

             

            I've tried something similar ( if I understood it right ) and the problem remains.

             

             

             

            <?xml version="1.0" encoding="utf-8"?>
            <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                           xmlns:s="library://ns.adobe.com/flex/spark"
                           xmlns:mx="library://ns.adobe.com/flex/halo" minWidth="1024"
                           minHeight="768" xmlns:countries="services.countries.*"
                           xmlns:statescountry="services.statescountry.*">
                <fx:Script>
                    <![CDATA[
                        import mx.events.ListEvent;
                        import mx.events.FlexEvent;
                        import mx.controls.Alert;

             

                        protected function comboBox_creationCompleteHandler(event:FlexEvent):void
                        {
                            getDataResult.token = countries.getData();
                        }

             


                        protected function comboBox2_creationCompleteHandler(event:FlexEvent):void
                        {
                            getDataResult2.token = statesCountry.getData();
                        }

             


                        protected function comboBox_changeHandler(event:ListEvent):void
                        {
                            comboBox2.dataProvider = getDataResult2.lastResult;
                           
                            getDataResult2.token = statesCountry.getDataC(comboBox.selectedItem.ID);
                                   
                        }

             


                    ]]>
                </fx:Script>
                <fx:Declarations>
                    <s:CallResponder id="getDataResult"/>
                    <countries:Countries id="countries"
                                         fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                                         showBusyCursor="true"/>
                   
                    <s:CallResponder id="getDataCResult"/>
                    <statescountry:StatesCountry id="statesCountry"
                                                 fault="Alert.show(event.fault.faultString + '\n' + event.fault.faultDetail)"
                                                 showBusyCursor="true"/>
                   
                    <s:CallResponder id="getDataResult2"/>
                    <!-- Place non-visual elements (e.g., services, value objects) here -->
                </fx:Declarations>
               
                <mx:ComboBox x="108" y="66" editable="true" id="comboBox"
                             creationComplete="comboBox_creationCompleteHandler(event)"
                             dataProvider="{getDataResult.lastResult}"
                             labelField="PrintableNameEN"
                             change="comboBox_changeHandler(event);comboBox2.dropdown.dataProvider = comboBox2.dataProvider;"></mx:ComboBox>
               
                <mx:ComboBox x="108" y="163" editable="true" id="comboBox2"
                            
                             dataProvider="{getDataResult2.lastResult}"
                             labelField="Name"
                             creationComplete="comboBox2_creationCompleteHandler(event)"
                             >
                   
                </mx:ComboBox>

             

            </s:Application>

            • 3. Re: combobox cascade selection
              Peter deHaan Level 4

              I'm not 100% certain they are the same issue, but they do sound pretty similar. It's a bit tricky to debug since you're using bindings and web services.

               

              Try something like this. It sets up a "collectionChange" event listener which gets dispatched when the Halo/MX ComboBox control's data provider changes. If that works, I believe it is the same issue as the other bug.

              If it DOESNT work, try switching to a Spark DropDownList instead of a Halo ComboBox and see if that solves the problem.

               

              <?xml version="1.0" encoding="utf-8"?>
              <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                             xmlns:s="library://ns.adobe.com/flex/spark"
                             xmlns:mx="library://ns.adobe.com/flex/halo">
                  <fx:Script>
                      <![CDATA[
                          private function init():void {
                              cb.addEventListener('collectionChange', cb_collectionChange);
                          }
                          protected function cb_collectionChange(evt:Event):void {
                              cb.dropdown.dataProvider = cb.dataProvider;
                          }
                      ]]>
                  </fx:Script>
                  <s:VGroup left="20" top="20">
                      <s:Button click="cb.dataProvider = ['Five (New)', 'Six (New)', 'Seven (New)', 'Eight (New)'];" />
                      <mx:ComboBox id="cb" dataProvider="[One (old),Two (old),Three (old),Four (old)]" initialize="init();" />
                  </s:VGroup>
              </s:Application>
              

               

              Peter

              • 4. Re: combobox cascade selection
                mewk Level 3

                The following is working fine for me:

                CREATE SCHEMA IF NOT EXISTS `Geo` DEFAULT CHARACTER SET latin1 COLLATE latin1_swedish_ci ;
                USE `Geo`;
                
                -- -----------------------------------------------------
                -- Table `Geo`.`countries`
                -- -----------------------------------------------------
                DROP TABLE IF EXISTS `Geo`.`countries` ;
                
                CREATE  TABLE IF NOT EXISTS `Geo`.`countries` (
                  `country_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
                  `country` VARCHAR(45) NOT NULL ,
                  PRIMARY KEY (`country_id`) )
                ENGINE = InnoDB;
                
                
                -- -----------------------------------------------------
                -- Table `Geo`.`states`
                -- -----------------------------------------------------
                DROP TABLE IF EXISTS `Geo`.`states` ;
                
                CREATE  TABLE IF NOT EXISTS `Geo`.`states` (
                  `state_id` INT UNSIGNED NOT NULL AUTO_INCREMENT ,
                  `country_id` INT UNSIGNED NOT NULL ,
                  `state` VARCHAR(45) NOT NULL ,
                  PRIMARY KEY (`state_id`) ,
                  INDEX `states_fk1` (`country_id` ASC) ,
                  CONSTRAINT `states_fk1`
                    FOREIGN KEY (`country_id` )
                    REFERENCES `Geo`.`countries` (`country_id` )
                    ON DELETE CASCADE
                    ON UPDATE CASCADE)
                ENGINE = InnoDB;
                

                INSERT INTO countries (country) VALUES ('United States');
                INSERT INTO countries (country) VALUES ('Canada');
                INSERT INTO countries (country) VALUES ('Mexico');
                
                INSERT INTO states (country_id, state) VALUES (1, 'Alaska');
                INSERT INTO states (country_id, state) VALUES (1, 'California');
                INSERT INTO states (country_id, state) VALUES (1, 'Colorado');
                INSERT INTO states (country_id, state) VALUES (1, 'Florida');
                INSERT INTO states (country_id, state) VALUES (1, 'Hawaii');
                INSERT INTO states (country_id, state) VALUES (1, 'New Mexico');
                INSERT INTO states (country_id, state) VALUES (1, 'New York');
                INSERT INTO states (country_id, state) VALUES (1, 'Washington');
                
                INSERT INTO states (country_id, state) VALUES (2, 'British Columbia');
                INSERT INTO states (country_id, state) VALUES (2, 'Alberta');
                INSERT INTO states (country_id, state) VALUES (2, 'Saskatchewan');
                INSERT INTO states (country_id, state) VALUES (2, 'Manitoba');
                INSERT INTO states (country_id, state) VALUES (2, 'Ontario');
                INSERT INTO states (country_id, state) VALUES (2, 'Quebec');
                
                
                INSERT INTO states (country_id, state) VALUES (3, 'Californias');
                INSERT INTO states (country_id, state) VALUES (3, 'Texas');
                INSERT INTO states (country_id, state) VALUES (3, 'Nuevo Mexico');
                INSERT INTO states (country_id, state) VALUES (3, 'Sonora');
                INSERT INTO states (country_id, state) VALUES (3, 'Guadalajara');
                INSERT INTO states (country_id, state) VALUES (3, 'Oaxaca');
                

                <?php
                
                class GeoService {
                
                  var $username = "root";
                  var $password = "***********";
                  var $server = "localhost";
                  var $port = "3306";
                  var $databasename = "geo";
                
                  var $connection;
                
                  public function __construct() {
                    $this->connection = new mysqli(
                                              $this->server,
                                              $this->username,
                                              $this->password,
                                              $this->databasename
                                        );
                    }
                
                
                  public function getAllCountries() {
                    $q = "SELECT * FROM countries";
                    $r = $this->connection->query($q);
                    $countries = array();
                    while ($row = $r->fetch_assoc()) {
                     $countries[] = $row['country'];
                    }
                    return $countries;
                  }
                
                  public function getStatesByCountry($country) {
                    $q = "SELECT * FROM states INNER JOIN countries";
                    $q .= " ON states.country_id = countries.country_id";
                    $q .= " WHERE countries.country = '$country'";
                    $r = $this->connection->query($q);
                    $states = array();
                    while ($row = $r->fetch_assoc()) {
                     $states[] = $row['state'];
                    }
                    return $states;
                  }
                }
                
                ?>
                

                <?xml version="1.0" encoding="utf-8"?>
                <s:Application xmlns:fx="http://ns.adobe.com/mxml/2009"
                  xmlns:s="library://ns.adobe.com/flex/spark"
                  xmlns:mx="library://ns.adobe.com/flex/halo"
                  xmlns:geoservice="services.geoservice.*">
                  <fx:Script>
                    <![CDATA[
                      import mx.events.ListEvent;
                      import mx.events.FlexEvent;
                
                      protected function countryCB_creationCompleteHandler(event:FlexEvent):void {
                        getAllCountriesResult.token = geoService.getAllCountries();
                        getStatesByCountryResult.token = geoService.getStatesByCountry("United States");
                      }
                
                      protected function countryCB_changeHandler(event:ListEvent):void {
                        getStatesByCountryResult.token = geoService.getStatesByCountry(event.target.selectedItem);
                      }
                   ]]>
                  </fx:Script>
                  <fx:Declarations>
                    <s:CallResponder id="getAllCountriesResult"/>
                    <s:CallResponder id="getStatesByCountryResult"/>
                    <geoservice:GeoService id="geoService" showBusyCursor="true"/>
                  </fx:Declarations>
                
                  <s:HGroup gap="40" verticalCenter="0" horizontalCenter="0">
                    <mx:ComboBox id="countryCB" width="200"
                                 creationComplete="countryCB_creationCompleteHandler(event)"
                                 dataProvider="{getAllCountriesResult.lastResult}"
                                 change="countryCB_changeHandler(event)"/>
                    <mx:ComboBox id="statesCB" width="200"
                                 dataProvider="{getStatesByCountryResult.lastResult}"/>
                  </s:HGroup>
                
                </s:Application>
                

                 

                I also used your code almost exactly and the app still worked:

                <s:Application>
                  <fx:Script>
                    <![CDATA[
                      protected function comboBox_creationCompleteHandler(event:FlexEvent):void {
                        getDataResult.token = geoService.getAllCountries();
                      }
                
                      protected function comboBox2_creationCompleteHandler(event:FlexEvent):void {
                        getDataResult2.token = geoService.getStatesByCountry("United States");
                      }
                
                      protected function comboBox_changeHandler(event:ListEvent):void {
                        getDataResult2.token = getDataResult2.token = geoService.getStatesByCountry(comboBox.selectedItem as String);
                      }
                    ]]>
                  </fx:Script>
                  <fx:Declarations>
                    <s:CallResponder id="getDataResult"/>
                    <geoservice:GeoService id="geoService" showBusyCursor="true"/>
                    <s:CallResponder id="getDataResult2"/>
                  </fx:Declarations>
                
                  <mx:ComboBox x="108" y="66" editable="true" id="comboBox"
                               creationComplete="comboBox_creationCompleteHandler(event)"
                               dataProvider="{getDataResult.lastResult}"
                               labelField="PrintableNameEN"
                               change="comboBox_changeHandler(event)">
                  </mx:ComboBox>
                
                  <mx:ComboBox x="108" y="163" editable="true" id="comboBox2"
                               dataProvider="{getDataResult2.lastResult}"
                               labelField="Name"
                               creationComplete="comboBox2_creationCompleteHandler(event)">
                  </mx:ComboBox>
                
                </s:Application>
                

                 

                - e

                • 5. Re: combobox cascade selection
                  Flex harUI Adobe Employee

                  This is a problem in beta2 only, not beta1.  And for me, required a few twists and turns to get it to happen.

                   

                  I'm not sure the OP coded the right workaround.  The workaround for his set up would most likely involve getting a result event and setting the dropdown's dataProvider or watching for a change to the dataProvider binding.

                   

                  Alex Harui

                  Flex SDK Developer

                  Adobe Systems Inc.

                  Blog: http://blogs.adobe.com/aharui