10 Replies Latest reply on Aug 7, 2009 4:53 AM by ajdove

    Targeting a child viewState from another child viewState of same parent

    ajdove Level 1

      I have a similar issue of targeting a viewState, however, my issue is targeting second (or third or fourth) viewState of parentDocument from a different viewState of that same parent. So I have an application document which loads 5 different viewStates. Each viewState loads a module using <mx:moduleLoader>. If I am currently viewing viewState 1 (thereby using a loaded module) and want to call a separate viewState of the parent. How do I do this?

       

      I will show my example by loading code for the main application erp.mxml, and 2 separate modules called modAccountPayable.mxml and modWelcome.mxml.  If I load the application and click the HOME button which launches the modWelcome.mxml module I want to be able to click a button (or any other control for that matter) and target a new viewState "acctPay" from the parentDocument, which happens to load a new module modAccountPayable.mxml.

       

       

      <?xml version="1.0" encoding="utf-8"?>

      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationPolicy="all" layout="absolute" width="100%" height="100%" xmlns:p="com.erp.*">

      <mx:Script>

      <![CDATA[

      import mx.events.ItemClickEvent;

       

                  private function toggleButtonBar_itemClick(evt:ItemClickEvent):void {

                      currentState = evt.item.data;

       

                  }

      ]]>

      </mx:Script>

       

       

          <mx:Array id="dp">

              <mx:Object data="Welcome" label="Home" />

              <mx:Object data="CustomerManager" label="Customer Management" />

              <mx:Object data="VendorManager" label="Vendor Management" />

              <mx:Object data="OrderEntry" label="Order Entry" />

              <mx:Object data="AccountPayable" label="Acct Payables" />

              <mx:Object data="AccountReceivable" label="Acct Receivables" />

              <mx:Object data="Employees" label="Employees" />

          </mx:Array>

       

      <mx:states>

      <mx:State name="Help"/>

      <mx:State name="CustomerManager">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="custMgr" url="com/erp/modules/modCustomerMgr.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="AccountPayable">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="acctPay" url="com/erp/modules/modAccountPayable.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="AccountReceivable">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="acctRec" url="com/erp/modules/modAccountReceivable.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="OrderEntry">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="orderEntry" url="com/erp/modules/modOrderEntry.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="VendorManager">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="vendMgr" url="com/erp/modules/modVendorMgr.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="Employees">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="employee" url="com/erp/modules/modEmployees.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      <mx:State name="Welcome">

      <mx:AddChild relativeTo="{bodyBox}" position="lastChild">

      <mx:ModuleLoader id="welcome" url="com/erp/modules/modWelcome.swf" width="100%" height="100%"/>

      </mx:AddChild>

      </mx:State>

      </mx:states>

      <mx:Canvas x="0" y="108" width="100%" height="492" id="bodyBox">

      </mx:Canvas>

       

      <mx:ApplicationControlBar x="0" y="0" width="100%" height="100" dock="true">

      <mx:Canvas width="100%" height="100%" id="appCntrlBarCanvas">

       

       

      <mx:ToggleButtonBar id="toggleButtonBar"

                      dataProvider="{dp}"

                      itemClick="toggleButtonBar_itemClick(event);" />

       

      </mx:Canvas>

      </mx:ApplicationControlBar>

      </mx:Application>

       

       

       

      modWelcome.mxml

      <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">

      <mx:Button x="166" y="179" label="Button" click="='acctPay'"/>

       

      </mx:Module>

       

       

      modAccountPayable.mxml

       

      <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%">

      <mx:Button x="167" y="139" label="Click me "/>

       

      </mx:Module>

       

      In the image below, you will see the main application  with the HOME button already clicked which loaded the modWelcome.mxml module. I want to be able to click the button from this viewState and/or this module and traverse back to the parentDocument and then to a different viewState "acctPay". I currently am getting an error as an undefined State 'acctPay'.

      ScreenHunter_0698.jpg
        • 1. Re: Targeting a child viewState from another child viewState of same parent
          ajdove Level 1

          My goal is to create an ERP application for a customer so they can enter new customers, search records, send invoices, manage data, etc. I have started by creating a modular application which is loaded/unloaded using viewStates from a parent control panel. I don't know which method is best, such as using viewStack, or tabbed navigation, etc. so any guidance on this too will be helpful.

           

          Is there a way to declare onClick event to perform all linking relative to the parentDocument? So no matter when I am in the application when I click on a button and I am leaving the current view or current module to jump to the root of the application and then navigate to the requested view or module?

           

          For instance, here is my test example outline:

           

          • Application
            • view A
              • module vma1
                • view vmva1
                • view vmva2
            • view B
            • view C
              • module vmc1
            • view D
              • module vmd1
                • view vmvd1
                • view vmvd2
                • view vmvd3

           

          If I am located at "view vmva1" which is "view A - module vma1 - view vmva1" and I want to click a button and goto "view vmvd2" which is off the parent application inside "view D - module vmd1 - view vmvd2". How would I do this?

           

          My thoughts would be to use onClick="parentDocument.currentState = 'vmvd2'";

           

          So I would call the "parentDocument" and then call the currentState of "vmvd2" but this gets an error saying it cannot locate the 'vmvd2' state because the reference path is wrong. it  still thinks I am inside the "view A" state. Thats my thought. So what is the correct syntax?

           

          Thanks

          Alex

          • 2. Re: Targeting a child viewState from another child viewState of same parent
            ajdove Level 1

            I found this article enterState event does not fire when switching to a parent view-state from a derivative view-state. located at URL https://bugs.adobe.com/jira/browse/SDK-15223 which looks enticing, but I cannot determine a solution from it. Is there a solution in this which I am not seeing? If so, or if someone can look at it and derrive an answer I would be so happy.

             

            Thanks again in advance.

            Alex

            • 3. Re: Targeting a child viewState from another child viewState of same parent
              Gregory Lafrance Level 6

              View states should be used for simple components. You should be using a ViewStack for this.

               

              These links will help:

               

              http://livedocs.adobe.com/flex/3/html/help.html?content=navigators_3.html

               

              http://livedocs.adobe.com/flex/3/langref/mx/containers/ViewStack.html

               

              http://learn.adobe.com/wiki/display/Flex/ViewStack

               

              If this post answers your question or helps, please mark it as such.

              1 person found this helpful
              • 4. Re: Targeting a child viewState from another child viewState of same parent
                ajdove Level 1

                Ok. Great advice...but I still have a problem.

                 

                I have created a Tabbed Navigation (which is based off the viewStack) as follows:

                Here is my main application

                 

                <mx:Application

                 

                xmlns:mx="http://www.adobe.com/2006/mxml"

                backgroundColor="

                #FFFFFF"

                backgroundAlpha="

                0"

                layout="

                absolute"

                width="

                100%"

                height="

                100%"

                xmlns:archive="

                com.erp.files.*">

                <mx:Panel width="760" height="600"

                      headerColors="[#000000,#FFFFFF]" horizontalCenter="-12" verticalCenter="0">

                 

                        <mx:TabNavigator id="vs1"

                            selectedIndex="0"

                            historyManagementEnabled="false"

                            width="100%" height="100%">

                 

                            <mx:Form label="Welcome" width="760" height="600" id="vs1a">

                                <mx:FormItem label="Acme Widget 1.0">

                                    <mx:NumericStepper value="1" />

                                    <mx:Button label="Add to Cart"

                                        click="vs1.selectedIndex=1" />

                                </mx:FormItem>

                            </mx:Form>

                 

                            <mx:Form label="Employee Mgnt" width="760" height="600" id="vs1b">

                                <mx:FormItem label="Name on Credit Card">

                                    <mx:ModuleLoader url="com/erp/files/modules/employee/modMgrEmployee.swf" />

                                </mx:FormItem>

                            </mx:Form>

                     </mx:TabNavigator>

                </mx:Panel>

                </mx:Application>

                 

                Here is my module which is loaded into a tabbed view above. My goal is to load a module into the application canvas/tabbed view and then dynamically connect to other tabs or views above via bubbling. My example below is a module, which is loaded in the above application, I have a button with a label="vs1 selectedindex 2". I want to use the click event of the button to open the parent application or tabbed view and go directly to selectedindex 2 (which should be the 3rd tab). When I use the click event click="vs1.selectedindex=2" I receive an error stating Flex does not know the variable "vs1" so the nested child is not communicating with the parent. 

                 

                Is there a way to place a listener in the main application to allow all events gain access to the parent states?

                 

                <mx:Module xmlns:mx="http://www.adobe.com/2006/mxml" layout="absolute" width="100%" height="100%" x="0" y="0">

                      <mx:Canvas x="0" y="0" width="100%" height="100%">

                            <mx:HBox x="0" y="0" width="100%" height="100%">

                                  <mx:TabNavigator width="100%" height="100%">

                                        <mx:Canvas label="Search" width="100%" height="100%" id="memSearch">

                                        <mx:Button label="vs1 selectedindex 2"/>

                                        </mx:Canvas>

                                        <mx:Canvas  label="Directory" width="100%" height="100%" id="memDirectory">

                                              <mx:ModuleLoader id="empDir" url="/com/erp/modules/modEmployee.swf" />

                                        </mx:Canvas>

                                        <mx:Canvas  label="New" width="100%" height="100%" id="memNew">                    

                                        </mx:Canvas>

                                        <mx:Canvas  label="Edit" width="100%" height="100%" id="memEdit">

                                             

                                        </mx:Canvas>

                                  </mx:TabNavigator>

                                 

                            </mx:HBox>

                      </mx:Canvas>

                     

                </mx:Module>

                 

                 

                 

                 

                 

                 

                • 5. Re: Targeting a child viewState from another child viewState of same parent
                  Gregory Lafrance Level 6

                  You might try adding the event listener to systemManager:

                   

                  systemManager.addEventListener(....

                   

                  I know that solves problems with popups and events.

                   

                  If this post answered your question or helped, please mark it as such.

                  1 person found this helpful
                  • 6. Re: Targeting a child viewState from another child viewState of same parent
                    ajdove Level 1

                    Greg,

                     

                    Thanks for your last comments, they proved useful, however, a new but related problem is I am getting a "1120: Access of undefined property moduleContainer" and I do not understand why?  I have attached my Application file and the module I am loading using <mx:moduleLoader url="" /> and also I have added a .jpg image of my tree structure of the Flex project.  I am trying to use the Module class and the IModuleContainer class to dynamically reference child modules.  When I load these child modules into the main Application through the <mx:moduleLoader /> tag I receive an error, but when I load the code directly into the Applicaiton without using the <mx:moduleLoader /> it works. What's wrong? I assume it is a listener issue or an import of a class, but what? Can you or anyone else help?

                     

                    Thank you

                    Alex Dove

                    • 7. Re: Targeting a child viewState from another child viewState of same parent
                      Gregory Lafrance Level 6

                      If this post answered your question or helped, please mark it as such.

                       

                      This LiveDoc page may help:

                       

                      http://livedocs.adobe.com/flex/3/html/help.html?content=modular_5.html

                       

                      This sample code from the page seems to indicate you need to add a "ready" event listener for the module:

                       

                      <?xml version="1.0"?>
                      <!-- modules/ModuleLoaderApp.mxml -->
                      <mx:Application xmlns:mx="http://www.adobe.com/2006/mxml" creationComplete="initApp()">
                          <mx:Script>
                              <![CDATA[
                              import mx.events.ModuleEvent;
                              import mx.modules.ModuleManager;
                              import mx.modules.IModuleInfo;

                       

                              public var info:IModuleInfo;
                             
                              private function initApp():void {
                                  info = ModuleManager.getModule("ColumnChartModule.swf");
                                  info.addEventListener(ModuleEvent.READY, modEventHandler);         

                       

                                  // Load the module into memory. Calling load() makes the
                                  // IFlexModuleFactory available. You can then get an
                                  // instance of the class using the factory's create()
                                  // method.
                                  info.load();
                              }
                             
                              private function modEventHandler(e:ModuleEvent):void {
                                  // Add an instance of the module's class to the
                                  // display list.
                                  vb1.addChild(info.factory.create() as ColumnChartModule);
                              }
                              ]]>
                          </mx:Script>

                       

                          <mx:VBox id="vb1"/>

                       

                      </mx:Application>

                      • 8. Re: Targeting a child viewState from another child viewState of same parent
                        ajdove Level 1

                        Unfortunately, I still cannot get this piece to work. Uggh.

                        • 9. Re: Targeting a child viewState from another child viewState of same parent
                          Gregory Lafrance Level 6

                          Have you tried these:

                           

                          click="mx.core.Application.application.vs1.selectedindex=2"

                          click="parentApplication.vs1.selectedindex=2"

                          click="parentDocument.vs1.selectedindex=2"

                           

                          If this post answered your question or helped, please mark it as such.

                          • 10. Re: Targeting a child viewState from another child viewState of same parent
                            ajdove Level 1

                            That's it!  Thank you. I understand better now that the issue I was having was a multi-faceted issue with multiple mistakes. Primarily, your suggestion led me to the other corrections of the app to locate the id name of the targeted destination.  Let me explain with some code examples below:

                             

                            My application contains 3 main sections which include the main application file "ModuleLoader", a module for a splash page "welcome1", and a sales page "modSalesMain".

                             

                            The body section on my application file ModuleLoader.mxml loads actionscript calling the canvas container id called "moduleContainer" and then uses a ModuleManager with a READY ModuleEvent to listen to events.  The main canvas contains a TabNavigator called "tnbase" containing individualized tabs with embedded ViewStack containers inside each tab canvas.

                             

                            <mx:Script>

                            .

                            .

                            .

                             

                            //start loading the module

                                        private function loadModule():void {

                                            /*btnLoad.enabled = false;*/

                             

                                            //create and setup loading progress bar

                                            pb = new ProgressBar();

                                            pb.labelPlacement = "center";

                                            pb.label = "Loading %3 %";

                                            progressContainer = new Box();

                                            progressContainer.percentWidth = 100;

                                            progressContainer.percentHeight = 100;

                                            progressContainer.setStyle("horizontalAlign", "center");

                                            progressContainer.setStyle("verticalAlign", "middle");

                                            progressContainer.addChild(pb);

                             

                                            moduleContainer.addChild(progressContainer);

                             

                                            //load the module

                                            var moduleURL:String = "com/files/mods/welcome/welcome1.swf";     

                                      info = ModuleManager.getModule(moduleURL);

                                      if (info != null) {

                                      info.addEventListener(ModuleEvent.READY, modEventHandler);

                                      info.addEventListener(ModuleEvent.ERROR, modErrorHandler);

                                      pb.source = info;

                                      info.load();

                                      }

                                        }

                             

                            .

                            .

                            .

                            </mx:Script>

                             

                            <mx:Canvas id="moduleContainer" width="100%" height="100%" >

                                    <mx:TabNavigator id="tnbase" width="100%" height="100%" x="0" y="10" selectedIndex="0">

                                        <mx:Canvas label="Welcome" width="100%" height="100%">

                                            <mx:ModuleLoader url="com/files/mods/welcome/welcome1.swf" width="100%" height="100%" />

                                        </mx:Canvas>

                                        <mx:Canvas label="Sales" width="100%" height="100%">

                                        <mx:ViewStack borderStyle="solid" width="100%" height="100%" id="vsSales">

                                         <mx:Canvas id="salesMainCanvas" width="100%" height="100%">

                            <mx:ModuleLoader url="com/files/mods/sales/modSalesMain.swf" width="100%" height="100%" />

                                         </mx:Canvas>

                                         </mx:ViewStack>

                                        </mx:Canvas>

                            .

                            .

                            .

                             

                            The welcome1.mxml page body section contains a series of buttons inside a grid.  This button has a click event which calls the root application and looks for the tnbase id and then the selectedIndex value. The application is looking for a container which has a selectedIndex value. The ViewStack container is a container which does have this selectedIndex property which is why we are using it. 

                             

                            <mx:Canvas verticalCenter="3" horizontalCenter="0">

                            <mx:HBox width="100%" horizontalAlign="left" height="100%">

                                    <mx:Grid id="welcomeBtnPack">

                                                <mx:GridRow width="100%" height="100%">

                                                    <mx:GridItem width="100%" height="100%">

                                                        <mx:Button label="Sales" width="100" height="150" click="mx.core.Application.application.tnbase.selectedIndex=1" />

                                                    </mx:GridItem>

                            .

                            .

                            .

                             

                            The modSalesMain.mxml module is the destination file in this example and contains no substantial info. All the relevant code for the solution exists in the two files above, ModuleLoader.mxml and welcome1.mxml