0

Here is the scenario (simplified): I am trying to use dynamic p:menus inside ui:repeat as shown below ...

<h:form>
   <ui:repeat value="#{bloggerBean.listOfModel}" var="categoryModel" varStatus="loop">
       <p:commandButton id="dynaButton" type="button" 
             value="#{categoryModel.category.name}"/> 
       <p:menu model="#{categoryModel}" overlay="true" trigger="dynaButton" 
                    my="left top" at="left bottom" />
   </ui:repeat>
</h:form>

With this, buttons and menuitems displayed correctly however only the last p:menu action listeners in the loop worked correctly (called at managed bean). Obviously because I am not using varStatus for model. If I changed the above to use varStatus as shown here below,

<h:form>
   <ui:repeat value="#{bloggerBean.listOfModel}" var="categoryModel" varStatus="loop">
       <p:commandButton id="dynaButton" type="button" 
             value="#{categoryModel.category.name}"/> 
       <p:menu model="#{bloggerBean.listOfModel[loop.index]}" overlay="true" trigger="dynaButton" 
                    my="left top" at="left bottom" />
   </ui:repeat>
</h:form>

Buttons and menu displayed however the menuItems in every p:menu is empty.

This is similar to as BalusC reported [here] (Using <ui:repeat><h:inputText> on a List<String> doesn't update model values)!

Any idea why? Thanks!

Community
  • 1
  • 1
Getis
  • 1
  • 3
  • Here is what i wanted to produce, dynamic bread crumb that allows dynamic p:menu selection at any of the button(button with arrow) so that the bread crumb grow or shrink dynamically: – Getis Apr 27 '14 at 14:37

1 Answers1

0

ui:repeat couldn't attach selection event to p:menu menuitems except the last p:menu in the bread crumb model. I come up with a work around for this problem using primefaces remoteCommand. Here is what I changed ... I was setting ActionListener for each menuItems in my model (while generating dynamic bread crumb) as follows:

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
for(Category childCategory : category.getChildCategories()) {
   MenuItem subCategoryItem = new MenuItem();
   ...
   subCategoryItem.addActionListener(this);

}  
...
}

This is not working as I discussed in the question, so I changed the code as follows

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
for(Category childCategory : category.getChildCategories()) {
   MenuItem subCategoryItem = new MenuItem();
   ...

   //Since ui:repeat isn't attaching events to submenus except the last p:menu
   //use instead javascript, pass whatever info as a name value pair
   String parentMapping = "{name: 'parentName', value: '" + category.getName() + "'}";
   String subCategoryMapping = "{name: 'submenuName', value: '" + childCategory.getName() + "'}";
   String remoteMethod = "handleSubmenuSelection([" + parentMapping + "," + subCategoryMapping + "])";
   subCategoryItem.setOnclick(remoteMethod);

}  
...
}

And in my .xhtml, I added p:remoteCommand listening menuItems click event in all bread crumbs submenu

<p:remoteCommand name="handleSubmenuSelection" action="#{bloggerBean.processSubmenuSelection()}" />

Finally, I added some code in my managed bean parsing 'parentName' and 'submenuName' and process which menuItem selected from which bread crumb in my model as follows:

@ManagedBean
@ViewScoped
public class BloggerBean {
...
public void processSubmenuSelection() {
    FacesContext context = FacesContext.getCurrentInstance();
    Map<String, String> map = context.getExternalContext().getRequestParameterMap();
    this.parentName = map.get("parentName");
    this.submenuName = map.get("submenuName");
    for (CategoryMenuModel model : listOfModel) {
        if(parentName.equals(model.category.getName())){
            model.processSubmenuSelection(submenuName);
            break;
        }
    }
}
...
}

In my model

public class CategoryMenuModel implements MenuModel, ActionListener, Serializable {
...
void processSubmenuSelection(String submenuName) {
    System.out.println("In processSubmenuSelection ... starting");
    for (Category childCategory : category.getChildCategories()) {
        if(childCategory.getName().equals(submenuName)){
            setCategory(childCategory);
            break;
        }
    }
}
...
}

Hope, this will help someone with similar question.

Getis
  • 1
  • 3