4

This question is mainly directed at the PrimeFaces dev team but maybe someone else knows a workaround. I can't upload screenshots on the PrimeFaces support forums but I can link to my question here.

Reported in PrimeFaces support forums: http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=14022

I have a <p:tree> in my webapp that has selection="single" mode set. Node selection is working normally when the <p:tree> is not inside a <p:dialog> as shown here:

Works OK when not inside a dialog

However, when the <p:tree> is inside a dialog an exception is thrown on the server side each time a node is clicked in the browser. The selection is never registered on the backing bean:

Fails to set selection when inside a dialog

The following stacktrace appears in my server logs once for each time a tree node is clicked by a user in the browser:

    27-Jul-2011 3:21:52 PM com.sun.faces.context.PartialViewContextImpl processPartial
INFO: java.lang.NullPointerException
java.lang.NullPointerException
    at org.primefaces.component.tree.TreeRenderer.decode(TreeRenderer.java:53)
    at javax.faces.component.UIComponentBase.decode(UIComponentBase.java:787)
    at javax.faces.component.UIComponentBase.processDecodes(UIComponentBase.java:1181)
    at com.sun.faces.context.PartialViewContextImpl$PhaseAwareVisitCallback.visit(PartialViewContextImpl.java:506)
    at com.sun.faces.component.visit.PartialVisitContext.invokeVisitCallback(PartialVisitContext.java:183)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1589)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIForm.visitTree(UIForm.java:344)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at javax.faces.component.UIComponent.visitTree(UIComponent.java:1600)
    at com.sun.faces.context.PartialViewContextImpl.processComponents(PartialViewContextImpl.java:376)
    at com.sun.faces.context.PartialViewContextImpl.processPartial(PartialViewContextImpl.java:252)
    at javax.faces.context.PartialViewContextWrapper.processPartial(PartialViewContextWrapper.java:183)
    at javax.faces.component.UIViewRoot.processDecodes(UIViewRoot.java:931)
    at com.sun.faces.lifecycle.ApplyRequestValuesPhase.execute(ApplyRequestValuesPhase.java:78)
    at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
    at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
    at javax.faces.webapp.FacesServlet.service(FacesServlet.java:409)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:304)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.primefaces.webapp.filter.FileUploadFilter.doFilter(FileUploadFilter.java:79)
    at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:243)
    at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:210)
    at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:240)
    at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:164)
    at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:462)
    at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:164)
    at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:100)
    at org.apache.catalina.valves.AccessLogValve.invoke(AccessLogValve.java:563)
    at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:118)
    at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:399)
    at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:317)
    at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:204)
    at org.apache.tomcat.util.net.JIoEndpoint$SocketProcessor.run(JIoEndpoint.java:311)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)

Here is the offending PrimeFaces method:

@Override
public void decode(FacesContext context, UIComponent component) {
    Tree tree = (Tree) component;
    Map<String,String> params = context.getExternalContext().getRequestParameterMap();
    String clientId = tree.getClientId(context);
    TreeModel model = new TreeModel((TreeNode) tree.getValue());

    if(tree.getSelectionMode() != null) {
        String selection = params.get(clientId + "_selection");

        String instantUnselection = params.get(clientId + "_instantUnselection");
        boolean isSingle = tree.getSelectionMode().equalsIgnoreCase("single");

        if(selection.equals("")) {
            if(isSingle)
                tree.setSelection(null);
            else
                tree.setSelection(new TreeNode[0]);
        }
        else {
            String[] selectedRowKeys = selection.split(",");

            if(isSingle) {
                TreeNode selectedNode = treeExplorer.findTreeNode(selectedRowKeys[0], model);
                tree.setSelection(selectedNode);
            }
            else {
                TreeNode[] selectedNodes = new TreeNode[selectedRowKeys.length];

                for(int i = 0 ; i < selectedRowKeys.length; i++) {
                    selectedNodes[i] = treeExplorer.findTreeNode(selectedRowKeys[i], model);
                    model.setRowIndex(-1);  //reset
                }

                tree.setSelection(selectedNodes);
            }
        }
    }

    decodeBehaviors(context, component);
}

The line that causes the exception is this one:

        if(selection.equals("")) {

In the case where the <p:tree> is located inside a <p:dialog> the value of selection is always null.

Any idea how to work around this issue?

I am using today's nightly build of PF 3.0-M3-SNAPSHOT. Same thing happens with PF 3.0-M2. Exhibits the same behavior in both IE 7 and Firefox 4.0.1.

Jim Tough
  • 14,843
  • 23
  • 75
  • 96
  • I have the same exact problem. It seems that we both have the same problems the same days ;) http://stackoverflow.com/questions/6824705/jsf-2-0-update-a-primefaces-dialog-not-working-the-first-time – Sydney Jul 27 '11 at 19:35
  • haha, nice! I wasted so much time today trying to figure out why my freakin tree selection wouldn't work. I put a simplified example into a test app and it worked right away. I eventually figured out that the dialog was the only real diffence and I was not too pleased. I suppose I'll have to redesign my pages to work without dialogs until PrimeFaces 3.0 is more stable. It's a shame because they look so nice when they work correctly. – Jim Tough Jul 28 '11 at 02:35
  • I feel for you but I have pretty much resigned myself to believe that ANYTHING inside a `` is a hot mess. I always anticipate problems and begin thinking about javascript workarounds before I even encounter problems. – maple_shaft Jul 28 '11 at 11:22
  • I don't have the luxury of making JavaScript tweaks. When this application is built it will be maintained by a different group that likely won't have the skills to deal with customized JavaScript code. If a component doesn't work "out of the box" then I need to find an alternative that does. – Jim Tough Jul 28 '11 at 11:50

1 Answers1

1

Discussed on PrimeFaces forums. Similar issue found by another user.

Opened PrimeFaces issue ticket here.

Nathaniel Ford
  • 20,545
  • 20
  • 91
  • 102
Jim Tough
  • 14,843
  • 23
  • 75
  • 96