[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