Reputation: 20168
I'm creating a PrimeFaces (5.3) tree with a context menu. Selected nodes should be stored in #{myBean.selectedNode}
. When I select a node using the left mouse button the correct node is set. But, when I try to run an action on a node from a context menu, without selecting it first, the correct node isn't set (the setter in my bean is not called).
I'm following the example in the PrimeFaces showcase. As you can see, in the PrimeFaces showcase you are able to immediately right click a node, click "View", and the growl will display the correct node.
Here is my setup:
It is ViewScoped
and there is a private TreeNode selectedNode
with getter and setter.
Here are the interesting bits:
public void onNodeSelect(NodeSelectEvent event) {
MyTreeNode myTreeNode = (MyTreeNode) event.getTreeNode();
myController.setSelected(myTreeNode.getEntity());
}
public void addChild(String name) {
MyTreeNode myTreeNode = (MyTreeNode) selectedNode;
MyTreeNode childNode = myTreeNode.addChild(name);
myController.setSelected(childNode.getEntity());
myController.insert();
}
<h:form id="mainForm">
<p:tree value="#{myBean.root}" var="node"
id="myTree" dynamic="true"
selectionMode="single" selection="#{myBean.selectedNode}">
<p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed"
type="myType">
<h:outputText value="#{node}"/>
</p:treeNode>
<p:ajax event="select" listener="#{myBean.onNodeSelect}" />
</p:tree>
<p:contextMenu for="myTree">
<p:menuitem action="#{myBean.addChild('new')}"
value="Add"
process="@this"
update=":mainForm:myTree"/>
</p:contextMenu>
</h:form>
I was able to solve this problem by replacing the PrimeFaces.widget.BaseTree.nodeRightClick
function in JavaScript in order to trigger the fireNodeSelectEvent
on right click.
PrimeFaces.widget.BaseTree.prototype.nodeRightClick = function(e, a) {
PrimeFaces.clearSelection();
if ($(e.target).is(":not(.ui-tree-toggler)")) {
var d = a.parent(), b = a.hasClass("ui-tree-selectable");
if (b && this.cfg.selectionMode) {
var c = this.isNodeSelected(d);
if (!c) {
if (this.isCheckboxSelection()) {
this.toggleCheckboxNode(d)
} else {
this.unselectAllNodes();
// Fixed right click selecting
// original code: this.selectNode(d, true)
this.selectNode(d); // <-- Fix
}
}
this.fireContextMenuEvent(d)
}
}
}
This seemed like a bug to me, so I created an issue on GitHub. This issues was closed as "won't fix" with the comment "Please use contextMenu event".
I've checked the tree and contextMenu section of the documentation twice. What event should be used where? I've asked the same question at GitHub, but there was no response.
Upvotes: 2
Views: 3415
Reputation: 12337
Reading the issue you reported, I investigated the code (it is open). It seems that p:tree
has some undocumented events, contextMenu
being one of them (dragdrop
being the other).
The 5.3 java-source and 5.3 javascript-source contains references to a contextMenu
event, so
<p:ajax event="contextMenu" listener="#{myBean.onContextMenu}" />
and
public void onContextMenu(NodeSelectEvent event) {
MyTreeNode myTreeNode = (MyTreeNode) event.getTreeNode();
myController.setSelected(myTreeNode.getEntity());
}
will work. Notice that there is no ContextMenuEvent
but that it accepts/needs a NodeSelectEvent
Upvotes: 8