Dynamic Menus

I need to manage the display of menus based on user roles and in order to achieve this feat I would have to store this menu items and their respective urls in the database.  Then accordingly relate them to their respective window/form permission that have sets of permission maps for each role.

The permissions and permission maps for the various roles is already done so what is of concern now is being able to create the menus dynamically from a database table.

Step one: Lets create the table Dynamicmenu  with the following columns;

  • ID- pk
  • Label -menu title
  • url
  • parentMenu -self referencing fk to ID
  • parent – Boolean identifying if menu has submenus

There are many more attributes that go with a menu item and you can add columns for them as you wish. What is important to note here is the ‘parentMenu’ foreign key that is self referencing, I will use this to define child menu items and sub-menus.

Once we have the table set, the next step is to define the class that will read this table and derive the menu tree. There will definitely be a recursive method to iterate through your table as it creates the sub-menus and menus items. I will be using the Primefaces DefaultMenuModel. Here is a snippet of the class showing the recursive method.

/* Other methods */

DefaultMenuModel model = new DefaultMenuModel();
model.addElement(getFileMenu());

public DefaultSubMenu getFileMenu() {
List<Dynamicmenu> dMenuList = (List<Dynamicmenu>) dynamicmenuService
.findByQuery(“select * from dynamicmenu where parentMenu is null”);
DefaultSubMenu fileMenu = new DefaultSubMenu(“MENU”);

for (Dynamicmenu dMenu : dMenuList) {
if (dMenu.isParent()) {
DefaultSubMenu pMenu = new DefaultSubMenu(dMenu.getLabel());
pMenu.setIcon(“ui-icon ui-icon-triangle-1-e”);
if (getSubmenus(dMenu, pMenu) > 0) {
fileMenu.addElement(pMenu);
}
} else {
DefaultMenuItem mItem = new DefaultMenuItem(dMenu.getLabel());
mItem.setUrl(dMenu.getUrl());
mItem.setTitle(dMenu.getLabel());
mItem.setStyleClass(“FontNormal Fs15”);
fileMenu.addElement(mItem);
}
}

fileMenu.setId(“fileItem0”);

return fileMenu;
}

public int getSubmenus(Dynamicmenu pMenu, DefaultSubMenu parentMenu) {
List<Dynamicmenu> dMenuList = (List<Dynamicmenu>) dynamicmenuService
.findByQuery(“select * from dynamicmenu where parentMenu=”+pMenu.getId()+” “);
for (Dynamicmenu childMenu : dMenuList) {
if (childMenu.isParent()) {
DefaultSubMenu subMenu = new DefaultSubMenu(childMenu.getLabel());
subMenu.setIcon(“ui-icon ui-icon-triangle-1-e”);
if (getSubmenus(childMenu, subMenu) > 0) {
parentMenu.addElement(subMenu);
}
} else {
DefaultMenuItem mItem = new DefaultMenuItem(childMenu.getLabel());
mItem.setUrl(childMenu.getUrl());
mItem.setTitle(childMenu.getLabel());
parentMenu.addElement(mItem);

}
}
return parentMenu.getElementsCount();
}

The getFileMenu() method is responsible for getting all the top-level (parent) menus. Once we have that we need to iterate through the list and determine if we need to create a MenuItem or a SubMenu for each. Here is where the parent boolean column comes in handy, so I check if isParent() I create a submenu expecting more menus under it and then call the getSubmenus(childMenu, subMenu) method to get sublevel menus, otherwise I create a menu item and add it to the fileMenu.

The getSubmenus(Dynamicmenu pMenu, DefaultSubMenu parentMenu) is the recursive loop that calls itself for every time the Dynamicmenu object isParent() and adding it to a submenu until it reaches the last level menu and creates a menu item and exits to the next submenu and repeats. It returns a count of the elements is has created inside it and I use this to determine if to add it to the parent menu or not. Some sub menus would turnout empty because a user has not been assigned any of the items under it or has no credentials to access them, if its empty there is no need to add it.

No you add it to your page and that’s it.

    <h:form id=”menuform”>
<p:menu model=”${mainMenuModel.model}” />
</h:form>

Advertisements

One thought on “Dynamic Menus

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s