Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Primefaces: ContextMenu does not appear in overlayPanel

I try to add a contextMenu in a tree to perform a custom action. This tree is implemented inside an overlaypanel. What i observed is that the contextMenu only appears in random situations like after selecting and unselecting some elements on the tree. Any Idea?

<p:overlayPanel id="advancedSearchPanel" 
    styleClass="ui-advanced-search-overlay"
    for="advancedSearch" 
    hideEffect="fade" 
    my="right top" 
    widgetVar="advancedSearchPanelWidgetVar" > 
        <ui:include src="/search/advancedSearch-form.xhtml"/>  
</p:overlayPanel>

advancedSearch-form

<p:panelGrid  id="panelAdvanced" styleClass="borderless">
...
    <p:row> 
        <p:column colspan="4"> 
            <p:outputLabel value="#{text['searchForm.classifiers']}" for="treeClassifier" styleClass="paddingLabelGrid"/>

            <p:contextMenu id="contextSearch" for="treeClassifier">
                <p:menuitem value="Escolha todos" update=":searchForm:treeClassifier" actionListener="#{navBarController.displaySelectedSingle}"/>
            </p:contextMenu>

            <p:tree id="treeClassifier" 
                value="#{navBarController.rootClassifier}" 
                var="node" selectionMode="checkbox" 
                selection="#{navBarController.selectedClassifiers}"
                style="height: 200px;width: 540px; margin-bottom: 0px; overflow: auto" 
                propagateSelectionDown="false"
                propagateSelectionUp="false">

                    <p:ajax event="select" update=":searchForm:btnSearch"/> 
                    <p:ajax event="unselect" update=":searchForm:btnSearch"/>     

                    <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed">
                         <h:outputText value="#{node.description}(#{node.code})"/> 
                    </p:treeNode>  
            </p:tree>
        </p:column>   
    </p:row>
...
like image 394
tech4 Avatar asked Nov 06 '14 12:11

tech4


2 Answers

Try like that:

my advancedSearch-form.xhtml

<?xml version="1.0" encoding="UTF-8" ?>
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:p="http://primefaces.org/ui">      

<h:form id="searchForm">
    <p:panelGrid  id="panelAdvanced" styleClass="borderless">
       <p:row> 
          <p:column colspan="4"> 
               <p:contextMenu id="contextSearch" for="treeClassifier">
                                <p:menuitem value="Escolha todos" update="treeClassifier" actionListener="#{treeView.displaySelectedSingle}"/>
                </p:contextMenu>
                <p:tree id="treeClassifier" value="#{treeView.root}" var="node" selectionMode="checkbox" selection="#{treeView.selectedClassifiers}" 
                            style="height: 200px;width: 540px; margin-bottom: 0px; overflow: auto" 
                            propagateSelectionDown="false" 
                            propagateSelectionUp="false">
                                <p:ajax event="select"  global="false" listener="#{treeView.reset}" /> 
                                <p:ajax event="unselect"  global="false" listener="#{treeView.reset}" />     
                                <p:ajax event="contextMenu" global="false" listener="#{treeView.onContextMenu}"/>     
                                <p:treeNode expandedIcon="ui-icon-folder-open" collapsedIcon="ui-icon-folder-collapsed">
                                    <h:outputText value="#{node.nodeName}"/> 
                                </p:treeNode>  
                </p:tree>
           </p:column>   
       </p:row>
       </p:panelGrid>
</h:form>           
</ui:composition>

And my bean:

@Component(value="treeView")
@Scope(value = "session")
public class TreeView implements Serializable {

    private TreeNode[] selectedClassifiers;

    public TreeNode[] getSelectedClassifiers() {
        return selectedClassifiers;
    }

    public void setSelectedClassifiers(TreeNode[] selectedClassifiers) {
        this.selectedClassifiers = selectedClassifiers;
    }

    private TreeNode selectedClassifier;

    public void reset(){
        selectedClassifier = null;
    }

    public void displaySelectedSingle(){
        if(selectedClassifier != null){
             List<TreeNode> selected = new ArrayList<TreeNode>();
             for(int i=0; i < selectedClassifiers.length; i++){
                 selected.add(selectedClassifiers[i]);
                 if(selectedClassifiers[i].equals(selectedClassifier))
                     selected.addAll(selectionRecursive(selectedClassifier));
             }
             selectedClassifiers = selected.toArray(new TreeNode[selected.size()]);
        }

    }

    public void onContextMenu(NodeSelectEvent event){
     selectedClassifier = event.getTreeNode();
    }

    public List<TreeNode> selectionRecursive(TreeNode node){

        List<TreeNode> selected = node.getChildren();

        for(TreeNode child : node.getChildren()){
            selected.addAll(selectionRecursive(child));
            child.setSelected(true);
        }

        return selected;
    }
}

Method selectionRecursive(TreeNode node) need debug but in my case all work great.

like image 157
0x5a4d Avatar answered Oct 26 '22 23:10

0x5a4d


I'm not sure about what you really want to achieve, but:

You are using 2 features of the tree component.

  • Checkbox (multiple) selection
  • Context menu on nodes

Use of both features at the same time is not currently supported bt Primefaces. Whenever you right-click a node, the contextMenu shows up, then the node is selected/deselected. The contextMenu does not shows up if you click outside a node (container background or between nodes)

If you want a single contextMenu for the whole tree (ie Select All, Unselect All, Select whatever...) so just remove the for attribute on contextMenu :

instead of :

<p:contextMenu id="contextSearch" for="treeClassifier">

just write

<p:contextMenu id="contextSearch">

In this way, the contextMenu appears wherever you right-click on the container (p:column in your case).

like image 37
Stephane Lallemagne Avatar answered Oct 27 '22 01:10

Stephane Lallemagne