Problem with pu:menu with models

Forum rules
Please note that response time for technical support is within 3-5 business days.
Post Reply
bmoon
Posts: 24
Joined: 10 May 2016, 21:16

21 Feb 2017, 21:23

I'm trying to build a menu in the side menu (pu:menu) where the number of items in the menu is dynamic. Since there's now "menu items" construct, the only way that I see to do this is to do a server side "MenuModel". However, when doing this, I have strange behavior on select any "menu item" that has an outcome or url associated. What happens is that in various cases, some other menu item winds up being highlighted in the menu rather than the menu item that was selected. Mind you that the correct outcome/url is executed, its just that the client side js is highlighting the wrong sub-menu and menu item combination.

Here's my server side code, located in a session bean called "sessionBean" :

Code: Select all

    private transient MenuModel sideMenuModel;

    public MenuModel getSideMenuModel() {
        if (sideMenuModel == null) {
            LOG.log(Level.INFO, "BUILDING MENU");
            sideMenuModel = new DefaultMenuModel();

            // collections
            DefaultSubMenu subMenu = new DefaultSubMenu("Locations", "fa fa-location-arrow");
            sideMenuModel.addElement(subMenu);

            // smart reports
            subMenu = new DefaultSubMenu("Smart Reports", "trending_up");
            // dashboard
            DefaultMenuItem item = new DefaultMenuItem("Dashboard", "dashboard","/charts.xhtml");
            item.setIconPos("left");
            subMenu.addElement(item);
            // inventory
            item = new DefaultMenuItem("Inventory", "view_list","/data.xhtml");
            item.setIconPos("left");
            subMenu.addElement(item);
            sideMenuModel.addElement(subMenu);
            // optional admin menu
            if (isAdmin()) {
                subMenu = new DefaultSubMenu("Admin", "settings");
                item = new DefaultMenuItem("Edit Users", "group","/editUsers.xhtml");
                item.setIconPos("left");
                subMenu.addElement(item);
                sideMenuModel.addElement(subMenu);
            }
            // utlities
            item = new DefaultMenuItem("Utils", "fa fa-institution","/utils.xhtml");
            sideMenuModel.addElement(item);
            // documentation
            item = new DefaultMenuItem("Documentation", "help","/docs.xhtml");
            sideMenuModel.addElement(item);
        }
        return sideMenuModel;
    }
Here's my "menu.xhtml" code:

Code: Select all

<ui:composition 
    xmlns="http://www.w3.org/1999/xhtml"
    xmlns:f="http://java.sun.com/jsf/core"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:ui="http://java.sun.com/jsf/facelets"
    xmlns:p="http://primefaces.org/ui"
    xmlns:pu="http://primefaces.org/ultima">

    <h:form id="menuform"> 
        <div class="layout-menu #{guestPreferences.menuClass}">
            <div class="nano">
                <div class="nano-content menu-scroll-content">
                    <pu:menu widgetVar="me" rendered="#{sessionBean.loggedIn}" model="#{sessionBean.sideMenuModel}"/>
                </div>
            </div>
        </div>
    </h:form>
</ui:composition>
I'm not able to attache a screen shot to this message, so I'll have to describe an outcome. If for example, you select "admin/edit users" then the "editUsers.xhtml" page is shown, however in the "menu.xhtml" fragment, the sub menu "admin" and menu item "Edit Users" are not selected and the "admin" sub menu closes. If you then subsequently select another menu item, for example if you pick "Smart Reports" and "Inventory" then instead of those two being highlighted in the menu, the "admin" and "edit users" are highlighted.

If I change my code from using a "DefaultMenuModel" to construct this menu to instead "hard code" the menu, then everything works fine. I also tried adding my programatic menu to the demo project by adding in my sessionBean and the then adding this line of code to the menu.xhtml from the demo project just above the already defined menu ("me"):

Code: Select all

                    <pu:menu widgetVar="me2" rendered="#{sessionBean.loggedIn}" model="#{sessionBean.sideMenuModel}"/>
When I do this, I see the same failures. Have you validated that a "model" can be used to drive a "pu:menu" element?

bmoon
Posts: 24
Joined: 10 May 2016, 21:16

22 Feb 2017, 22:18

Here's how to re-create this bug. I took the demo project and then I added the following code to the "GuestPreferences.java" file:

Code: Select all

    private MenuModel menuModel;

    private DefaultSubMenu createSubMenu(final String label, final String icon) {
        final DefaultSubMenu result = new DefaultSubMenu(label, icon);
        return result;
    }

    private DefaultMenuItem createMenuItem(final String label, final String icon, final String outcome) {
        final DefaultMenuItem result = new DefaultMenuItem(label, icon);
        result.setIconPos("left");
        result.setOutcome(outcome);
        return result;
    }

    public MenuModel getSideMenuModel() {
        if (menuModel == null) {
            menuModel = new DefaultMenuModel();
            // THESE MENU ITEMS will work
            DefaultSubMenu subMenu = createSubMenu("Analytics", "trending_up");
            subMenu.addElement(createMenuItem("Dashboard", "dashboard", "/charts.xhtml"));
            subMenu.addElement(createMenuItem("Inventory", "view_list", "/data.xhtml"));
            menuModel.addElement(subMenu);

            // NOTE, this is an example of a menu item that will FAIL when picked
            subMenu = createSubMenu("Admin", "settings");
            subMenu.addElement(createMenuItem("Edit Users", "group", "/empty.xhtml"));
            menuModel.addElement(subMenu);

            // THESE MENU ITEMS will work
            menuModel.addElement(createMenuItem("Utils", "fa fa-institution", "/utils.xhtml"));
            menuModel.addElement(createMenuItem("Documentation", "help", "/docs.xhtml"));
        }
        return menuModel;
    }
I then edited the "menu.xhtml" file in the "WEB-INFO" folder to add the following line to the bottom of the file just after the close of the statically defined pu:menu

Code: Select all

                    <pu:menu widgetVar="me2" model="#{guestPreferences.sideMenuModel}"/>                    
With that, I then load the project into my Glassfish server and visit the page. When I try to select the menu item "Edit Users", the state of the pu:menu is messed up, the menu closes and does not show "Admin", "Edit User" as being highlighted. The next item that I select from the menu causes the "Admin", "Edit User" to be highlight rather than the next menu item selected.

Oddly enough, selecting "Analytics/Dashboard" or "Analytics/Inventory" don't cause this problem. Instead of loading the "empty.xhtml" file they load "data.xhtml" or "charts.xhtml" and those seem to work. Note I'm using the "stock" files from the demo project to be loaded by the menu model. I also have noted that if you try to load "samples.xhtml" that it causes the same menu error.

mert.sincan
Posts: 5281
Joined: 29 Jun 2013, 12:38

20 Mar 2017, 10:07

I tested this issue. Firstly, I think you can add a method to create menu model instead of "get" methods. My example;

//java code

Code: Select all

@ManagedBean
@SessionScoped
public class GuestPreferences implements Serializable {

    ..

    private MenuModel sideMenuModel;

    @PostConstruct
    public void init() {
        ...

        createMenuModel();
    }

    public void createMenuModel() {
        sideMenuModel = new DefaultMenuModel();

        // collections
        DefaultSubMenu subMenu = new DefaultSubMenu("Locations", "fa fa-location-arrow");
        subMenu.setId("um_locations");
        sideMenuModel.addElement(subMenu);

        // smart reports
        subMenu = new DefaultSubMenu("Smart Reports", "trending_up");
        subMenu.setId("um_smart");
        // dashboard
        DefaultMenuItem item = new DefaultMenuItem("Dashboard", "dashboard", "/charts.xhtml");
        item.setId("um_dashboard");
        item.setIconPos("left");
        subMenu.addElement(item);
        // inventory
        item = new DefaultMenuItem("Inventory", "view_list", "/data.xhtml");
        item.setId("um_inventory");
        item.setIconPos("left");
        subMenu.addElement(item);
        sideMenuModel.addElement(subMenu);
        // utlities
        item = new DefaultMenuItem("Utils", "fa fa-institution", "/utils.xhtml");
        item.setId("um_utils");
        sideMenuModel.addElement(item);
        // documentation
        item = new DefaultMenuItem("Documentation", "help", "/docs.xhtml");
        item.setId("um_documentation");
        sideMenuModel.addElement(item);
    }

    public MenuModel getSideMenuModel() {
        return sideMenuModel;
    }

    public void setSideMenuModel(MenuModel sideMenuModel) {
        this.sideMenuModel = sideMenuModel;
    }
    
    ..
}
//xhtml code

Code: Select all

<pu:menu id="menu" widgetVar="me" model="#{guestPreferences.sideMenuModel}"/>
You need to add ids to submenu, menuitems and pu:menu to use the stateful feature. Then, please add the following method within UltimaMenuRenderer.java;

Code: Select all

public class UltimaMenuRenderer extends BaseMenuRenderer {
    
       @Override
	public void encodeEnd(FacesContext context, UIComponent component) throws IOException { // PLEASE ADD THIS METHOD
		AbstractMenu menu = (AbstractMenu) component;

		encodeMarkup(context, menu);
		encodeScript(context, menu);
	}
       
       ...
}

Hamsterbau
Posts: 409
Joined: 28 Dec 2011, 17:44

11 Sep 2017, 09:47

This cannot work with the following versions:
  • Primefaces 6.1.x
  • Ultima 1.0.9
In UltimaMenuRenderer following code cast to UIComponent for each item:

Code: Select all

        if(value != null && ((UIComponent)menuitem).getParent() instanceof UltimaMenu) {
            encodeTooltip(context, value);
        }
But DefaultMenuItem does not inherit from UIComponent (or UIMenuItem). Only MenuItem object will be inherited, so this cast cannot work with the mentioned versions. Now is the question, is DefaultMenuItem implementation wrong (perhaps it should inherit from UIMenuItem insteaed of MenuItem) or do Ultima theme the wrong cast to UIComponent?

But this should be fixed soon, because dynamic menus are currently not possible.

Wbr,

Daniel
Primefaces 8.0.7 (PF Extensions 8.0)
JSF: Mojarra 2.3.2 (Spec 2.3) - running on WildFly 22

mert.sincan
Posts: 5281
Joined: 29 Jun 2013, 12:38

13 Sep 2017, 10:48

Fixed for next version. Thanks a lot!

Post Reply

Return to “Ultima - PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 13 guests