Home » Java » Enterprise Java » Building dynamic responsive multi-level menus with plain HTML and OmniFaces

About Oleg Varaksin

Oleg Varaksin

Building dynamic responsive multi-level menus with plain HTML and OmniFaces

Recently, I had to create a responsive multi-level menu with JSF 2.2. Requirements: the menu should:
 
 
 
 
 
 
 
 
 

  • be created with dynamic structure from backend
  • be responsive, i.e. desktop- and mobile-friendly
  • have submenu items with navigation links
  • support touch events
  • support keyboard accessibility

PrimeFaces’ menus were not a choice. They can indeed be created programmatically by model, but:

  • they are not really responsive
  • submenu items only collapse / expand the submenus and can not contain navigation links

Well, why not to pick any jQuery based plugin for responsive multi-level menus? There are a lot of plugins. See Useful List of Responsive Navigation and Menu Patterns. I chose FlexNav.

But how to output the dynamic menu structure? ui:repeat is not a choice here because the structure (nested sub menus, etc.) is not known a priori. Fortunately, there is OmniFaces with o:tree, which allows to have full control over the markup of a tree hierarchy by declaring the JSF components or HTML elements in the markup. o:tree does not render any HTML markup by itself. Exactly what I need!

I ended up with this XHTML fragment mixing o:treeNode, o:treeNodeItem, o:treeInsertChildren and HTML elements defined by the mentioned FlexNav menu:

<h:outputScript library="js" name="jquery.flexnav.js"/>
<h:outputStylesheet library="css" name="flexnav.css"/>

<ul id="mainnavi" class="flexnav" data-breakpoint="640" role="navigation">
    <o:tree value="#{mainNavigationBean.treeModel}" var="item">
        <o:treeNode level="0">
            <o:treeNodeItem>
                <li class="item">
                    <a href="#{item.href}" title="#{item.title}">#{item.text}</a>
                    <o:treeInsertChildren/>
                </li>
            </o:treeNodeItem>
        </o:treeNode>
        <o:treeNode>
            <ul>
                <o:treeNodeItem>
                    <li>
                        <a href="#{item.href}" title="#{item.title}">#{item.text}</a>
                        <o:treeInsertChildren/>
                    </li>
                </o:treeNodeItem>
            </ul>
        </o:treeNode>
    </o:tree>
</ul>

<h:outputScript id="mainnaviScript" target="body">
    $(document).ready(function () {
        $("#mainnavi").flexNav({'calcItemWidths': true});
    });
</h:outputScript>

The OmniFaces’ TreeModel with menu items is created programmatically. The Java code looks like:

public TreeModel<NavigationItemDTO> getTreeModel() {
    // get menu model from a remote service
    NavigationContainerDTO rootContainer = remoteService.fetchMainNavigation(...);

    TreeModel<NavigationItemDTO> treeModel = new ListTreeModel<>();
    buildTreeModel(treeModel, rootContainer.getNavItem());

    return treeModel;
}

private void buildTreeModel(TreeModel<NavigationItemDTO> treeModel, List<NavigationItemDTO> items) {
    for (NavigationItemDTO item : items) {
        buildTreeModel(treeModel.addChild(item), item.getNavItem());
    }
}

And the end result (desktop variant):

responsiveMenu

Note that submenus are clickable and can be expanded on mouseover.

You see, JSF is flexible and sometimes you don’t need full-blown components. Have fun!

(0 rating, 0 votes)
You need to be a registered member to rate this.
4 Comments Views Tweet it!
Do you want to know how to develop your skillset to become a Java Rockstar?
Subscribe to our newsletter to start Rocking right now!
To get you started we give you our best selling eBooks for FREE!
1. JPA Mini Book
2. JVM Troubleshooting Guide
3. JUnit Tutorial for Unit Testing
4. Java Annotations Tutorial
5. Java Interview Questions
6. Spring Interview Questions
7. Android UI Design
and many more ....
I agree to the Terms and Privacy Policy

4
Leave a Reply

avatar
4 Comment threads
0 Thread replies
0 Followers
 
Most reacted comment
Hottest comment thread
3 Comment authors
Mücahit AtaşçiNathan HughesJosé Gregorio Castillo Recent comment authors

This site uses Akismet to reduce spam. Learn how your comment data is processed.

  Subscribe  
newest oldest most voted
Notify of
José Gregorio Castillo
Guest
José Gregorio Castillo

Hi Oleg, I was trying to understand this code, but I there’s something that I can not see: has your NavigationItemDto object the menu names and the menuItems in it?. My menu model has to entities, one for the Menu names and other ItemMenu, for the action (navigation to other place). The only thing that I see its to change my model to contain in one Entity the Menu name and the action, if this action is null or empty, means that is a name, so has children, wich has the action. Is this ok or am I wrong?. I… Read more »

Nathan Hughes
Guest

Hello,

I am trying to create a dynamic menu just like this on a wix website.

I am new to the coding for websites and and wondering if the code you have used here is something I could adopt in my wix code. Is that something you might have some insight into?

Thank you

Mücahit Ataşçi
Guest
Mücahit Ataşçi

Can you share NavigationItemDto code ?

Mücahit Ataşçi
Guest
Mücahit Ataşçi

it will be very useful if you helped me to create dynamic menu. Your Above code is clear, but have some trouble with NavigationItemDto . İt would be very useful if you share NavigationItemDto code with us,

thanks in advanced.,

Mücahit ATAŞÇİ