* This method is separated from the encodeChildren so that it can be overridden by
* subclasses. One class that uses this functionality is autoUpdateDataTable.
*/
public void encodeInnerHtml(FacesContext facesContext, UIComponent component)throws IOException
{
UIData uiData = (UIData) component;
ResponseWriter writer = facesContext.getResponseWriter();
int rowCount = uiData.getRowCount();
int newspaperColumns = getNewspaperColumns(component);
if (rowCount == -1 && newspaperColumns == 1)
{
encodeInnerHtmlUnknownRowCount(facesContext, component);
return;
}
if (rowCount == 0)
{
//nothing to render, to get valid xhtml we render an empty dummy row
writer.startElement(HTML.TBODY_ELEM, uiData);
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element", null);
writer.startElement(HTML.TR_ELEM, uiData);
writer.startElement(HTML.TD_ELEM, uiData);
writer.endElement(HTML.TD_ELEM);
writer.endElement(HTML.TR_ELEM);
writer.endElement(HTML.TBODY_ELEM);
return;
}
// begin the table
// get the CSS styles
Styles styles = getStyles(uiData);
int first = uiData.getFirst();
int rows = uiData.getRows();
int last;
if (rows <= 0)
{
last = rowCount;
}
else
{
last = first + rows;
if (last > rowCount)
{
last = rowCount;
}
}
int newspaperRows;
if((last - first) % newspaperColumns == 0)
{
newspaperRows = (last - first) / newspaperColumns;
}
else
{
newspaperRows = ((last - first) / newspaperColumns) + 1;
}
boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(component);
// get the row indizes for which a new TBODY element should be created
Integer[] bodyrows = getBodyRows(facesContext, component);
int bodyrowsCount = 0;
// walk through the newspaper rows
for(int nr = 0; nr < newspaperRows; nr++)
{
boolean rowStartRendered = false;
// walk through the newspaper columns
for(int nc = 0; nc < newspaperColumns; nc++)
{
// the current row in the 'real' table
int currentRow;
if (newspaperHorizontalOrientation)
{
currentRow = nr * newspaperColumns + nc + first;
}
else
{
currentRow = nc * newspaperRows + nr + first;
}
// if this row is not to be rendered
if(currentRow >= last)
{
continue;
}
// bail if any row does not exist
uiData.setRowIndex(currentRow);
if(!uiData.isRowAvailable())
{
log.severe("Row is not available. Rowindex = " + currentRow);
break;
}
if (nc == 0)
{
// first column in table, start new row
beforeRow(facesContext, uiData);
// is the current row listed in the bodyrows attribute
if(ArrayUtils.contains(bodyrows, currentRow))
{
// close any preopened TBODY element first
if(bodyrowsCount != 0)
{
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.endElement(HTML.TBODY_ELEM);
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
writer.startElement(HTML.TBODY_ELEM, uiData);
// Do not attach bodyrowsCount to the first TBODY element, because of backward compatibility
writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element" +
(bodyrowsCount == 0 ? "" : bodyrowsCount), null);
bodyrowsCount++;
}
HtmlRendererUtils.writePrettyLineSeparator(facesContext);
renderRowStart(facesContext, writer, uiData, styles, nr);
rowStartRendered = true;
}
List children = null;
int columnStyleIndex = 0;
for (int j = 0, size = getChildCount(component); j < size; j++)
{
if (children == null)
{
children = getChildren(component);
}
UIComponent child = (UIComponent) children.get(j);
if (child.isRendered())
{
boolean columnRendering = child instanceof UIColumn;
if (columnRendering)
{
beforeColumn(facesContext, uiData, columnStyleIndex);
}
encodeColumnChild(facesContext, writer, uiData, child,
styles, nc * uiData.getChildCount() + columnStyleIndex);
if (columnRendering)
{
afterColumn(facesContext, uiData, columnStyleIndex);
}