13 Replies Latest reply on Sep 28, 2006 3:02 PM by mac_martine

    custom components -

    tophe1603
      Hi,
      I hope this isn't an obvious thing... but I have searched high & low for a decent reference to implementing Custom Components.
      It is not critical, but I would like to place a <mx:states> codeset into a custom component.
      Can anyone please suggest if and/or how this can be done?

      Does it matter that I am calling the new State from a VBox inside a TabNavigator?

      Also, while I'm here...
      I am switching Sates OK - sort of... I am getting the new state (a form) to switch into the upper region of my Tab VBox.
      BUT, I would like the form to actually REPLACE the datagrid which is the normal view upon clicking the Tab.

      Thanks in advance...
      Chris

        • 1. Re: custom components -
          mac_martine Level 1
          You can add states to components just as you would to MXML applications. What is the problem you're having?
          • 2. custom components -
            tophe1603 Level 1
            Thanks for the reply...
            Firstly, I have resolved the "replace" issue with: <mx:RemoveChild target="{jobTab_taskManager}"/> which is the ID of a VBox (inside the root VBOX) in the base Tab definition - and that works really nicely.

            However, I would like several of my Tab / Vbox elements to have "states" applied. So I thought it would be useful to have these alternative states in a custom component - just to keep my "job_dashboard" custom component clear of clutter.

            So I have tried to move my <states> to a custom component - inside a container thus:
            <mx:Container xmlns:mx="....adobe.com/2006/mxml">

            But now I generate an error in respect to <mx:AddChild relativeTo="{dgPanel_taskManager}" position="firstChild"> as "access to an undefined property dgPanel_taskManager".

            I'm guessing that maybe I have to prefix "dgPanel_taskManager" with something --- but I cannot figure out what !! I tried "job_dasboard.dgPanel_taskManager" but to no avail - where job_dashboard is a custom component holding the TabNavigator.

            My root component in the job_dashboard is a Canvas and I am not allowed to give that an ID.
            Where I call <mmComps:states_TaskMgr_addNew/>, can I pass a parameter - or some such?

            BTW, before I moved the <states> out to the custom component the states were switching as designed to do.

            I hope that's clear.
            • 3. Re: custom components -
              mac_martine Level 1
              I'm not exactly clear on what you're doing, but I'll try.

              If you are trying to addChild relative to an object in a custom component you would need to specify the component id. So, if it's within <mmComps:states_TaskMgr_addNew/>, you'd need to give that an id, like:
              <mmComps:states_TaskMgr_addNew id="mycomp"/>

              then your addChild might look more like:
              <mx:AddChild relativeTo="{myComp.dgPanel_taskManager}" position="firstChild">

              haven't tried this, but I think it should work.
              • 4. Re: custom components -
                tophe1603 Level 1
                Good get! that has pretty much nailed what i'm trying to do.

                I tried <mmComps:states_TaskMgr_addNew id="testComp"/>
                and then:
                <mx:AddChild relativeTo="{testComp.jobTab_taskManager}" position="firstChild">
                but now the error... "access of undefined property testComp"
                • 5. Re: custom components -
                  mac_martine Level 1
                  I'm assuming that your addChild tag is in the same file where you have <mmComps:states_TaskMgr_addNew id="testComp"/>, and NOT IN the states_TaskMgr_addNew component?

                  Assuming that is the case, it's very weird that it's not seeing that id.
                  Oh, is states_TaskMgr_addNew located in a TabNavigator or ViewStack? If so, this error could be happening because only components in the currently view Tab are visible/accessible unless you explicitely say otherwise.
                  • 6. custom components -
                    tophe1603 Level 1
                    quote:

                    Originally posted by: mac_martine
                    I'm assuming that your addChild tag is in the same file where you have <mmComps:states_TaskMgr_addNew id="testComp"/>, and NOT IN the states_TaskMgr_addNew component?



                    Sorry, not quite...
                    the addChild is integral to the states_TaskMgr_addNew component
                    Thiese are the first 7 lines of the states_TaskMgr_addNew component
                    quote:


                    <mx:Container xmlns:mx=".....adobe.com/2006/mxml">
                    <mx:states>
                    <mx:State name="tNav_TaskMgr_AddNew">
                    <mx:RemoveChild target="{testComp.vBox_taskManager}"/>
                    <mx:AddChild relativeTo="{testComp.jobTab_taskManager}" position="firstChild">
                    <mx:target>
                    <mx:Grid id="gridTaskMgr_adnew" width="100%" color="black" paddingTop="4" verticalAlign="top">



                    Re:
                    quote:

                    Oh, is states_TaskMgr_addNew located in a TabNavigator or ViewStack?

                    I'm using a TabNavigator .

                    Re:
                    quote:

                    only components in the currently view Tab are visible/accessible unless you explicitely say otherwise.

                    How do I "explicitely say otherwise" ? - just point me to some docs if it's easier...
                    I do appreciate your time here.
                    • 7. Re: custom components -
                      mac_martine Level 1
                      I'm getting the feeling you're trying to do something in an unusual way, and I'm not quite grasping what it is.
                      Is vBox_taskManager in states_TaskMgr_addNew or or in the application that includes states_TaskMgr_addNew?
                      Can you simplify your files to just what code is necessary for figuring this out and post those?
                      • 8. Re: custom components -
                        mac_martine Level 1
                        btw, to make all tabNavigator children accessible at all times, you would set creationPolicy="all"
                        • 9. custom components -
                          tophe1603 Level 1
                          quote:


                          Is vBox_taskManager in states_TaskMgr_addNew or or in the application that includes states_TaskMgr_addNew?

                          vBox_taskManager is the id of a VBox inside the base VBox of a Tab in a TabNavigator - the TabNav is in a custom component file called job_dashboard.mxml
                          job_dashboard.mxml carries the <mmComps:states_TaskMgr_addNew id="testComp"/> call wherein is the <states> definition for the alternate state to appear when a button is clicked on that Tab pane.

                          The first 7 lines of states_TaskMgr_addNew.mxml I posted earlier.

                          quote:

                          Can you simplify your files to just what code is necessary for figuring this out and post those?

                          I will try to map the current hierarchy as succinctly as possible...
                          1. I have a primary App file which (at the moment) calls just one custom component called job_dashboard thus:<mmComps:job_dashboard x="200" y="35" id="appMaster"/>

                          2. the first few lines of job_dashboard.mxml and the TabNavigator are as follows:
                          quote:


                          <mx:Canvas xmlns:mx="....adobe.com/2006/mxml" xmlns:mmComps="mmComponents.*"
                          width="845" height="786"
                          backgroundColor="#003399" fontFamily="verdana"
                          paddingTop="4" paddingBottom="4" paddingLeft="4" paddingRight="4">

                          <mmComps:states_TaskMgr_addNew id="testComp"/>

                          ... various stuff including a call to a custom comp for a form displaying "Job Status" according a the Job selected etc ....

                          <mx:TabNavigator creationPolicy="all" id="job_tabNav" width="813" height="313"....>
                          ... some tabs...
                          the Tab for the <states> switch in question in this discussion:

                          <mx:VBox id="jobTab_taskManager" label="Task Mgt." height="275" width="95%" paddingLeft="4">
                          <mx:VBox id=" vBox_taskManager" verticalAlign="top" width="100%" height="250">
                          <mx:Label text="Listing of Actions which remain open."/>
                          <mx:HBox verticalAlign="top" width="100%" height="250">
                          <mx:DataGrid width="80%" height="229">
                          <mx:columns>
                          <mx:DataGridColumn width="100" headerText="Type"/>
                          ... various others ...
                          <mx:DataGridColumn width="150" headerText="Assigned To"/>
                          </mx:columns>
                          </mx:DataGrid>
                          <mx:VBox width="20%" height="229" horizontalAlign="right" borderStyle="solid" paddingTop="10" paddingBottom="10" paddingLeft="10" paddingRight="10">
                          <mx:Button label="Update" id="btn_TMupdate" width="82"/>
                          <mx:Button label="Delete" id="btn_TMdelete" width="82"/>
                          <mx:Button id="link_addNew" label="Add new"
                          click="currentState='tNav_TaskMgr_AddNew'" width="82"/>
                          </mx:VBox>
                          </mx:HBox>
                          </mx:VBox>
                          </mx:VBox>



                          The <state> switch turns off the DataGrid and replaces it with a form when an AddNew button is clicked.

                          I am considering alternative approaches... though I did not think what I'm doing is too radical...! eg.
                          (i) split the whole TabNav - complete with all <states> out to a custom comp - just to see if that works...
                          (ii) trying to rebuild using a TabBar with a ViewStack - which I see are really at the core of the TabNavigator anyway. Ugh! work...!

                          I hope this thing is now clear.

                          BTW, nothing in this App has any smarts yet - this is all by way of laying up the foundations - eventually to be driven by (perhaps) a Ruby on Rails backend.

                          Also, I am aware that I can make the DataGrid editable... I went through that when doing the Stuart Eccles and Derek Wischusen excercises. I just wanted to "master" getting these State swiches under control.

                          I have now tried item (i) above - does not work for me.... maybe I should just just give up and go with what works...!
                          • 10. Re: custom components -
                            mac_martine Level 1
                            okay, i'll give it another try.
                            It sounds like:

                            1) job_dashboard.mxml contains the line
                            <mmComps:states_TaskMgr_addNew id="testComp"/>.

                            2) states_TaskMgr_addNew is where you define the states

                            3) the states are defined in states_TaskMgr_addNew, but are called from job_dashboard.mxml, and call back to job_dashboard.mxml to make modifications there.

                            To call the states in states_TaskMgr_addNew with id="testComp" from it's parentApplication job_dashboard.mxml:
                            testComp.currentState='tNav_TaskMgr_AddNew'

                            The tNav_TaskMgr_AddNew state would then access objects in the parent application with:
                            <mx:RemoveChild target="{parentApplication.vBox_taskManager}"/>
                            <mx:AddChild relativeTo="{parentApplication.jobTab_taskManager}" position="firstChild">

                            Hope that helps!
                            • 11. Re: custom components -
                              tophe1603 Level 1
                              Hi,
                              Thanks for persisting with this...

                              Yes, your summary is correct.

                              However, having tried your solution - I thought it looked like it should go!
                              Flex had no complaints at compile time.

                              I now generate the following error in browser (F'fox) when I click the Ad New button
                              TypeError: Error #1009: Cannot access a property or method of a null object reference.
                              at mx.states::RemoveChild/apply()
                              at mx.core::UIComponent/::applyState()
                              at mx.core::UIComponent/::commitCurrentState()
                              at mx.core::UIComponent/setCurrentState()
                              at mx.core::UIComponent/set currentState()
                              at mmComponents::job_dashboard/__link_addNew_click()

                              I must say your solution did not look like there was a "null object reference"... _link_addNew_click() is refernce to the id of the Add New button.

                              I also tried the following (from states_TaskMgr_addNew.mxml):
                              <mx:RemoveChild target="{parentApplication.testComp.vBox_taskManager}"/>
                              <mx:AddChild relativeTo="{parentApplication.testComp.jobTab_taskManager}" position="firstChild">

                              Flex did not complain here either... but same error result.

                              This is the Add New button:
                              <mx:Button id="link_addNew" label="Add New"
                              click="testComp.currentState='tNav_TaskMgr_AddNew'" width="82"/>

                              I took out the
                              <mx:RemoveChild target="{parentApplication.vBox_taskManager}"/>
                              line to see what would happen...
                              No brower/ActionScript error... but no state switch either...!

                              Do you think maybe there is there something I can do directly with Action Script?
                              • 12. custom components -
                                tophe1603 Level 1
                                Hello again...

                                Eureka!!
                                I went to Help pages to lookup "parentApplication"... to explore the hierarchy.
                                ...came across Flex Applications > Using the Application Container > About the Application object
                                where I found the refernce to mx.core.UIComponent.parentDocument and then
                                "You can use parentDocument.parentDocument to walk up the tree of multiple documents"

                                So, I replaced "parentApplication" with "parentDocument" in the states_TaskMgr_addNew.mxml file...

                                ... and it worked.

                                Thanks again for all your help... it has been a terrific learning experience.
                                Cheers,
                                Chris
                                • 13. Re: custom components -
                                  mac_martine Level 1
                                  Hah! Glad you caught my mistake!
                                  Good luck!