Sentinel left SubMenu Expand/Collapse based on a parameter.

ramasamy-sk
Posts: 9
Joined: 16 Oct 2015, 21:56

23 Oct 2015, 15:39

Hello,

We have a requirement in a project, that limited access user will have only few options in the left menu in sentinel layout. Basically the users would like to expand those submenus by default for those limited access users.

We are using ps:menu comes with the sentinel layout. It would be great, if there will be an option to control the sub menu using parameter to expand and collapse by default.

Please let us know what could be the best choice for us.

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

26 Oct 2015, 16:33

Sorry for late reply. We are working for Layouts compatibility with PF5.3. (Responsive Layouts and Components).
For this issue, I think you can use model attribute in ps:menu. Exp;

Code: Select all

//Xhtml
<ps:menu id="sm_leftmenu" model="#{menuView.model}" />

//menuView.java

@ManagedBean
public class MenuView {
     
    private MenuModel model;
 
    @PostConstruct
    public void init() { // or After login, you can call a function as createMenuModel() { contents of the init() function }
        model = new DefaultMenuModel();
         
        //Dashboard
        DefaultMenuItem dashboard = new DefaultMenuItem("Dashboard");
        dashboard.setIcon("icon-home-outline");
        dashboard.setOutcome("dashboard");
        dashboard.setId("sm_dashboard");
        
        model.addElement(dashboard);
        
        //Sentinel Theme submenu
        DefaultSubMenu sentinelSubmenu = new DefaultSubMenu("Sentinel Theme");
        sentinelSubmenu.setIcon("icon-gauge");
        sentinelSubmenu.setId("sm_sentineltheme");
        
        DefaultMenuItem forms = new DefaultMenuItem("Forms");
        forms.setIcon("icon-doc-text-1");
        forms.setOutcome("forms");
        forms.setId("sm_forms");
        sentinelSubmenu.addElement(forms);
        
       /* if(!limited_access_user) { // boolean value. Exp; after login, you can change this value according to user information */ 
           DefaultMenuItem datatable = new DefaultMenuItem("DataTable");
           datatable.setIcon("icon-table");
           datatable.setOutcome("datatable");
           datatable.setId("sm_datatable");
          sentinelSubmenu.addElement(datatable);
        /* } */
        
        sentinelSubmenu.setExpanded(true);
        model.addElement(sentinelSubmenu);
        
        //Documentation
        DefaultMenuItem documentation = new DefaultMenuItem("Documentation");
        documentation.setIcon("icon-graduation-cap");
        documentation.setOutcome("documentation");
        documentation.setId("sm_doc");
        
        model.addElement(documentation);
    }

    public MenuModel getModel() {
        return model;
    }
}
in My example
Expand; sentinelSubmenu.setExpanded(true);
Collapse; sentinelSubmenu.setExpanded(false);

ramasamy-sk
Posts: 9
Joined: 16 Oct 2015, 21:56

26 Oct 2015, 18:48

Hi Aragon,

Thanks for your response.

I tried with the code snippet with my project. The submenu always collapse regardless of the "sentinelSubmenu.setExpanded(true);" value. Please correct me if i am doing something wrong.

Environment:
Primefaces Elite - 5.2.11
Sentinel : 1.3.1
JSF: 2.1
JBoss EAP 6.3
Browser : Firefox & IE 11
OS: Windows 7

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

27 Oct 2015, 08:39

Or I think you can use expanded=true attribute in p:submenu. But, for menu stateful(cookie) you need to override the js codes. If you want this feature with expanded attribute, I can override layout.js for you in this week.

How do you want to use? expanded=true in p:submenu OR submenu.setExpanded(true) in bean.java

ramasamy-sk
Posts: 9
Joined: 16 Oct 2015, 21:56

27 Oct 2015, 15:10

For now, I would like to use it in " p:submenu" instead of Bean. But please provide us an example of both options incase if it is possible.

ramasamy-sk
Posts: 9
Joined: 16 Oct 2015, 21:56

09 Nov 2015, 22:51

Hi Aragorn,

Hope you are doing great.

Did you get a chance to work on this??

Thanks,
-Senthil

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

10 Nov 2015, 15:05

Yes, I changed some things on layout.js and SentinelMenuRenderer.java. I spent long time to do stateful feature of menu.
Please find this functions and replace them in layout.js;

Code: Select all

...
toggleSubMenu: function(element) {
        var link = $(element),
        menuitem = link.closest('li'),
        subMenuContainer = menuitem.children('ul.layout-menubar-submenu-container'),
        isRootItem = menuitem.parent().is(this.menubarContainer),
        menuitemId = menuitem.attr('id');

        if(subMenuContainer.length) {
            if(subMenuContainer.is(':visible')) {
                if(isRootItem) {
                    menuitem.removeClass('layout-menubar-active');
                }
                
                var childrenContainers = subMenuContainer.find('.layout-menubar-submenu-container:visible');
                if(this.activeMenuitemId) {
                    this.activeMenuitemId = $.grep(this.activeMenuitemId, function(value) {
                        return value != menuitemId;
                    });

                    for(var i = 0; i < childrenContainers.length; i++) {
                        var itemId = childrenContainers.eq(i).closest('li').attr('id');
                        this.activeMenuitemId = $.grep(this.activeMenuitemId, function(value) {
                            return value != itemId;
                        });
                    }
                    this.saveMenuState();
                }
                subMenuContainer.hide();
            }
            else {
                if(isRootItem)
                    menuitem.addClass('layout-menubar-active');
                else
                    menuitem.removeClass('layout-menubar-active');
                
                subMenuContainer.show();
                
                if(this.activeMenuitemId.indexOf(menuitemId) < 0) {
                    this.activeMenuitemId.push(menuitemId);
                    this.saveMenuState();
                }
            }
        }
    },
...
restoreMenuState: function() {
        var expandedItems = $.cookie('sentinel_activemenuitem');
        this.menubar = $('#layout-menubar');
        this.menubarContainer = this.menubar.children('ul.layout-menubar-container');
        
        if(expandedItems) {
            this.collapseAll();
            this.activeMenuitemId = expandedItems.split(',');
            
            for(var i = 0; i < this.activeMenuitemId.length; i++){
                var element = $(PrimeFaces.escapeClientId(this.activeMenuitemId[i]));
                if(element.children('.layout-menubar-submenu-container')) {
                    this.toggleSubMenu(element);
                }
            }
        }
        else {
            this.activeMenuitemId = [];
            if(expandedItems !== undefined) {
                this.collapseAll();
            }
            
            var activeItems = this.menubarContainer.find('.layout-menubar-active');
            for(var i = 0; i < activeItems.length; i++){
                var element = activeItems.eq(i),
                    elementId = element.attr('id');
            
                if(element.children('.layout-menubar-submenu-container').length) {
                    if(!element.parent().is(this.menubarContainer)) {
                        element.removeClass('layout-menubar-active');
                        this.openParentsItem(element);
                    }
                    
                    if(this.activeMenuitemId.indexOf(elementId) < 0) {
                        this.activeMenuitemId.push(elementId);
                    }
                    element.children('.layout-menubar-submenu-container').show();
                }
                else {
                    element.removeClass('layout-menubar-active');
                }
            }
            this.saveMenuState();
        }
        
        if($.cookie('sentinel_menumode') === 'slim') {
            this.menubar.addClass('slimmenu');
            $('#searchArea').addClass('slimsearch');
        }
    },
And add in layout.js;

Code: Select all

...
openParentsItem: function(element) {
        var parentElement = element.parent();
        if(parentElement.is(this.menubarContainer)) {
            element.addClass('layout-menubar-active');
            return;
        }
        var parentAnchor = parentElement.prev('a');
        
        this.toggleSubMenu(parentAnchor);
        this.openParentsItem(parentAnchor.closest('li'));
    },
    
    collapseAll: function() {
        this.menubarContainer.find('.layout-menubar-active').each(function() {
            var element = $(this);
            element.removeClass('layout-menubar-active').children('ul.layout-menubar-submenu-container').hide();
        });
        this.activeMenuitemId = [];
    },
   
   restoreMenuitem: function(menuitem) {
    ...
   },
....
Then, please change encodeElements function in SentinelMenuRenderer.java;

Code: Select all

//line 62
protected void encodeElements(FacesContext context, AbstractMenu menu, List<MenuElement> elements, int marginLevel) throws IOException {
        ResponseWriter writer = context.getResponseWriter();
        String menuClientId = menu.getClientId(context);
        
        for(MenuElement element : elements) {
            if(element.isRendered()) {
                if(element instanceof MenuItem) {
                    MenuItem menuItem = (MenuItem) element;
                    String menuItemClientId = (menuItem instanceof UIComponent) ? menuItem.getClientId() : menuClientId + "_" + menuItem.getClientId();
                    String containerStyle = menuItem.getContainerStyle();
                    String containerStyleClass = menuItem.getContainerStyleClass();

                    writer.startElement("li", null);
                    writer.writeAttribute("id", menuItemClientId, null);
                    writer.writeAttribute("role", "menuitem", null);
                    
                    if(containerStyle != null) writer.writeAttribute("style", containerStyle, null);
                    if(containerStyleClass != null) writer.writeAttribute("class", containerStyleClass, null);

                    encodeMenuItem(context, menu, menuItem, marginLevel);
                    
                    writer.endElement("li");
                }
                else if(element instanceof Submenu) {
                    Submenu submenu = (Submenu) element;
                    boolean expanded = submenu.isExpanded();
                    String submenuClientId = (submenu instanceof UIComponent) ? ((UIComponent) submenu).getClientId() : menuClientId + "_" + submenu.getId();
                    String style = submenu.getStyle();
                    String styleClass = submenu.getStyleClass();
                    String expandedStyle = expanded ? "layout-menubar-active":"";
                    styleClass = (styleClass != null) ? styleClass + " " + expandedStyle : expandedStyle; 
                    
                    writer.startElement("li", null);
                    writer.writeAttribute("id", submenuClientId, null);
                    writer.writeAttribute("role", "menuitem", null);
                    
                    if(style != null) writer.writeAttribute("style", style, null);
                    if(styleClass != null) writer.writeAttribute("class", styleClass, null);
 
                    encodeSubmenu(context, menu, submenu, marginLevel);
                    
                    writer.endElement("li");
                } 
                else if(element instanceof Separator) {
                    encodeSeparator(context, (Separator) element);
                }
            }
        }
    }
Full codes of layout.js and SentinelMenuRenderer.java; https://www.dropbox.com/s/oyt9z1hawvgbj ... u.rar?dl=0

Exp;
// leftmenu.xhtml

Code: Select all

<ps:menu id="sm_leftmenu">
    <p:menuitem id="sm_dashboard" value="Dashboard" icon="icon-home-outline" outcome="dashboard"/>
    <p:submenu id="sm_sentineltheme" label="Sentinel Theme" icon="icon-gauge" expanded="true">
        <p:menuitem id="sm_sample" value="Sample Page" icon="icon-columns" outcome="sample" />
        <p:menuitem id="sm_forms" value="Forms" icon="icon-doc-text-1" outcome="forms"/>
        <p:menuitem id="sm_datacomponents" value="Data Components" icon="icon-th" outcome="data"/>
        <p:menuitem id="sm_datatable" value="DataTable" icon="icon-table" outcome="datatable"/>
        <p:menuitem id="sm_panels" value="Panels" icon="icon-magic" outcome="panel"/>
    </p:submenu>

    <p:menuitem id="sm_fonts" value="Font Icons" icon="icon-book" outcome="font-icons.xhtml" />

    <p:submenu id="sm_menu" label="Menu Hierarchy" icon="icon-sitemap">
        <p:submenu id="sm_sub1" label="Submenu 1" icon="icon-folder-empty">
            <p:submenu id="sm_sub1_1" label="Submenu 1.1" icon="icon-folder-empty">
                <p:submenu id="sm_sub1_1_1" label="Submenu 1.1.1" icon="icon-folder-empty" expanded="true">
                    <p:menuitem id="sm_lnk1" value="Link 1" icon="icon-link" outcome="empty-page.xhtml"/>
                    <p:menuitem id="sm_lnk2" value="Link 2" icon="icon-link" outcome="empty-page.xhtml" />
                    <p:menuitem id="sm_lnk3" value="Link 3" icon="icon-link" outcome="empty-page.xhtml" />
                </p:submenu>
            </p:submenu>
        </p:submenu>
    </p:submenu>

    <p:menuitem id="sm_user" value="User Profile" icon="icon-vcard" outcome="empty-page" />
</ps:menu>
Waiting for test results ;)

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

10 Nov 2015, 15:12

You can use expanded attribute of submenu ;)

ramasamy-sk
Posts: 9
Joined: 16 Oct 2015, 21:56

19 Nov 2015, 15:52

Aragorn,

We completed our testing. The expand attribute in the submenu is working great in desktop and mobile version. But the slim version of the left menu appear only with parent icon. We don't see its a problem. it just our observation.

Could you please release this functionality in new Sentinel Theme version? It will be easy for us to replace the existing jar file and java scripts.

Looking forward for your response.

Thank you for your great support.

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

24 Nov 2015, 10:07

Sorry, we have not a plan for this issue in next release.

Locked

Return to “Sentinel”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 2 guests