Jasper de Vries February 2016

Selected tree node not set when context menu action is invoked

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, and I suppose I've got everything lined up. What am I doing wrong?

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.

Bean

I don't think the bean code is relevant (it is ViewScoped and there is a private TreeNode selectedNode with getter and setter).

Here are the interesting bits though:

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();
}

XHTML

<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         

Answers


sghaier ali February 2016

hy,
is a bug in primefaces.
You can fixed this issue by youself. For it you neccessary add verification in the primefaces js file which mouse button has been pressed. You can override file primefaces.js in your project, find first call function selectNode(d) and add follow checking:

if (e.which == 1) {
    this.selectNode(d)
    this.cursorNode = d;
}

This is part of code you can find then function nodeClick: function (e, a) is called:

nodeClick: function (e, a) {
    PrimeFaces.clearSelection();
    if ($(e.target).is(":not(.ui-tree-toggler)")) {
        var d = a.parent();
        if (this.cfg.onNodeClick) {
            this.cfg.onNodeClick.call(this, d)
        }
        if (a.hasClass("ui-tree-selectable") && this.cfg.selectionMode) {
            var c = this.isNodeSelected(d), f = e.metaKey || e.ctrlKey, b = e.shiftKey;
            if (this.isCheckboxSelection()) {
                this.toggleCheckboxNode(d)
            } else {
                if (c && f) {
                    this.unselectNode(d)
                } else {
                    if (this.isSingleSelection() || (this.isMultipleSelection() && !f)) {
                        this.unselectAllNodes()
                    }
                    if (this.isMultipleSelection && b) {
                    } else {
                        if (e.which == 1) {
                             this.selectNode(d);
                             this.cursorNode = d;
                        }
                    }
                }
            }
        }
    }
}


Jasper de Vries March 2016

It turns out you need the undocumented contextMenu Ajax event listener.

See http://stackoverflow.com/a/35800393/880619

Post Status

Asked in February 2016
Viewed 1,550 times
Voted 10
Answered 2 times

Search




Leave an answer