Updating Cells Inside A Table With Richfaces
Sometimes one wants to update some cells of a table using AJAX. Re-render the whole table is mostly not an option ,especially if the table(s) are very large. Using the Richfaces framework it’s quite simply.
This may be the JSF code:
...
<rich:subTable value="#{myBackingBean.descriptions}" var="oneTableRow" border="0" id="monatsberichtValuesSubTable"
ajaxKeys="#{myBackingBean.rowsToUpdate}" rowKeyVar="rowCounter">
<rich:column styleClass="#{oneTableRow.styleClass}">
<h:outputLink value="#{oneTableRow.linkTarget}">
<h:outputText value="#{oneTableRow.linkName}"/>
</h:outputLink>
</rich:column>
<rich:column styleClass="#{oneTableRow.styleClass}">
<h:outputText value="#{oneTableRow.description}"/>
</rich:column>
<rich:columns value="#{myBackingBean.getArrayWithFieldValues(oneTableRow.mappedToValuesRowId)}" var="field"
border="0" index ="ind3" styleClass="#{field.getStyleClass()}" colspan="#{field.getColspan()}">
<h:inputText value="#{field.fieldIntegerValue}" ondblclick="setErgebnisCalculator(this)"
rendered="#{field.showField and (!myBackingBean.reportClosed) and (myBackingBean.writePermission) and (field.editable)}">
<a4j:support event="onchange" ajaxSingle="true" reRender="id_0,id_1,id_2,id_3,id_4,id_5,id_6"
action="#{myBackingBean.calculateSums(0, oneTableRow.mappedToValuesRowId, ind3)}"/>
</h:inputText>
<h:outputText value="#{field.fieldIntegerValue}" id="#{field.identifier}"
rendered="#{field.showField and (!field.editable or myBackingBean.reportClosed or !myBackingBean.writePermission )}"/>
</rich:columns>
</rich:subTable>
...
The subTable uses the ajaxKeys attribute and the tag uses the reRender attribute. Used together they act like coordinates for the X-axis and Y-axis inside the table.
The backing - or more specific the method called by the AJAX request - looks like that:
...
private Set<Integer> rowsToUpdate = new HashSet<Integer>();
...
public String calculateSums(int tableNumber, int rowNumber, int columnNumber) throws BusinessException{
log.debug("calculateSums() called for table number: " + tableNumber + " and row numer " +
rowNumber + " and column number " + columnNumber + "...");
/* Just call the internal calculation method */
calculateInternal(...);
/* Add the last row (holding the sums) to the set of rows which should be updated */
rowsToUpdate.add(reportTables[0].getDescriptions().length-1);
rowsToUpdate.add(rowNumber);
return "";
}
...
public Set<Integer> getRowsToUpdate() {
return rowsToUpdate;
}