2 Replies Latest reply on Mar 11, 2010 1:14 PM by stickamw

    Accessing inputs of multiples instances of same module via ModuleMgr == frustration

    stickamw

      Hi guys,

       

           Have a fun one here...really getting aggrivating...my code is after my message...

       

           I have a requirement to have a dynamic form that allows users to quasi-build a query.  The user chooses a "field" from a combo and depending on what they select, I display the appropriate input fields for them.  From there, they can hit the little "+" sign to add another row with another search criteria.  Once they have all the search criteria they want, they clicky the button and off it goes...

       

           Or at least that's how it's supposed to work....

       

           So my solution for this was to create a module with one instance of the possible search row.  It has the combobox and dynamically builds the inputs according to what's selected on the combo.  The module is first loaded by the parentApp via a public "load" function.  From there, whenever the user hits the "+" sign, which is in the module itself, I simply call the parentApp.load function to add another instance of the module for the next row of criteria.

       

           This works dandy....with the exception of the placement of the new instance...instead of stacking directly below the first, the new instance goes to the middle and spaces....

       

           But the hard part that I've just not been able to get around is this:  when it comes time to put the search criteria together to fire off to my remote object, I can't figure out how to get all the data values from the modules. I've spent a day reading posts and trying everything that I've found and can think of and I cannot even find the instances of the modules to access, much less get the values for the inputs.

       

           So, three questions here:

       

           1.)  How do I get the loaded modules to stack vertically one below the next without the extra space?

           2.)  How do I reference the loaded modules

           3.)  How do I reference the controls within each module so I can pull the data that the user has entered?

       

           Any help on this would be greatly appreciated....and even suggestions (& examples!) of better ways to do this are more than welcome.

       

      Thanks in advance,

      Adrian

       

      First, the parent application (moduleTester.mxml):

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" initialize="loadModules()" >
         
          <mx:Script>
              <![CDATA[
                  import mx.modules.Module;
                  import mx.modules.IModuleInfo;
                  import mx.events.ModuleEvent;
                  import mx.modules.ModuleManager;
                 
                  private var moduleInfo:IModuleInfo = ModuleManager.getModule('apps/modules/DynamicSearchBox.swf');
                 
                  private function loadModules():void
                  {
                      moduleInfo.addEventListener(ModuleEvent.READY, onModuleReady);
                     
                      moduleInfo.load();
                  }
                 
                  private function onModuleReady(event:ModuleEvent):void
                  {
                      addChildModule();
                  }
                 
                  public function addChildModule():void
                  {
                      moduleVBox.addChild(moduleInfo.factory.create() as DisplayObject);
                  }
                 
                  public function removeChildModule(module:Module):void
                  {
                      moduleVBox.removeChild(module);
                  }
                 
                  private function searchButtonClick():void
                  {
                      //parse thru all instances of the loaded modules, get the criteria for each module and send the parameters to the remote object
                  }
                 
              ]]>
          </mx:Script>
         
          <mx:Panel title="Module Tester" width="75%" height="75%">
              <mx:VBox id="moduleVBox" height="100%" width="100%">

       

              </mx:VBox>   
              <mx:HBox horizontalAlign="center" width="100%">
                  <mx:Button id="searchButton" label="Search!" click="searchButtonClick()"/>
              </mx:HBox>
          </mx:Panel>

       

      </mx:Application>

       

      And then the module code (DynamicSearchBox.mxml):

       

       

      <?xml version="1.0" encoding="utf-8"?>
      <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">
         
          <mx:Script>
              <![CDATA[
                  import mx.controls.Text;
                  import mx.controls.DateField;
                  import mx.controls.TextInput;

       

                  [Bindable] private var criteriaComboOptions:Array=['Please Select...', 'Location','Day','Date Range','IP','IP Range'];                          

       

                  private function criteriaChange():void
                  {           
                      searchBox.removeAllChildren();
                     
                      switch (criteriaCombo.selectedItem)
                      {
                          case "Location":
                              addLocationFields();
                              operatorLabel.text = " = ";
                              break;
                             
                          case "Day":
                              addStartDateFields();
                              operatorLabel.text = " = ";
                              break;
                             
                          case "Date Range":
                              addStartDateFields();
                              addEndDateFields();
                              operatorLabel.text = " between ";
                              break;
                             
                          case "IP":
                              addFromIPFields();
                              operatorLabel.text = " = ";
                              break;
                             
                          case "IP Range":
                              addFromIPFields();
                              addToIPFields();                                               
                              operatorLabel.text = " between ";
                              break;
                             
                          default:
                              break;                                                                                                                                                            
                      }
                  }   
                 
                  private function addLocationFields():void
                  {
                      var locationInput:TextInput = new TextInput;
                      locationInput.id = "locationInput";
                      locationInput.width = 150;
                      locationInput.visible = true;
                      searchBox.addChild(locationInput);
                  }
                 
                  private function addStartDateFields():void
                  {
                      var startDateInput:DateField = new DateField;
                      startDateInput.id = "startDateInput";
                      startDateInput.width = 150;
                      startDateInput.visible = true;
                      searchBox.addChild(startDateInput);
                  }
                 
                  private function addEndDateFields():void
                  {
                      var toLabel:Label = new Label;
                      toLabel.text = "  and  ";
                      searchBox.addChild(toLabel);
                                     
                      var endDateInput:DateField = new DateField;
                      endDateInput.id = "endDateInput";
                      endDateInput.width = 150;
                      endDateInput.visible = true;
                      searchBox.addChild(endDateInput);
                  }
                 
                  private function addFromIPFields():void
                  {
                      for (var i:int = 0; i < 4; i++)
                      {
                          var newOctet:TextInput = new TextInput;
                          newOctet.id = "fromOctet" + i.toString();
                          newOctet.width = 35;
                          newOctet.maxChars = 3;
                          newOctet.visible = true;
                         
                          searchBox.addChild(newOctet);
                      }
                  }
                             
                  private function addToIPFields():void
                  {
                      var toLabel:Label = new Label;
                      toLabel.text = "  and  ";
                      searchBox.addChild(toLabel);
                     
                      for (var i:int = 0; i < 4; i++)
                      {
                          var newOctet:TextInput = new TextInput;
                          newOctet.id = "toOctet" + i.toString();
                          newOctet.width = 35;
                          newOctet.maxChars = 3;
                          newOctet.visible = true;
                         
                          searchBox.addChild(newOctet);
                      }
                  }
                 
                  private function addActions():void
                  {
                      var addLabel:Label = new Label;
                      addLabel.text = "+";
                  }

       

                  private function addChildModule():void
                  {
                      parentApplication.addChildModule();
                  }       
                 
                  private function removeChildModule():void
                  {
                      parentApplication.removeChildModule(this);
                  }
                         
              ]]>
          </mx:Script>
         
          <mx:HBox width="100%">
              <mx:ComboBox id="criteriaCombo" dataProvider="{criteriaComboOptions}" change="criteriaChange()"></mx:ComboBox>
              <mx:Label id="operatorLabel" text="  =  "/>
              <mx:HBox id="searchBox"/>
              <mx:Spacer width="20"/>
              <mx:Label id="addModule" text="+" click="addChildModule()" fontSize="14"/>
              <mx:Label text=" / "    />
              <mx:Label id="removeModule" text="-" click="removeChildModule()" fontSize="14" />
          </mx:HBox>
      </mx:Module>

        • 1. Re: Accessing inputs of multiples instances of same module via ModuleMgr == frustration
          Darrell Loverin Level 4

          1. Remove the "height="100%" attribute from the Module element.

          2. All the modules are all children of the same parent, modueVBox. Seems like could loop over the children of moduleVBox and you would have all the modules.

          3. You could add a public function on the module to return the search criteria for its set of controls. You already gave each control an id. You could loop over the children of seachBox and retrieve the input from each control.

           

           

          -Darrell

          1 person found this helpful
          • 2. Re: Accessing inputs of multiples instances of same module via ModuleMgr == frustration
            stickamw Level 1

            Hi Darrell,

             

                 Thanks for taking the time to help with this....

             

                 1.)  Perfect!  That takes care of the spacing.

             

                 2.)  I thought the same thing, but there isn't a children property on the moduleVBox...

             

                 But now as I was writing this, it hit me that I can call the .getChildren() method on the VBox and THEN cycle thru the array of children to get to the specific data fields that I need....now, when they hit the search button, I simply call the searchButtonClick() function in the parent and after a couple of .getChildren() calls, I have the fields.  WOOT!

             

                 And that does the trick...thanks for nudging my brain to remember the backside functions there....

             

            Best,

            Adrian