我需要树的动态上下文菜单(基于某些权限在每个节点上不同,因此我不能为每个节点使用不同的菜单类型)。
我使用支持bean模型实现了它,并在每次选择更改时更新它。一切正常,但如果用户右键单击未选择的节点,则会发生以下情况:
我发现我的解决方法是treetable PEP-0008 ... e-of-tree /
但它不适用于树。
欢迎任何提示
PF 6.1.2,WF 10.0.0
答案 0 :(得分:0)
我想我找到了一个有效的解决方案。我已经根据primeface的展示建立了一个例子
BasicView.java
package example;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import org.primefaces.context.RequestContext;
import org.primefaces.event.NodeSelectEvent;
import org.primefaces.model.DefaultTreeNode;
import org.primefaces.model.TreeNode;
@ManagedBean(name="treeBasicView")
@ViewScoped
public class BasicView implements Serializable {
private TreeNode root;
@ManagedProperty(value="#{selectionView}")
SelectionView selectionView;
@PostConstruct
public void init() {
root = new DefaultTreeNode("Root", null);
TreeNode node0 = new DefaultTreeNode("Node 0", root);
TreeNode node1 = new DefaultTreeNode("Node 1", root);
TreeNode node00 = new DefaultTreeNode("Node 0.0", node0);
TreeNode node01 = new DefaultTreeNode("Node 0.1", node0);
TreeNode node10 = new DefaultTreeNode("Node 1.0", node1);
node1.getChildren().add(new DefaultTreeNode("Node 1.1"));
node00.getChildren().add(new DefaultTreeNode("Node 0.0.0"));
node00.getChildren().add(new DefaultTreeNode("Node 0.0.1"));
node01.getChildren().add(new DefaultTreeNode("Node 0.1.0"));
node10.getChildren().add(new DefaultTreeNode("Node 1.0.0"));
root.getChildren().add(new DefaultTreeNode("Node 2"));
}
public TreeNode getRoot() {
return root;
}
public void onNodeSelect(NodeSelectEvent event){
checkSelectionChanged();
}
public void onRightClickSelectListener(NodeSelectEvent e) {
checkSelectionChanged();
}
/* Update the contextMenu only if the selection has changed */
private void checkSelectionChanged(){
if(this.getSelectionView().getSelectedNode()!=this.getSelectionView().getPrevSelectedNode()){
RequestContext.getCurrentInstance().update("treeform:mytreeContexMenu");
}
}
public SelectionView getSelectionView(){
return selectionView;
}
public void setSelectionView(SelectionView selectionView){
this.selectionView=selectionView;
}
}
MenuView.java
package example;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.RequestScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.menu.*;
@ManagedBean
@RequestScoped
public class MenuView {
private MenuModel model;
@ManagedProperty(value="#{selectionView}")
SelectionView selectionView;
public void init() {
model = new DefaultMenuModel();
//First submenu
DefaultSubMenu firstSubmenu = new DefaultSubMenu("Dynamic Submenu");
DefaultMenuItem item = new DefaultMenuItem("External");
item.setUrl("http://www.primefaces.org");
item.setIcon("ui-icon-home");
firstSubmenu.addElement(item);
model.addElement(firstSubmenu);
//Second submenu
DefaultSubMenu secondSubmenu = new DefaultSubMenu("Dynamic Actions");
this.getTreeSelectionView().getSelectedNode();
if(this.getTreeSelectionView().getSelectedNode()==null){
return;
}
String nodeText = this.getTreeSelectionView().getSelectedNode().getData().toString();
if(nodeText.contains("0")){ //just a condition
item=new DefaultMenuItem("Action for 0");
item.setIcon("ui-icon-disk");
item.setCommand("#{menuView.save}");
secondSubmenu.addElement(item);
}
if(nodeText.contains("1")){ //just a condition
item=new DefaultMenuItem("Action for 1");
item.setIcon("ui-icon-close");
item.setCommand("#{menuView.delete}");
item.setAjax(false);
secondSubmenu.addElement(item);
}
if(nodeText.contains("2")){ //just a condition
item=new DefaultMenuItem("Action for 2");
item.setIcon("ui-icon-search");
item.setCommand("#{menuView.redirect}");
secondSubmenu.addElement(item);
}
model.addElement(secondSubmenu);
}
public MenuModel getModel() {
if(model==null){
this.init();
}
return model;
}
public void save() {}
public void update() {}
public void delete() {}
public SelectionView getTreeSelectionView(){
return selectionView;
}
public void setSelectionView(SelectionView selectionView){
this.selectionView=selectionView;
}
}
SelectionView.java
package example;
import java.io.Serializable;
import javax.annotation.PostConstruct;
import javax.faces.application.FacesMessage;
import javax.faces.bean.ManagedBean;
import javax.faces.bean.ManagedProperty;
import javax.faces.bean.ViewScoped;
import javax.faces.context.FacesContext;
import org.primefaces.model.TreeNode;
@ManagedBean(name="selectionView")
@ViewScoped
public class SelectionView implements Serializable {
private TreeNode selectedNode;
private TreeNode prevSelectedNode;
public TreeNode getSelectedNode() {
return selectedNode;
}
public void setSelectedNode(TreeNode selectedNode) {
this.setPrevSelectedNode(this.selectedNode);
this.selectedNode = selectedNode;
}
public TreeNode getPrevSelectedNode(){
return prevSelectedNode;
}
public void setPrevSelectedNode(TreeNode prevSelectedNode){
this.prevSelectedNode=prevSelectedNode;
}
}
tree.xhtml
<!DOCTYPE html>
<html
xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://java.sun.com/jsf/core"
xmlns:h="http://java.sun.com/jsf/html"
xmlns:p="http://primefaces.org/ui">
<h:head>
<title><h:outputText value="Test tree"/></title>
<h:outputScript library="scripts" name="navigator.js"/>
</h:head>
<h:body>
<h:form id="treeform">
<p:tree value="#{treeBasicView.root}" var="node" dynamic="true" id="mytree" selectionMode="single" selection="#{selectionView.selectedNode}">
<p:ajax event="select" listener="#{treeBasicView.onNodeSelect}"/>
<p:ajax event="contextMenu" listener="#{treeBasicView.onRightClickSelectListener}" oncomplete="PF('mytreeContexMenuVar').show()"/>
<p:treeNode>
<h:outputText value="#{node}" />
</p:treeNode>
</p:tree>
<p:contextMenu for="mytree" id="mytreeContexMenu" model="#{menuView.model}" widgetVar="mytreeContexMenuVar">
</p:contextMenu>
</h:form>
</h:body>
</html>
mytree.js contextMenu应该更新,而不是显示 (基于此处的示例:https://dnhome.wordpress.com/2013/10/07)
var siteFunctions = {
//patch to fix a problem that the context menu disappears after update
//delay the show to occure after the update
patchContextMenuShow: function() {
'use strict';
var protShow = PrimeFaces.widget.ContextMenu.prototype.show;
siteFunctions.patchContextMenuShow.lastEvent = null;
PrimeFaces.widget.ContextMenu.prototype.show = function(e) {
var ret;
if (e) {
siteFunctions.patchContextMenuShow.lastEvent = e;
siteFunctions.patchContextMenuShow.lastEventArg = arguments;
siteFunctions.patchContextMenuShow.lastEventContext = this;
//prevent default browser context menu
e.preventDefault();
e.stopPropagation();
} else if (siteFunctions.patchContextMenuShow.lastEvent) {
ret = protShow.apply(siteFunctions.patchContextMenuShow.lastEventContext, siteFunctions.patchContextMenuShow.lastEventArg);
siteFunctions.patchContextMenuShow.lastEvent = null;
}
return ret;
};
}
};
$(document).ready(function() {
'use strict';
try {
siteFunctions.patchContextMenuShow();
} catch (e) {
console.error(e);
}
});