c:set and JSF
gjeudy Jun 20, 2008 8:58 PMHi,
I know this request might not be related as much to Seam but I noticed something strange with using c:set in a facelets page.
I am using JSTL with facelets to derive some labels based on backing bean states.
<c:choose> <c:when test="${editMode}"> <c:choose> <c:when test="${staticEntity.id != null}"> <c:set var="actionLabel" value="Edit #{type}" /> </c:when> <c:otherwise> <c:set var="actionLabel" value="Add #{type}" /> </c:otherwise> </c:choose> </c:when> <c:otherwise> <c:set var="actionLabel" value="Show #{type}" /> </c:otherwise> </c:choose> <h:outputText value="${actionLabel}" styleClass="label" />
When I add a new entity the h:outputText in the page will render 'Add Product' for example. When i save the product (JSF postback), the product gets persisted and now the h:outputText should show 'Edit Product' but it still shows 'Add Product'. If I leave the page and come back to it for the same product then the h:outputText correctly displays 'Edit Product'.
I read something, don't remember where, c:set should be avoided because it is a compile time tag as opposed to render time.
As I understand all JSF tags are render time. JSTL c:set happens to be compile time which means the value of c:set is only evaluated when a new JSF component tree is built.
Since this is view layer logic I would hate to have to set a label on my action bean just so my page can pick up the latest value.
I could use the primitive below approach but I figure there must be a more elegant way to solve this.
<h:outputText rendered="#{editMode and staticEntity.id == null}" value="Add #{type}" styleClass="label" /> <h:outputText rendered="#{editMode and staticEntity.id != null}" value="Edit #{type}" styleClass="label" /> <h:outputText rendered="#{!editMode}" value="Show #{type}" styleClass="label" />
Any ideas?