Data iteration components, such as dataTable
, tree
, and treeTable
, have a special integration with the context menu. These components can display a context menu for every right-click of the mouse on any row in dataTable
or any node in tree
.
In this recipe, we will integrate a context menu with the tree
component. Integration with dataTable
or treeTable
is similar and described well in the PrimeFaces User's Guide documentation (http://primefaces.org/documentation.html).
We will develop a context menu with two menu items—View and Delete. A View item shows the currently selected tree node, and the Delete item removes it. We would like to implement this behavior for all tree nodes. The following listing demonstrates the integration of p:contextMenu
with p:tree
:
<p:growl id="growl" showDetail="true"/> <p:contextMenu for="fileSystem"> <p:menuitem value="View" update="growl" actionListener="#{contextMenuBean.viewNode}" icon="ui-icon-search"/> <p:menuitem value="Delete" update="fileSystem" actionListener="#{contextMenuBean.deleteNode}" icon="ui-icon-close"/> </p:contextMenu> <p:tree id="fileSystem" value="#{contextMenuBean.root}" var="node" dynamic="true" cache="false" selectionMode="single" selection="#{contextMenuBean.selectedNode}"> <p:ajax event="select" listener="#{contextMenuBean.onNodeSelect}"/> <p:ajax event="unselect" listener="#{contextMenuBean.onNodeUnselect}"/> <p:treeNode> <h:outputText value="#{node}"/> </p:treeNode> </p:tree>
We can see the context menu over tree nodes in the following screenshot. The View item that has been clicked on shows a growl
notification.
The view-scoped CDI bean, ContextMenuBean
, creates tree
. The bean implements all listener methods. This is shown in the following code:
@Named @ViewScoped public class ContextMenuBean implements Serializable { private TreeNode root; private TreeNode selectedNode; @PostConstruct protected void initialize() { root = new DefaultTreeNode("Root", null); TreeNode node0 = new DefaultTreeNode("Folder 0", root); ... } public TreeNode getRoot() { return root; } public TreeNode getSelectedNode() { return selectedNode; } public void setSelectedNode(TreeNode selectedNode) { this.selectedNode = selectedNode; } public void onNodeSelect(NodeSelectEvent event) { selectedNode = event.getTreeNode(); } public void onNodeUnselect(NodeUnselectEvent event) { selectedNode = null; } public void viewNode() { if (selectedNode == null) { return; } FacesMessage msg = new FacesMessage( FacesMessage.SEVERITY_INFO, "Selected", selectedNode.getData().toString()); FacesContext.getCurrentInstance().addMessage(null, msg); } public void deleteNode() { if (selectedNode == null) { return; } selectedNode.getChildren().clear(); selectedNode.getParent().getChildren(). remove(selectedNode); selectedNode.setParent(null); selectedNode = null; } }
When a menu item is clicked on, the whole tree
component gets processed and the currently selected node is stored in the ContextMenuBean
bean via the #{contextMenuBean.selectedNode}
EL expression. After that, an action listener is called and can access the selected node. The viewNode()
action listener only generates a message with the name of the selected node. The subsequent AJAX response updates p:growl
. We see a growl
notification. The deleteNode()
action listener deletes the selected node from the tree model. The subsequent AJAX response updates p:tree
(see <p:menuitem … update="fileSystem"/>
). We see the tree updated without the deleted node.
The nodeType
attribute is featured by p:contextMenu
. This attribute specifies the type of tree nodes to attach to. It matches the type
attribute of p:treeNode
. Hence, different menus can be attached to particular tree nodes by matching the menu's nodeType
to the tree node's type
.
Explore data iteration components in Chapter 5, Data Iteration Components. You will find many tips to use p:tree
, p:dataTable
, and p:treeTable
.
This recipe is available in the demo web application on GitHub (https://github.com/ova2/primefaces-cookbook/tree/second-edition). Clone the project if you have not done it yet, explore the project structure, and build and deploy the WAR file on application servers compatible with Servlet 3.x, such as JBoss WildFly and Apache TomEE.
The showcase for the recipe is available at http://localhost:8080/pf-cookbook/views/chapter6/contextMenuIntegration.jsf
.