简体   繁体   中英

select event doesn't fire when right click on primefaces treenode

I have jsf page :

<p:contextMenu for="treeProfileSetEvent"
                                   nodeType="PROFILESET">
                        <p:menuitem value="#{lang['common.button.add']}" 
                                    icon="ui-icon-plus"
                                    update="@([id$=editPanel_event])"
                                    actionListener="#{profileSetEventController.prepareAdd()}">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" value="#{vpcrfConst.BTN_ADD}" />
                        </p:menuitem>                     
                        <p:menuitem value="#{lang['common.button.delete']}" 
                                    icon="ui-icon-close"
                                    update="@([id$=btnPanel]) @([id$=treeProfileSetEvent]) @([id$=msgInfo])" 
                                    actionListener="#{profileSetEventController.prepareDelete()}"
                                    oncomplete="PF('deleteDialog').show()">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_DELETE}" />                            
                        </p:menuitem>                                          
                    </p:contextMenu>
                    <p:contextMenu for="treeProfileSetEvent"
                                   nodeType="PARENT">   
                        <p:menuitem value="#{lang['common.button.edit']}" 
                                    icon="ui-icon-pencil"                                    
                                    update="@([id$=editPanel_profileSetEvent])"
                                    actionListener="#{profileSetEventController.prepareEdit()}">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_EDIT}" />
                        </p:menuitem>
                        <p:menuitem value="#{lang['common.button.delete']}" 
                                    icon="ui-icon-close"
                                    update="@([id$=btnPanel]) @([id$=treeProfileSetEvent]) @([id$=msgInfo])" 
                                    actionListener="#{profileSetEventController.prepareDelete()}"
                                    oncomplete="PF('deleteDialog').show()">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_DELETE}" />                            
                        </p:menuitem>                                          
                    </p:contextMenu>
                    <p:contextMenu for="treeProfileSetEvent"                                  
                                   nodeType="PARENT_HAS_CHILD">
                        <p:menuitem value="#{lang['common.button.delete']}" 
                                    icon="ui-icon-close"
                                    ajax="true"
                                    update="@([id$=btnPanel]) @([id$=treeProfileSetEvent]) @([id$=msgInfo])" 
                                    actionListener="#{profileSetEventController.prepareDelete()}"
                                    oncomplete="PF('deleteDialog').show()">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_DELETE}" />                            
                        </p:menuitem>                                          
                    </p:contextMenu>
                    <p:contextMenu for="treeProfileSetEvent"
                                   nodeType="CHILD">    
                        <p:menuitem value="#{lang['common.button.edit']}" 
                                    icon="ui-icon-pencil"
                                    update="@([id$=editPanel_profileSetEvent])"
                                    actionListener="#{profileSetEventController.prepareEdit()}">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_EDIT}" />
                        </p:menuitem>
                        <p:menuitem value="#{lang['common.button.delete']}" 
                                    icon="ui-icon-close"
                                    update="@([id$=btnPanel]) @([id$=treeProfileSetEvent]) @([id$=msgInfo])" 
                                    actionListener="#{profileSetEventController.prepareDelete()}"
                                    oncomplete="PF('deleteDialog').show()">
                            <f:setPropertyActionListener target="#{profileSetEventController.formStatus}" 
                                                         value="#{vpcrfConst.BTN_DELETE}" />                            
                        </p:menuitem>                                          
                    </p:contextMenu>
                    <p:tree id="treeProfileSetEvent"
                            value="#{profileSetEventController.root}"
                            selection="#{profileSetEventController.selectedNode}"
                            dynamic="true"                            
                            selectionMode="single"   
                            animate="true"
                            cache="true"
                            var="ps"
                            styleClass="vpcrf-tree-50pc">
                        <p:ajax event="select" listener="#{profileSetEventController.onNodeSelectListener}" update="@([id$=btnPanel]) @([id$=dlgProfileSetEvent])" />
                        <p:ajax event="expand" listener="#{profileSetEventController.onNodeExpandListener}" update="@([id$=btnPanel]) @([id$=dlgProfileSetEvent])" />
                        <p:treeNode id="parentNode"                                     
                                    icon="vpcrf-icon-profile" 
                                    type = "PROFILESET">
                            <h:outputText value="#{ps}" title="#{ps}"
                                          styleClass="vpcrf-txt-400" />
                        </p:treeNode>
                        <p:treeNode id="eventParent" icon="vpcrf-icon-event-parent" type = "PARENT">
                            <h:outputText value="#{ps}" title="#{ps}"
                                          styleClass="vpcrf-txt-400" />
                        </p:treeNode>
                        <p:treeNode id="eventParentHasChild" icon="vpcrf-icon-event-parent" type = "PARENT_HAS_CHILD">
                            <h:outputText value="#{ps}" title="#{ps}"
                                          styleClass="vpcrf-txt-400" />
                        </p:treeNode>
                        <p:treeNode icon="vpcrf-icon-event-child" type = "CHILD">
                            <h:outputText value="#{ps}" title="#{ps}"
                                          styleClass="vpcrf-txt-400" />
                        </p:treeNode>
                    </p:tree>

And the controller :

    public void onNodeSelectListener(NodeSelectEvent e) {
        try {            
            selectedNode = e.getTreeNode();
            if (selectedNode.getData() instanceof ProfileSetDTO) {
                selectedProfileSet = (ProfileSetDTO) selectedNode.getData();
            } else {
                event = (EventDTO) selectedNode.getData();
                System.out.println(event.getEventName());
            }
            profileSet = null;
            formStatus = Const.CLEAR;
        } catch (Exception ex) {
            reportError("msgInfo", "msg.error.unknown");
            logger.error(ex, ex);
        }
    }

The problem is ajax event select only fire when I left-click on treenode, when right-click it doesn't work. Is there any way to make it work when I right-click on node ? Any help would be great.

On Primefaces 5.x (I'm using 5.1, but should work also on newer versions), you should be able to solve your issue by adding an ajax event related to contextMenu in the JSF page, as follows:

<p:ajax event="contextMenu" listener="#{profileSetEventController.onNodeSelectListener}" update="@([id$=btnPanel]) @([id$=dlgProfileSetEvent])" />

I tend to prefer this solution to the one already posted (the one that "overrides" the Primefaces onRightClick function) for three reasons.

First, there is no need to modify the Primefaces javascript (what if a newer version changes something about it? It's likely that, in this case, you have to modify your custom script!)

Second, you may want to separate the behavior of the listener onNodeSelectListener depending on which click (left or right) is fired by using e.isContextMenu() in the backing bean, so the controller may become something like:

public void onNodeSelectListener(NodeSelectEvent e) {
    if (e.isContextMenu()) {
      // right click has been fired
    } else {
      // left click has been fired
    }
}

The second parameter true in this.selectNode(d, true) of the Primefaces script nodeRightClick serves exactly this purpose. In other words, by using this.selectNode(d) (as the overriding script does), it will be not possible to decide whether the listener has been invoked by a left or a right click.

Last, you may want to use a different listener ( onRightClickSelectListener ) for the two events ( select and contextMenu ) in the JSF page, as follows:

<p:ajax event="select" listener="#{profileSetEventController.onNodeSelectListener}" update="@([id$=btnPanel]) @([id$=dlgProfileSetEvent])" />
<p:ajax event="contextMenu" listener="#{profileSetEventController.onRightClickSelectListener}" update="@([id$=btnPanel]) @([id$=dlgProfileSetEvent])" />

and consequentely in the backing bean, as:

public void onNodeSelectListener(NodeSelectEvent e) {
   // called when a select event occurs
}

public void onRightClickSelectListener(NodeSelectEvent e) {
  // called when a contextMenu event occurs
}

Therefore using a contextMenu event only for the right click, instead of using select event for both clicks, may be a cleaner approach anyway.

Hope that helps.

I think you are facing the same problem I was having . I still don't get why this is working in the PrimeFaces showcase, but I was able to fix it by replacing PrimeFaces' nodeRightClick handler (JavaScript):

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM