Sentinel left SubMenu Expand/Collapse based on a parameter.

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

24 Nov 2015, 15:26

Hi Aragon,

If i built the jar file with the updated java file that you provided earlier, then I have to do the manual build for future releases too. So i am worried about merging the new release in the future. I feel this option will be a overhead for us in the future. So give us a other feasible solution.

This is really a cool feature i would like to receive as an official release. Please let us know what you can do for us.

Thanks and I appreciate your help in this.

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

30 Nov 2015, 11:29

I will work on this issue and get back with a new solution to you.

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

30 Nov 2015, 12:50

I think you can create a new class (extends SentinelMenuRenderer) and use this class to render the menu in your project. Also, you can override functions of layout.js in a custom JS file and add this file in your template. If you make this changes, you do not have to modify your files for each Sentinel Version.

Please add this files and changes in your project;

SentinelCustomMenuRenderer.java

Code: Select all

package myPackage.component.menu;

import java.io.IOException;
import java.util.List;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import org.primefaces.component.menu.AbstractMenu;
import org.primefaces.model.menu.MenuElement;
import org.primefaces.model.menu.MenuItem;
import org.primefaces.model.menu.Separator;
import org.primefaces.model.menu.Submenu;

public class SentinelCustomMenuRenderer extends SentinelMenuRenderer {

    @Override
    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);
                }
            }
        }
    }
}

customLayout.js (please import this file into template.xhtml)

Code: Select all


/* Override some functions in layout.js */
Sentinel.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();
            }
        }
    }
};

Sentinel.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');
    }
};

Sentinel.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'));
};

Sentinel.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 = [];
};

faces-config.xml

Code: Select all

<render-kit>
   <renderer>
      <component-family>org.primefaces.component</component-family>
      <renderer-type>org.primefaces.component.SentinelMenuRenderer</renderer-type>
      <renderer-class>myPackage.component.menu.SentinelCustomMenuRenderer</renderer-class>
   </renderer>
</render-kit>

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

30 Nov 2015, 15:51

Hi Aragorn,

Its working great.

I like your idea to extend the feature from sentinel.

I'll reach you again, if it crashes due to the new SENTINEL JAR file release. I hope this fix will not break in the future releases.

Thank you so much for your great support.

I really appreciate your help in this.

Thanks,
-Senthil

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

24 Dec 2015, 12:54

Glad to hear, thanks ;) Sorry, we don't think this feature in next release for now.

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

11 Oct 2016, 19:03

Hi,

We upgraded our sentinel theme jar and other resources files into sentinel theme 2.1.1. The Expanded property in the submenu with custom code is not working as expected. It was working on the older version as we confirmed eariler. Please help us to update the custom code that you provided for the older version to make it work for expand and collapse feature.

If you need any additional information please feel free comment.

Thank you in advance.

Regards,
-Senthil

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

21 Oct 2016, 08:12

Please only change my customLayout.js;

Code: Select all

/* Override some functions in layout.js */
PrimeFaces.widget.Sentinel.prototype.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();
            }
        }
    }
};

PrimeFaces.widget.Sentinel.prototype.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');
    }
};

PrimeFaces.widget.Sentinel.prototype.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'));
};

PrimeFaces.widget.Sentinel.prototype.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 = [];
};

Also, you can use new sentinel version(2.1.2); http://blog.primefaces.org/?p=4141

senthilrmca
Posts: 11
Joined: 02 Aug 2014, 03:45

21 Oct 2016, 17:27

Thank you aragorn. Its working now. I appreciate it.

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

26 Oct 2016, 16:04

You're welcome!

Locked

Return to “Sentinel”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 2 guests