12 Replies Latest reply on Sep 17, 2011 3:03 AM by Eldin Okanovic

    Generating menu items inside <rich:contextMenu> dynamically

    Chandra Sekar.S Newbie

      Hi,

      Could some one please point out the problem in the following page code?

      <%@ page language="java" contentType="text/html; charset=ISO-8859-1"
       pageEncoding="ISO-8859-1"%>
      
      <%@taglib uri="http://java.sun.com/jsf/core" prefix="f"%>
      <%@taglib uri="http://java.sun.com/jsf/html" prefix="h"%>
      <%@taglib uri="http://richfaces.org/a4j" prefix="a4j"%>
      <%@taglib uri="http://richfaces.org/rich" prefix="rich"%>
      <!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
      <html>
      <head>
      <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
      <title>Demo Page</title>
      </head>
      <body>
      <f:view>
       <h:form>
       <a4j:outputPanel layout="block" id="demoPanel"
       style="width: 100px; height: 100px; border: 1px solid black">
       </a4j:outputPanel>
       <rich:contextMenu>
       <rich:menuItem value="Demo" />
       <a4j:repeat var="currentDestination"
       value="#{dataContainer.destinations}">
       <rich:menuItem value="Re-Load for #{currentDestination}" />
       </a4j:repeat>
       </rich:contextMenu>
       </h:form>
      </f:view>
      </body>
      </html>


      The statically generated item with title "Demo" is shown fine. But the dynamically generated ones are not. Can't we use a4j:repeat inside contextMenu? If not then how to dynamically generate the menu items?

        • 2. Re: Generating menu items inside <rich:contextMenu> dynamica
          Ilya Shaikovsky Master

          you should not use not a4j nor ui repeat components. Use c:forEach instead or use component binding.

          • 3. Re: Generating menu items inside <rich:contextMenu> dynamica
            Chandra Sekar.S Newbie

            Could you kindly explain why that approach does not work?

            Also, component binding seems like an over kill as it is needed at just one place. I read at many places that using JSTL along with JSF is not advisable.

            Could you please enlighten me on these?

            • 4. Re: Generating menu items inside <rich:contextMenu> dynamica
              Ilya Shaikovsky Master

              1) c:forEach will works fine in facelets envirenment.

              http://www.ilikespam.com/blog/c:foreach-vs-ui:repeat-in-facelets - the difference.

              if you do not using facelets - use binding.

              • 5. Re: Generating menu items inside <rich:contextMenu> dynamica
                Chandra Sekar.S Newbie

                I managed it quite a bit with component binding. Thanks for the tip.

                I have set up the actionExpression for each individual HtmlMenuItem component. The action method is invoked which I verify with a System.out.println(); statement.

                Here is the code used to build the ContextMenu object.

                public ContextMenu getPopupMenu() {
                 popupMenu = new ContextMenu();
                 List<HtmlMenuItem> components = new ArrayList<HtmlMenuItem>();
                
                 for (String string : destinations) {
                 HtmlMenuItem item = new HtmlMenuItem();
                 item.setValue(string);
                 MethodExpression expression = FacesContext.getCurrentInstance()
                 .getApplication().getExpressionFactory()
                 .createMethodExpression(
                 FacesContext.getCurrentInstance().getELContext(),
                 "#{dataContainer.show}", null, new Class<?>[0]);
                 item.setActionExpression(expression);
                 components.add(item);
                 }
                 popupMenu.getChildren().clear();
                 popupMenu.getChildren().addAll(components);
                 return popupMenu;
                 }


                popupMenu is an instance reference.

                But how do I determined which menu item was selected in the action method? Also, what is the reason for a4j:repeat not working inside context menu while it works perfectly inside components like a4j:outputPanel?

                • 6. Re: Generating menu items inside <rich:contextMenu> dynamica
                  Ilya Shaikovsky Master

                  "But how do I determined which menu item was selected in the action method?"

                  add parameters or use actionListener instead.

                  • 7. Re: Generating menu items inside <rich:contextMenu> dynamica
                    Chandra Sekar.S Newbie

                    Thanks that worked really well using ActionListener!

                    Could you please enlighten me on the reason for a4j:repeat not working inside context menu while it works perfectly inside components like a4j:outputPanel?

                    I have tried searching a lot but not getting any hint. :(

                    • 8. Re: Generating menu items inside <rich:contextMenu> dynamica
                      liumin hu Master

                      hi,

                      i want to create a contextmenu dynamically for every line of a datatable. I used the code posted by chandru.in to creat the contextmenu. the xhtml is like this

                      <rich:dataTable var="line" value="#{list}">
                       <rich:column>
                       <t:graphicImage id="imgAction" value="#{line.actionImg}" />
                       <rich:contextMenu binding="#{line.lineContextMenu}" />
                       </rich:column>
                      </rich:dataTable>
                      


                      But i get a error like this:

                      binding="#{line.lineContextMenu}": Target Unreachable, identifier 'line' resolved to null


                      i want to know if we can use the contextmenu in this way?

                      Thanks in advance



                      • 9. Re: Generating menu items inside <rich:contextMenu> dynamica
                        Ilya Shaikovsky Master

                        and what is inside your bean? have you initialized this variable?

                        • 10. Re: Generating menu items inside <rich:contextMenu> dynamica
                          liumin hu Master

                          yes. i initialized this variable.

                          if i replace the binding of rich:contextMenu with value , like

                          <rich:contextMenu value="#{line.lineContextMenu}" />


                          there is no exception, but contextmenu does not work simply.

                          if i use
                          <h:outputText value="#{line.lineContextMenu}" />


                          I can see the object is created.

                          in the bean, i have the code is almost the same as the code of chandru.in shown above.

                          • 11. Re: Generating menu items inside <rich:contextMenu> dynamica
                            Felix Siegrist Newbie

                            Hi

                             

                            I have the same problem as Iiumin Hu.

                             

                            I would like to create a rich:contextMenu within each row of a rich:dataTable. The menu items of the context menu must be added dynamically (i.e. each row has different context menu entries).

                             

                            This leads to a dilemma:

                            Dynamically adding menu items to a context menu is not possible using ui:repeat/a4j:repeat because rich:contextMenu only accepts rich:menuItem or rich:menuGroup as its children. Using c:forEach is not possible neither, because we are whithin a rich:dataTable and each row will have a different number of menu items within its context menu (i.e. different number of components in the component tree).

                             

                            So I hoped the solution is to use the binding attribute of rich:contextMenu. But like Iiumin Hu, I get a an Exception telling me, that the element I use as binding target is unreachable:

                            javax.faces.FacesException: javax.el.PropertyNotFoundException: /path/to/my/page.xhtml binding="#{_row.contextMenu}": Target Unreachable, identifier '_row' resolved to null

                             

                            The relevant parts of the page look like this:

                            <rich:dataTable ... var="_row" ...>

                                 <rich:column>

                                      <f:facet name="header>...</f:facet>

                                      <rich:contextMenu ... submitMode="ajax" binding="#{_row.contextMenu}" />

                                 </rich:column>

                            ...

                            </rich:dataTable>

                             

                            Is there anybody having successfully resolved this problem?

                            • 12. Re: Generating menu items inside <rich:contextMenu> dynamica
                              Eldin Okanovic Newbie

                              I have a same problem like Felix and liumin hu, but with dropdown menu.

                              When i remove column with menu it's renders fine, but when i put column back with <rich:dropDownMenu binding="#{item.menu}" it show a same exception from above.

                              This is mine method generating dropdown menu object in backing bean:

                              private void generateMenu()

                              {

                                      menu = new UIDropDownMenu();

                                      menu.setDirection(Positioning.bottomRight);

                                      menu.setMode(Mode.server);

                                      menu.setJointPoint(Positioning.topRight);                   

                                      menu.setId("menuOdsjek" + odsjek.getId());

                                      menu.setStyle("padding:0px;white-space: normal;");

                                      HtmlCommandLink link = new HtmlCommandLink();

                                      link.setTitle("Otvori stranicu odsjeka");

                                      HtmlOutputText text = new HtmlOutputText();

                                      text.setValue(odsjek.getNazivAt());

                                      link.getChildren().add(text);

                                      link.setId("linkOdsjek" + odsjek.getId());

                                      FacesComponentFunkcije.addAction(link, "#{odsjeciForm.otvoriOdsjek}");

                                      link.setStyle("font-size:11px;");

                                      menu.getFacets().put("label", link);

                              }