@DataTable, datatable and outputText rendered behavior
marius.oancea Nov 16, 2005 11:55 AMI have the following piece of code:
<h:dataTable value="#{itemsList}" var="tocEntry" rendered="#{not empty itemsList}"> <h:column> <h:outputText value="#{courseTracker.currentItem == tocEntry}" /> <h:commandLink action="#{courseTracker.selectTocEntry}" >#{tocEntry.learnItem.title}#{tocEntry.quiz.title} </h:commandLink> </h:column> </h:dataTable>
the code display correctly :
falseGetting familiar with your JSP server falseYour first JSP trueOpening the editor falseStart coding falseAdding dynamic content via expressions falseScriptlets falseScriplets test falseJSP Professional
The condition courseTracker.currentItem == tocEntry is telling me if the currently rendered component is the one marked as selected in the backing bean (itemsList - a List annotated with @DataTable).
If I select a new entry (e.g. Start coding) the boolean value before the enty is changed and the selected entry in backing bean is also changed. (All perfect until now).
I wanted to only render the outputText if the enty is selected. So i changed the obove code to :
<h:dataTable value="#{itemsList}" var="tocEntry" rendered="#{not empty itemsList}"> <h:column> <h:outputText value="SOMETHING " rendered="#{courseTracker.currentItem == tocEntry}" /> <h:commandLink action="#{courseTracker.selectTocEntry}" >#{tocEntry.learnItem.title} </h:commandLink> </h:column> </h:dataTable>
Once i did that, any link i press (to make another selection) the same think is submitted (row 0 is submitted as selected).
If i put styleClass instead of renderer and i do the right css all is working again. Why "outputText rendered" can disturb the selection?
I think there is something with the time when the condition is evaluated and with the time when "column" is rendered ... Phases listeteners or so ....
I'm not expert in JSF but what is so special with "rendered" attribute? I think this attribute is somehow special being rendered before rendering. How to avoid this problem?
------
I did some more research and seems that if i put the expression into another place than in "rendered" attribute, the expresion is evaluated during uitext.encodeBegin called by renderChild included into the flow of table.renderColumnBody. See stack below:
UIText.encodeBegin(FacesContext) line: 49 RendererUtils.renderChild(FacesContext, UIComponent) line: 441 RendererUtils.renderChildren(FacesContext, UIComponent) line: 427 RendererUtils.renderChild(FacesContext, UIComponent) line: 448 HtmlTableRenderer(HtmlTableRendererBase).renderColumnBody(FacesContext, ResponseWriter, UIData, UIComponent, Iterator) line: 195 HtmlTableRenderer(HtmlTableRendererBase).encodeColumnChild(FacesContext, ResponseWriter, UIData, UIComponent, Iterator) line: 168 HtmlTableRenderer(HtmlTableRendererBase).encodeInnerHtml(FacesContext, UIComponent) line: 154 HtmlTableRenderer(HtmlTableRendererBase).encodeChildren(FacesContext, UIComponent) line: 94 HtmlDataTable(UIComponentBase).encodeChildren(FacesContext) line: 319 FaceletViewHandler.encodeRecursive(FacesContext, UIComponent) line: 513 FaceletViewHandler.encodeRecursive(FacesContext, UIComponent) line: 518 FaceletViewHandler.renderView(FacesContext, UIViewRoot) line: 447 LifecycleImpl.render(FacesContext) line: 300
If i do the same but putting the el into the rendered attribute, the el gets called at a diferent moment (see the stack below):
HtmlOutputText(UIComponentBase).isRendered() line: 822 HtmlOutputText(UIComponentBase).processDecodes(FacesContext) line: 393 HtmlDataTable(UIData).process(FacesContext, UIComponent, int) line: 511 HtmlDataTable(UIData).processColumnChildren(FacesContext, int) line: 498 HtmlDataTable(UIData).processDecodes(FacesContext) line: 381 UIViewRoot(UIComponentBase).processDecodes(FacesContext) line: 397 UIViewRoot.processDecodes(FacesContext) line: 131 LifecycleImpl.applyRequestValues(FacesContext) line: 177 LifecycleImpl.execute(FacesContext) line: 71
What am I missing ?