I'm familiar with RichFaces, but relatively new to Primefaces and trying to implement a simple h:graphicImage
inside a p:dataTable
(additionally inside a ui:repeat
). This is the subsequent question of p:ajax inside h:graphicImage.
I will split the following xhtml
-code to directly comment the behavior:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<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:ui="http://java.sun.com/jsf/facelets"
xmlns:p="http://primefaces.prime.com.tr/ui"
xml:lang="en" lang="en">
<h:head id="head">
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<title>Test</title>
</h:head>
<h:body id="body">
<f:view contentType="text/html">
Now the first h:form
follows which contains a h:outputText
and a h:graphicImage
. By clicking on the image the bean method is called and the counter is correctly updated.
<h:form id="f1">
<h:outputText id="counter" value="#{clientBean.counter}" />
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="counter" process="@this"
listener="#{clientBean.tag}"/>
</h:graphicImage>
</h:form><hr/>
In the second h:form
the button is inside a p:dataTable
. If I click on the image, the bean method is called the counter is updated. (Note At firt I've tried to update="counter"
without success)
<h:form id="f2">
<p:dataTable var="var" value="#{clientBean.vf}">
<p:column>
<f:facet name="header">Tag</f:facet>
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="f1:counter" process="@this"
listener="#{clientBean.tag}" />
</h:graphicImage>
</p:column>
</p:dataTable>
</h:form><hr/>
The image inside ui:repeated
updates the counter as expected:
<ui:repeat var="var1" value="#{clientBean.list}">
<h:form id="f3">
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="f1:counter" process="@this"
listener="#{clientBean.tag}" />
</h:graphicImage>
Now lets come to the p:dataTable
inside a ui:repeat
. With this piece of code the bean method is not called:
<p:dataTable var="var2" value="#{var1.list}">
<p:column>
<f:facet name="header">Tag</f:facet>
<h:graphicImage url="/images/circle-ok.png">
<p:ajax event="click" update="f1:counter" process="@this"
listener="#{clientBean.tag}" />
</h:graphicImage>
</p:column>
</p:dataTable>
</h:form>
</ui:repeat>
</f:view></h:body></html>
In this case I get the <partial-response><changes><update id="f1:counter">...
, but the bean method is not called (an inside it's tag()
method the counter not updated). This is tested with a debug.
I've read
unable to use <p:ajax> on my primeface's datatable
but I have the same behaivour with primefaces-3.0.M3.jar
and primefaces-2.2.1.jar
.
I used to have a similar issue. I might be paranoid but my impression is the iterative component
UIData
andUIRepeat
in JSF2 are bugged. In particular they won't handle component state properly when they are nested. I have patchedUIRepeat
myself and it works for me with any level of nesting. I know iterative component from tomahawk works correctly as well.In your particular case a reasonably simple workaround could help since you want the same behavior regardless of which image is clicked. Create a
h:commandLink
say in form f1 with proper ajax element inside and id like 'update-counter'. Hide it. Add onclick attribute to your graphicImage with valuejsf.ajax.request("f1:update-counter", event, {render: "f1:counter", execute="@this"})
. You may need to replace the first argument withdocument.getElementById("f1:update-counter")
, I'm not sure. This javascript api call should be equivalent to clicking the hidden commandLink. Alternatively you may try to skip the commandLink and pass graphicImage id/DOM node from f1 instead.I used to do this with
f:ajax
, but maybe will work forp:ajax
as well.