views:

67

answers:

2

I have a h:dataTable that displays ProfileNotification like below:

        <h:dataTable value="#{myBean.profileNotifications}" var="item"
                     rendered="#{myBean.renderProfileNotification}">
            <h:column>
                <h:form>                        
                    <h:outputText value="#{item.userName} "/>
                    <h:outputText value="commented on your profile. "/>
                    <!-- <h:outputText value="[#{item.createTime}]"/> -->
                </h:form>
            </h:column>                
        </h:dataTable>

when I dont have the item.createTime, if I click a commandLink to set renderProfileNotification=true, it print out 4 items. However, if i uncommented item.createTime, the it only print out 1 item, the first item.

EDIT: The problem is the [] inside value. Since BalusC suspect that this is an EL bug, I reproduce my bug in a small, readable and reproducible code. This code run on Glassfish v3.0.1 b22

index.xhtml

<html xmlns="http://www.w3.org/1999/xhtml"
  xmlns:f="http://java.sun.com/jsf/core"
  xmlns:h="http://java.sun.com/jsf/html"
  xmlns:p="http://primefaces.prime.com.tr/ui"&gt;
<h:head>
    <meta http-equiv="Content-Type" content="text/html; charset=UTF-8"/>
    <title>TODO supply a title</title>
</h:head>
<h:body>
    <h:form id="table">
        <h:dataTable   value="#{myBean.temp}" var="item" rendered="#{myBean.display}">
            <h:column>
                <h:outputText value="[#{item}]"/>
            </h:column>
        </h:dataTable>            
    </h:form>
    <h:form>
        <p:commandLink value="Display" actionListener="#{myBean.setDisplay}" update="table"/>
    </h:form>
</h:body>
</html>

myBean.java

@ManagedBean(name="myBean")
@SessionScoped
public class myBean {

List<String> temp = null;

public myBean() {
}

private boolean display = false;

@PostConstruct
public void init(){
    temp = new ArrayList<String>();
    temp.add(0, "Tom");
    temp.add(1, "Peter");
    temp.add(2, "Mike");
    temp.add(3, "Fox");
}

public List<String> getTemp() {
    return temp;
}

public void setTemp(List<String> temp) {
    this.temp = temp;
}

public boolean isDisplay() {
    return display;
}

public void setDisplay() {
    this.display = !this.display;
}
}
+1  A: 

I figure what is wrong. Apparent, putting [] inside value attribute is bad. What I have is this:

<h:outputText value="[#{item.createTime}]"/>

if I take out the [], to become

<h:outputText value="#{item.createTime}"/>

then everything work fine. Must be one of the special character thing.

Harry Pham
Interesting. Sounds like EL bug. Those `[]` have also a special meaning in EL, but usually only *inside* the expression `#{}`. What servletcontainer are you using? Or are you using a custom/special EL implementation which you have definied in `web.xml`? It would be great if you nail this down into a small reproducible code snippet with all stubs.
BalusC
No custom/special EL implementation. I am not sure what my servlet container is? I am using java-ee 6, is that my servlet container? I am trying to put this into small reproducible code as you request. Back in a few :D
Harry Pham
A servletcontainer is whatever you're using to run JSP/Servlet/EL API's (and indirectly also JSF, but that's not so relevant since that runs *on top* of JSP/Servlet/EL). E.g. Apache Tomcat, Oracle Glassfish, JBoss AS, etc. As per your question history I bet it's Glassfish v3. Which version exactly?
BalusC
Glassfish v3.0.1 b22
Harry Pham
I just updated my post. I successfully recreate the bug in a small reproducible version. I did use primefaces framework, btw. Not sure if this is primefaces bugs.
Harry Pham
+1  A: 

OK, it's the last ] which is causing problems. When using

<h:outputText value="[#{item}]"/>

the XML response of the ajax request is as follows:

<?xml version="1.0" encoding="UTF-8"?><partialResponse><components><component><id>table</id><output><![CDATA[
<form id="table" name="table" method="post" action="/playground/test.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="table" value="table" />
<table>
<tbody>
<tr>
<td>[Tom]]]><![CDATA[</td>
</tr>
<tr>
<td>[Peter]]]><![CDATA[</td>
</tr>
<tr>
<td>[Mike]]]><![CDATA[</td>
</tr>
<tr>
<td>[Fox]]]><![CDATA[</td>
</tr>
</tbody>
</table>
~com.sun.faces.saveStateFieldMarker~
</form>]]></output></component></components><state><![CDATA[<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="8834103461195979522:5904029216967015556" autocomplete="off" />]]></state><callbackParams><callbackParam>{"validationFailed":false}</callbackParam></callbackParams></partialResponse>

Note the unnecessary CDATA blocks.

And when using

<h:outputText value="[#{item})"/>

the XML response of the ajax request is as follows:

<?xml version="1.0" encoding="UTF-8"?><partialResponse><components><component><id>table</id><output><![CDATA[
<form id="table" name="table" method="post" action="/playground/test.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="table" value="table" />
<table>
<tbody>
<tr>
<td>[Tom)</td>
</tr>
<tr>
<td>[Peter)</td>
</tr>
<tr>
<td>[Mike)</td>
</tr>
<tr>
<td>[Fox)</td>
</tr>
</tbody>
</table>
~com.sun.faces.saveStateFieldMarker~
</form>]]></output></component></components><state><![CDATA[<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="502405171373727621:5591448575905434431" autocomplete="off" />]]></state><callbackParams><callbackParam>{"validationFailed":false}</callbackParam></callbackParams></partialResponse>

This boils down to the following problem cause: the ajax response handler is unnecessary closing and starting a CDATA block for a ] in partial response and the JS XML response parser only picks the first one for display. An easy workaround was to place the ] outside the value expression:

<h:outputText value="[#{item}"/>]

which results in the following XML response:

<?xml version="1.0" encoding="UTF-8"?><partialResponse><components><component><id>table</id><output><![CDATA[
<form id="table" name="table" method="post" action="/playground/test.jsf" enctype="application/x-www-form-urlencoded">
<input type="hidden" name="table" value="table" />
<table>
<tbody>
<tr>
<td>[Tom]
            </td>
</tr>
<tr>
<td>[Peter]
            </td>
</tr>
<tr>
<td>[Mike]
            </td>
</tr>
<tr>
<td>[Fox]
            </td>
</tr>
</tbody>
</table>
~com.sun.faces.saveStateFieldMarker~
</form>]]></output></component></components><state><![CDATA[<input type="hidden" name="javax.faces.ViewState" id="javax.faces.ViewState" value="-1679996061683473780:1967669133311943592" autocomplete="off" />]]></state><callbackParams><callbackParam>{"validationFailed":false}</callbackParam></callbackParams></partialResponse>

I am not sure yet where the problem is rooted, in the ajax response handler or in the JS XML response parser, but now we at least know the cause. I will report an issue to the Mojarra guys sooner or later once nailed down.


Update: OK, I nailed it further down: it's the PrimeFaces' ajax response handler and JS XML parser which doing this incorrectly. When using a Mojarra's h:commandLink instead of p:commandLink it works fine.

<h:commandLink value="Display" actionListener="#{myBean.setDisplay}">
    <f:ajax render=":table" />
</h:commandLink>

Mojarra's ajax response handler doesn't print unnecessary CDATA blocks after each ]. That might be the root cause in PrimeFaces.


Update: issue reported to PF guys: http://code.google.com/p/primefaces/issues/detail?id=1282

BalusC
you are the super man, BalusC !!!
Harry Pham
You're welcome.
BalusC