Some time ago I published an article at jroller in order to show how the rich:calendar performance can be improved by using single component instance for all the date inputs on the form. Today I want to use the same workaround to solve another popular problem.
Looking through the community forum I see that many people are having issues related to extended/scrollable tables and embedded components with absolute positioning. These components can be cutoff by the tables borders. Unfortunately it's too late for markup redesign for tables components in 3.3.x because only stabilization works planned for the branch.
In this entry I want to highlight that for the rich:calendar component you can use the solution described in original article to make it work when embedded in tables. I'll also add small update for the article code sample in order to make it works with the latest RichFaces 3.3.3.
Lets check this simple table definition:
<rich:extendedDataTable value="#{dataBean.simpleList}" var="list" width="300px" height="400px" rowKeyVar="rowKey"> <rich:column> <f:facet name="header"> <h:outputText value="row number" /> </f:facet> <h:outputText value="#{rowKey}" /> </rich:column> <rich:column> <f:facet name="header"> <h:outputText value="calendar" /> </f:facet> <rich:calendar /> </rich:column> </rich:extendedDataTable>
It will produce the following problematic result:
Now lets move rich:calendar component outside the table and replace it in column with simple input and icon which activates it using api:
Calendar definition (outside the table)<a4j:loadScript src="/scripts/calendarUtils.js"></a4j:loadScript> <rich:calendar id="calendar" onchanged="#{rich:component('calendar')}.customInput.value=event.rich.component.getSelectedDateString();" zindex="1000"/> <script> #{rich:component('calendar')}.customExpand=customExpand; </script>definition of date columns
<rich:column> <f:facet name="header"> <h:outputText value="calendar" /> </f:facet> <h:inputText value="#{userBean.name}" id="input2" readonly="true" onclick="#{rich:component('calendar')}.customExpand(event, #{rich:element('input2')}, #{rich:element('button2')});" /> <h:graphicImage value="resource:///org.richfaces.renderkit.html.iconimages.CalendarIcon" onclick="#{rich:component('calendar')}.customExpand(event, #{rich:element('input2')}, #{rich:element('button2')});" id="button2" /> </rich:column>
This definitions and calendarUtils.js code is explained in detail in the jroller post. The only thing we need to correct is the script for our calendar initialization. The following lines should be added just after the customExpand function declaration in calendarUtils.js:
function customExpand(e,input,button) { if (!this.isRendered) { this.isRendered = true; this.render(); } ///the rest part fully the same as in original article
This change needed because lazy initialization implemented in calendar in 3.3.3 and without calling render method on the first time calendar call will produce empty calendar to be shown.
And here is expected result for extendedDataTable:
It should became the same used with scrollableDataTable.