[jsr-314-open] Mixing an ajax tag with a rendered attribute
Jim Driscoll
Jim.Driscoll at SUN.COM
Thu May 28 18:40:34 EDT 2009
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.
An obvious solution would just be to emit insert and deletes as
appropriate when the rendered value changes. Of course. But that
requires access to the previous state of the component, so you know when
the rendered value has changed.
The problem, as I understand it, is that the previous state of the
component may not be readily available - and you'd need to know that
previous state to know whether to change state in the page with an
insert or delete, instead of an update. This is especially true with
client side state. Also, this isn't just limited to the ajax tag, since
you can run into this with the jsf.ajax calls as well, though being
closer to the metal, you'd presumably be less likely to get stumped on
what's happening.
Workarounds are easy enough - have the ajax tag target render to an
element that wraps the component, but that's going to be awkward to
explain - primarily because the whole point of JSF is to abstract away
stuff like that. You could also use javascript to toggle a style of
display=none, but that requires JS programming, something we haven't
really been requiring in the past (though many common things, like
setting focus, do require such small JS efforts, we've never required it
to work around a spec deficiency like this).
So, I'd like to ask the EG for thoughts on how to handle this.
It's always possible we'll come up with something on the impl side, we
haven't studied it seriously yet - I'd have waited to send this out, but
we're all mostly going to JavaOne in few days, and wanted to throw this
out there before we did.
Any ideas? Other than saying it's not a supported function? (Barring
an impl solution, which may not be easily achievable.)
Jim
More information about the jsr-314-open-mirror
mailing list