0

p:outputLabel will set label for related UIInput, But when it is a child of Omnifaces o:tree It is not work. The validate error message still use clientId.

Omnifaces outputLabel can set label for related UIComponent, and it can work with o:tree.

Primefaces set lable in endEncode method, when work with o:tree, the validateValue method called before endEncode.

Anyone have a workaround?

UPDATE:

version:

  • Java 7
  • TomEE 1.5.1 (myfaces 2.1.9)
  • Primefaces-3.4.1
  • omnifaces-1.3-SNAPSHOT-20121121

Can only reproduce with myfaces, with Mojarra the value of lable in last node will be used for other node's invalid message.

Community
  • 1
  • 1
Yaocl
  • 194
  • 1
  • 12
  • You mean, you have something like `` and the message shows the input's client ID instead of the label value? Sorry, can't reproduce it with Mojarra 2.1.14, PrimeFaces 3.4.2 and latest OmniFaces snapshot. A concrete example, along with the library versions used would be helpful – BalusC Dec 01 '12 at 03:37
  • Yes can only reproduce with myfaces. But mojarra use the last node's label for other node. I attached the examples. – Yaocl Dec 01 '12 at 05:28

2 Answers2

2

I can reproduce your problem. This issue is not related to OmniFaces <o:tree>, but it's actually a bug in PrimeFaces' <p:outputLabel>. As evidence, try using it in an <ui:repeat>, you'll see that exactly the same problem manifests.

As to why it works with OmniFaces <o:outputLabel>, that's because it sets the label as a ValueExpression in the associated input component. The PrimeFaces one sets instead the currently evaluated value which is not necessarily the right value at the moment it's been requested for the message.

I recommend to report it as an issue to the PrimeFaces guys, along with a demo using <ui:repeat>.

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
  • Added a [issue](https://code.google.com/p/primefaces/issues/detail?id=4952) to primefaces. But with ``, Myfaces and Mojarra have same behavor. with `` and Myfaces it seems label attribute not restored when postback. – Yaocl Dec 02 '12 at 01:07
  • I found `Calendar.restoreState` not called when use `` and Myfaces. But with Mojarra it is called. Is it a Myfaces problem? – Yaocl Dec 02 '12 at 03:35
0

This problem have two parts. One is on the primefaces side. It set the evaluated value to the UIInput's label attribute, not the ValueExpression. So all the data use same label. The second is a compatibility problem. The Myfaces 2.1.9 is JSF2.1 and required Component honor the VisitHint.SKIP_ITERATION. Omnifaces not support it. This is a patch make Omnifaces work.

diff -r 0c0b57aa6780 src/org/omnifaces/component/tree/TreeInsertChildren.java
--- a/src/org/omnifaces/component/tree/TreeInsertChildren.java  Fri Nov 30 12:39:03 2012 -0400
+++ b/src/org/omnifaces/component/tree/TreeInsertChildren.java  Sun Dec 02 14:56:02 2012 +0800
@@ -16,6 +16,7 @@
 import javax.faces.component.UIComponent;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;

@@ -66,6 +67,11 @@
     */
    @Override
    public boolean visitTree(VisitContext context, VisitCallback callback) {
+       Boolean skipIterationHint = context.getHints().contains(VisitHint.SKIP_ITERATION);
+       if (skipIterationHint != null && skipIterationHint.booleanValue())
+       {
+           return super.visitTree(context, callback);
+       }
        return Components.getClosestParent(this, Tree.class).visitTreeNode(context, callback);
    }

diff -r 0c0b57aa6780 src/org/omnifaces/component/tree/TreeNodeItem.java
--- a/src/org/omnifaces/component/tree/TreeNodeItem.java    Fri Nov 30 12:39:03 2012 -0400
+++ b/src/org/omnifaces/component/tree/TreeNodeItem.java    Sun Dec 02 14:56:02 2012 +0800
@@ -18,6 +18,7 @@
 import javax.faces.component.UIComponent;
 import javax.faces.component.visit.VisitCallback;
 import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;

@@ -119,6 +120,12 @@
    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" }) // For TreeModel. We don't care about its actual type anyway.
    public boolean visitTree(final VisitContext context, final VisitCallback callback) {
+       
+       Boolean skipIterationHint = context.getHints().contains(VisitHint.SKIP_ITERATION);
+       if (skipIterationHint != null && skipIterationHint.booleanValue())
+       {
+           return super.visitTree(context, callback);
+       }
        if (!isVisitable(context) || getChildCount() == 0) {
            return false;
        }

UPDATE:

This patch have some compile time compatibility with JSF 2.0

diff -r 0c0b57aa6780 src/org/omnifaces/component/tree/TreeFamily.java
--- a/src/org/omnifaces/component/tree/TreeFamily.java  Fri Nov 30 12:39:03 2012 -0400
+++ b/src/org/omnifaces/component/tree/TreeFamily.java  Mon Dec 03 09:33:00 2012 +0800
@@ -16,6 +16,8 @@

 import javax.faces.FacesException;
 import javax.faces.component.UIComponentBase;
+import javax.faces.component.visit.VisitContext;
+import javax.faces.component.visit.VisitHint;
 import javax.faces.context.FacesContext;
 import javax.faces.event.PhaseId;

@@ -136,4 +138,24 @@
        }
    }

+   /**
+    * 
+    * <a href="http://java.net/jira/browse/JAVASERVERFACES_SPEC_PUBLIC-545" >JSF Spec</a>
+    * @param context The faces context
+    * @param visitContext the visit tree context
+    * @return
+    */
+   boolean isSkippingIteration(final VisitContext visitContext) {
+       //
+       try {
+           //JSF 2.1
+           VisitHint skipHint = VisitHint.valueOf("SKIP_ITERATION");
+           return visitContext.getHints().contains(skipHint);
+       }
+       catch(IllegalArgumentException e) {
+           //JSF 2.0
+           Object skipHint = visitContext.getFacesContext().getAttributes().get("javax.faces.visit.SKIP_ITERATION");
+           return Boolean.TRUE.equals(skipHint);
+       }
+   }
 }
\ No newline at end of file
diff -r 0c0b57aa6780 src/org/omnifaces/component/tree/TreeInsertChildren.java
--- a/src/org/omnifaces/component/tree/TreeInsertChildren.java  Fri Nov 30 12:39:03 2012 -0400
+++ b/src/org/omnifaces/component/tree/TreeInsertChildren.java  Mon Dec 03 09:33:00 2012 +0800
@@ -66,6 +66,9 @@
     */
    @Override
    public boolean visitTree(VisitContext context, VisitCallback callback) {
+       if (isSkippingIteration(context)) {
+           return super.visitTree(context, callback);
+       }
        return Components.getClosestParent(this, Tree.class).visitTreeNode(context, callback);
    }

diff -r 0c0b57aa6780 src/org/omnifaces/component/tree/TreeNodeItem.java
--- a/src/org/omnifaces/component/tree/TreeNodeItem.java    Fri Nov 30 12:39:03 2012 -0400
+++ b/src/org/omnifaces/component/tree/TreeNodeItem.java    Mon Dec 03 09:33:00 2012 +0800
@@ -119,6 +119,10 @@
    @Override
    @SuppressWarnings({ "rawtypes", "unchecked" }) // For TreeModel. We don't care about its actual type anyway.
    public boolean visitTree(final VisitContext context, final VisitCallback callback) {
+       if (isSkippingIteration(context)) {
+           return super.visitTree(context, callback);
+       }
+       
        if (!isVisitable(context) || getChildCount() == 0) {
            return false;
        }
Yaocl
  • 194
  • 1
  • 12
  • The `VisitHint.SKIP_ITERATION` is JSF 2.1 specific. OmniFaces is aimed to be JSF 2.0 compatible. – BalusC Dec 02 '12 at 12:16
  • I can only make it have some compile time compatibility with JSF 2.0 – Yaocl Dec 03 '12 at 01:35
  • It's been added as per [issue 106](http://code.google.com/p/omnifaces/issues/detail?id=106). Thank you for your contribution. – BalusC Dec 03 '12 at 03:25