7 Replies Latest reply: Aug 29, 2014 9:18 AM by dvohra21 RSS

    How to set navigation rules in faces-config.xml dynamically ?

    BAO.SZ

      In jdev 12.1.2, I'm studying and running the adf faces demo (12.1.2 version),

       

      I try to implement the function of navigation as this:

      1. the navigation tree in the left accordion panel will show functions of an application which is read from database tables;

      2. when click a node of the navigation tree, a correspondent function/pages will be launched in the right panel of the main page;

      3. the navigation tree nodes' display names and target pages' information will be reside in database tables and will be read from data control bindings in my case.

       

      and now I know , the click action was executed in this file in the demo: componentGallerySideBarTree.jsff:

          -->action="#{stamp.actionOutcome}

          <af:tree id="tree" value="#{attrs.menuModel}" var="stamp" rowSelection="single" fetchSize="200"

                   summary="#{attrs.summary}" disclosedRowKeys="#{attrs.menuModel.foldersTreeState}" autoHeightRows="0"

                   selectedRowKeys="#{attrs.menuModel.selectionState}" displayRow="selected"

                   contentDelivery="immediate" emptyText="There are no demos for this category"

                   styleClass="AFStretchWidth">

            <f:facet name="nodeStamp">

              <af:panelGroupLayout id="nodePgl">

                <af:image source="#{stamp.ico}" styleClass="GalleryIcon" shortDesc="Image of a tree node"

                          id="nodeImg"/>

                <af:switcher facetName="#{stamp.children==null?'leaf':'notLeaf'}" id="nodeSw">

                  <f:facet name="leaf">

                    <af:link id="leafLink" text="#{stamp.label}"

                             shortDesc="#{stamp.label}#{stamp.deprecated eq 'true' ? ' (deprecated)' : ''}"

                            action="#{stamp.actionOutcome}"

                             inlineStyle="#{stamp.deprecated eq 'true' ? 'font-style:italic;color:gray' : ''}"

                             selected="true">

                      <af:target execute="@this"/>

                    </af:link>

                  </f:facet>

                  <f:facet name="notLeaf">

                    <af:outputText id="notLeafText" value="#{stamp.label}" shortDesc="#{stamp.label}"/>

                  </f:facet>

                </af:switcher>

              </af:panelGroupLayout>

            </f:facet>

          </af:tree>

      and the value of actionOutcome was populated in this file DemoConfusedComponentsMenuModel.java:

      (for the case of Confused Component navagation tree folder)

        private TreeModel _initConfusedComponents()

          {

            // Confused Components

            List<DemoItemNode> confusedComponentsNodes = new ArrayList<DemoItemNode>()

            {

              {

               ..

                add(new DemoItemNode("Tabs", "/confusedComponents/tabs.jspx","/adfdt/panelTabbed.png","confused.tabs"));

               add(new DemoItemNode("Iterators", "/confusedComponents/iterators.jspx","/adfdt/iterator.png","confused.iterators"));          

              }   

            };

            DemoItemNode confusedComponentsGroup = new DemoItemNode("Commonly Confused", "/images/folder.png", confusedComponentsNodes);

            List confusedComponentsList = new ArrayList();
            confusedComponentsList.add(confusedComponentsGroup);

            TreeModel confusedComponents = new ChildPropertyTreeModel(confusedComponentsList, _CHILDREN);
            return confusedComponents;
          }

      Also, there are entries in faces-config.xml file to define navigation rules for "clicking tree node" actions.

          <navigation-case>

            <from-outcome>confused.iterators</from-outcome>

            <to-view-id>/confusedComponents/iterators.jspx</to-view-id>

            <!--  <redirect/>  -->

          </navigation-case>

        So, I can add a new entry to the navigation tree like this:

          1.in file DemoConfusedComponentsMenuModel.java: add

          add(new DemoItemNode("Iterators", "/confusedComponents/cms.jspx","/adfdt/iterator.png","confused.cms"));

         2. in the faces-config.xml file add:

          <navigation-case>

            <from-outcome>confused.cms</from-outcome>

            <to-view-id>/confusedComponents/cms.jspx</to-view-id>

            <!--  <redirect/>  -->

          </navigation-case>

        and it works!-- I successfully added a new node in the navigation tree  to call a new page cms.jspx created by myself.

       

      If I implement it using database tables (EO/VO datacontrols bindings) ,

      I think i can set action="#{stamp.actionOutcome}"  by bindings,

      but how can I set the entry in faces-config.xml file? --that is to say:

      How to set navigation rules in faces-config.xml dynamically ?

       

      Thanks in advance!

        • 1. Re: How to set navigation rules in faces-config.xml dynamically ?
          kdario

          ADF 12c comes with JSF 2.0 support so you can use implicit navigation feature.

          In short: you don't need to add navigation case, just set action property to page name(and include path if needed).

          In your case, action name will be: "/confusedComponents/cms.jspx" and of course, you can bind action property to method which will return this string.

           

          If you still want to programmatically add navigation case, try with ConfigurableNavigationHandler.

          For example:

          ConfigurableNavigationHandler handler = (ConfigurableNavigationHandler)FacesContext.getCurrentInstance().getApplication().getNavigationHandler();

          handler.getNavigationCases().put(...);

           

          Dario

          • 2. Re: How to set navigation rules in faces-config.xml dynamically ?
            BAO.SZ

            Hi,Dario

            Thank you very much for your kind suggestion.

            In my case, if I remove the following navigation rules from faces-config.xml file,

                <navigation-case>

                  <from-outcome>confused.cms</from-outcome>

                  <to-view-id>/confusedComponents/cms.jspx</to-view-id>

                  <!-- <redirect/>  -->

                </navigation-case>

            then, even if I do have set the action="#{stamp.actionOutcome}"  to the  "/confusedComponents/cms.jspx", when I run the  index.jspx of the application,

            I will get a alert msg like this:

            无法从视图 ID '/index.jspx' 中找到具有结果 'confused.cms' 的操作 '#{stamp.actionOutcome}' 的匹配导航条件

            (means: cannot find correspond navigation action target of 'confused.cms' in viewId '/index.jspx)

             

            and cannot launch the target page.-- that is why I think it will be a need to add navigation case in the faces-config.xml.

            I learn from your suggestion on how to programmatically add navigation case. You give the correct answer to my question.

             

            However, now I think, in my case it's not neccessary to set navigation rules  dynamically in the faces-config.xml, in stead I can add this <navigation-case> whenever I add a new jspx page into the application. as:

            The true idea for my implementation of this navigation tree of being populated by datas from database table is that users can adjust/reset the tree structure (ie. tree node name or hierachy structure) without having to modify the java class and rebuild/redeploy the application. but when I add a new function/page to the application, I have to modify-build-deploy the application again-- then I can add the <navigation-case> to the faces-config.xml by the way.

             

            (and I have to consider the security control for this navigation-tree-launched-function approach, that maybe a new post.)

            Thanks..

            • 3. Re: How to set navigation rules in faces-config.xml dynamically ?
              dvohra21

              cannot find correspond navigation action target


              What is the action target? The action target may be specified in the action method as the method return value. For example to navigate to page output.xhtml make the return value of the action method as


              return "output";


              But the output.xhtml must be available.

              • 4. Re: How to set navigation rules in faces-config.xml dynamically ?
                BAO.SZ

                Correction:

                dvohra21 and Dario are right, that

                ADF 12c comes with JSF 2.0 support so you can use implicit navigation feature.

                we don't need to add navigation case, just set action property to page name(and include path if needed).

                in my case, action="#{stamp.actionOutcome}"  actually returns confused.cms 
                by

                add(new DemoItemNode("Iterators", "/confusedComponents/cms.jspx","/adfdt/iterator.png","confused.cms"));

                so will need a mapping in faces-config.xml   (is that so)

                    <navigation-case>

                      <from-outcome>confused.cms</from-outcome>

                      <to-view-id>/confusedComponents/cms.jspx</to-view-id>

                      <!-- <redirect/>  -->

                    </navigation-case>

                if I set action="/confusedComponents/cms.jspx", it will work ok.

                 

                Thank you all!

                • 5. Re: How to set navigation rules in faces-config.xml dynamically ?
                  dvohra21

                  Why does the action method have to return confused.cms ? Make the action method return cms.

                   

                  return "cms";

                  • 6. Re: How to set navigation rules in faces-config.xml dynamically ?
                    BAO.SZ

                    Why does the action method have to return confused.cms ? Make the action method return cms.

                    --this was made in an Oracle official demo: adf faces demo, from the DemoConfusedComponentsMenuModel.java:

                      private TreeModel _initConfusedComponents()

                        {

                          // Confused Components

                          List<DemoItemNode> confusedComponentsNodes = new ArrayList<DemoItemNode>()

                          {

                            {

                              add(new DemoItemNode("Checkboxes", "/confusedComponents/checkboxes.jspx","/adfdt/selectManyCheckbox.png","confused.checkboxes"));

                              ...

                              add(new DemoItemNode("Iterators", "/confusedComponents/iterators.jspx","/adfdt/iterator.png","confused.iterators"));

                             }

                          };

                       ..

                        };

                    I'm now studying this demo, and trying to learn from this demo, see: How to create a adffacesdemo style navigation tree for application.?

                     

                    Many occassions I wonder "Why does *** by this way in the demo", and above was one of them.

                    From ADF newbies' point like me, what this demo trying to  show is not so straightforward.

                    Is there any more detail documents on this demo?

                     

                    Thanks.

                    • 7. Re: How to set navigation rules in faces-config.xml dynamically ?
                      dvohra21

                      The demo may have been developed for an earlier version of JDeveloper or JSF.