How to add pe:badge to dynamically created menu in bean using PrimeFaces

Viewed 328

I’m rewriting static menu to dynamic, since our customer wants to dynamically change the menu on the fly. Before that I had standard <p:menu> <p:menuItem> </p:menu> structure in my xhtml.

But now I have changed it to: <p:menu model="#{pageTemplateView.menuModel}"/>

And I’m creating model in my backing bean like this:

DefaultMenuItem menuItem = new DefaultMenuItem();
menuItem.setIcon(item.getIcon());
menuItem.setTarget(item.getLink());
menuItem.setValue(item.getName());

But the problem is I don’t know how to add <pe:badge> component inside menu item from bean.

Before that I included badges to menus the following way:

<p:menuitem id="tasks_icon_menuitem_id" icon="fa fa-tasks" url="#">
  <pe:badge content="#{badgeCountBean.badgeCount()}"/>
</p:menuitem> 

So how do I add <pe:badge> to dynamically created menu in bean?

I'm using PrimeFaces 8

1 Answers

After few hours of testing and plying around I found the issue that prevents me from adding badge to default menu item. The issue is when you try to add child to DefaultManuItem like this:

Badge badge = new Badge();
DefaultMenuItem defaultMenuItem = new DefaultMenuItem();
defaultMenuItem.getChildren().add(badge);

You get unsupported operation exception since DefaultMenuItem:: getChildren() is implemented like this:

public List<UIComponent> getChildren() {
    return Collections.emptyList();
}

But I have found an ugly workaround for this issue. So I might share it and maybe well get to better solution eventuality. In my xhtml I added empty menu and gave it fixed ID like this:

<!-- MENU PLACEHOLDER -->
<p:menu id="dynamic_menu_placeholder"/>

<!-- need to add dummy badge to xhtml otherwise it wont be displayed -->
<pe:badge/>

And then in my bean I got the component by ID and added UIMenuItem elements to it like this:

// get component by ID
UIComponent component = FacesContext.getCurrentInstance().getViewRoot().findComponent(":form:dynamic_menu_placeholder");
Menu menu = (Menu) component;
menu.getChildren().clear();

for (MenuItem item : menuItemList) {

    // creating menu item
    UIMenuItem menuItem = new UIMenuItem();
    menuItem.setUrl(item.getLink());
    menuItem.setValue(item.getValue());
    menuItem.setId(... generated some id);
    
    // creating badge
    Badge badge = new Badge();
    badge.setContent(...getBadgeCount()..);
    
    // adding badge to menu item
    menuItem.getChildren().add(badge);
}

// addin menu item to menu
menu.getChildren().add(menuItem);
Related