On Thu, May 28, 2009 at 6:40 PM, Jim Driscoll
<Jim.Driscoll@sun.com> wrote:
This is one of those "we should have seen this coming" bugs (and for all I know, maybe others did - but I hadn't thought about it).
https://javaserverfaces.dev.java.net/issues/show_bug.cgi?id=1139
If you're doing this:
<h:panelGrid>
<h:outputText value="Shipping/Billing address is the same" />
<h:selectBooleanCheckbox value="true" >
<f:ajax listener="#{order.toggle}" render="shippingGroup"/>
</h:selectBooleanCheckbox>
</h:panelGrid>
<h:panelGroup id="shippingGroup" rendered="#{order.renderShipping}">
<fieldset>
<legend>Shipping Address</legend>
<comp:address id="shippingAddress"
city="#{addressBean.city}"
state="#{addressBean.state}"
zip="#{addressBean.zip}"
street="#{addressBean.street}" />
</fieldset>
</h:panelGroup>
where "toggle" changed the order.renderShipping property, then it's going to fail in both directions - both when you change from not rendered to rendered (because we're doing an update on something that doesn't exist) and when changing from rendered to not rendered (because we're doing an update that won't have any data).
The upshot - if you're using f:ajax to toggle the rendered attribute of something that you're rendering, it's not going to work.
This is a very familiar issue for developers that have used Ajax4jsf for any length of time. So common, in fact, that Ajax4jsf offers a component which renders a placeholder to make this very use case possible. Max Katz even dedicates a whole section of Practical RichFaces on the problem So I would be very interested to here what Mr. Smirmov has to say given that he has likely lost nights of sleep thinking about how to deal with it ;)
Of course, the simple solultion is to use a wrapper component (such as a panelGroup) which is rerendered and have the toggle inside of that wrapper.
-Dan