右键单击primefaces treenode时,select事件不会触发

时间:2015-02-27 10:07:20

标签: jsf select primefaces tree contextmenu

我有jsf页面:

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

控制器:

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

问题是当我左键单击treenode时,ajax事件只选择fire,当右键单击它时不起作用。当我右键单击节点时,有没有办法让它工作?任何帮助都会很棒。

2 个答案:

答案 0 :(得分:1)

在Primefaces 5.x(我使用5.1,但也应该在较新的版本上工作),您应该能够通过在JSF页面中添加与contextMenu相关的ajax事件来解决您的问题,如下所示:

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

我倾向于选择已经发布的解决方案(#34;覆盖&#34; Primefaces onRightClick功能的解决方案)有三个原因。

首先,没有必要修改Primefaces javascript(如果更新的版本有什么改变呢?在这种情况下,您可能需要修改自定义脚本!)

其次,您可能希望将侦听器onNodeSelectListener的行为分开,具体取决于在辅助bean中使用e.isContextMenu()触发的单击(左侧或右侧),因此控制器可能会变为类似:

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

Primefaces脚本true的{​​{1}}中的第二个参数this.selectNode(d, true)正是出于此目的。换句话说,通过使用nodeRightClick(如重写脚本那样),将无法确定是通过左键还是右键单击调用了侦听器。

最后,您可能希望在JSF页面中为两个事件(this.selectNode(d)onRightClickSelectListener)使用不同的侦听器(select),如下所示:

contextMenu

并因此在支持bean中,如:

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

因此,仅使用public void onNodeSelectListener(NodeSelectEvent e) { // called when a select event occurs } public void onRightClickSelectListener(NodeSelectEvent e) { // called when a contextMenu event occurs } 进行右键点击,而不是使用contextMenu event进行两次点击,无论如何都可能是一种更清晰的方法。

希望有所帮助。

答案 1 :(得分:0)

我认为你面临同样的problem I was having。我仍然不知道为什么 在PrimeFaces展示中工作,但我能够通过取代PrimeFaces来解决这个问题。 nodeRightClick处理程序(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)
        }
    }
}