in tobago-core/src/main/java/org/apache/myfaces/tobago/internal/renderkit/renderer/SheetRenderer.java [438:691]
private void encodeTableBody(
final FacesContext facesContext, final AbstractUISheet sheet,
final TobagoResponseWriter writer, final String sheetId, final Selectable selectable,
final List<Integer> columnWidths, final List<Integer> selectedRows, final List<AbstractUIColumnBase> columns,
final boolean autoLayout, final List<Integer> expandedValue) throws IOException {
final boolean showHeader = sheet.isShowHeader();
final Markup sheetMarkup = sheet.getMarkup() != null ? sheet.getMarkup() : Markup.NULL;
boolean nonLazyUpdate = !sheet.isLazyUpdate(facesContext);
if (nonLazyUpdate) {
final UIComponent before = sheet.getFacet(Facets.BEFORE);
if (before != null) {
before.encodeAll(facesContext);
}
if (showHeader && !autoLayout) {
// if no autoLayout, we render the header in a separate table.
writer.startElement(HtmlElements.HEADER);
writer.startElement(HtmlElements.TABLE);
writer.writeAttribute(HtmlAttributes.CELLSPACING, "0", false);
writer.writeAttribute(HtmlAttributes.CELLPADDING, "0", false);
writer.writeAttribute(HtmlAttributes.SUMMARY, "", false);
writer.writeClassAttribute(
BootstrapClass.TABLE,
sheetMarkup.contains(Markup.DARK) ? BootstrapClass.TABLE_DARK : null,
sheetMarkup.contains(Markup.BORDERED) ? BootstrapClass.TABLE_BORDERED : null,
sheetMarkup.contains(Markup.SMALL) ? BootstrapClass.TABLE_SM : null,
TobagoClass.TABLE_LAYOUT__FIXED);
writeColgroup(facesContext, sheet, writer, columnWidths, columns, true);
writer.startElement(HtmlElements.THEAD);
encodeHeaderRows(facesContext, sheet, writer, columns);
writer.endElement(HtmlElements.THEAD);
writer.endElement(HtmlElements.TABLE);
writer.startElement(HtmlElements.DIV);
writer.writeClassAttribute(TobagoClass.SCROLLBAR__FILLER,
BootstrapClass.TABLE,
sheetMarkup.contains(Markup.DARK) ? BootstrapClass.TABLE_DARK : null,
sheetMarkup.contains(Markup.BORDERED) ? BootstrapClass.TABLE_BORDERED : null);
writer.endElement(HtmlElements.DIV);
writer.endElement(HtmlElements.HEADER);
}
}
writer.startElement(HtmlElements.DIV);
writer.writeClassAttribute(TobagoClass.BODY);
writer.startElement(HtmlElements.TABLE);
writer.writeAttribute(HtmlAttributes.CELLSPACING, "0", false);
writer.writeAttribute(HtmlAttributes.CELLPADDING, "0", false);
writer.writeAttribute(HtmlAttributes.SUMMARY, "", false);
writer.writeClassAttribute(
BootstrapClass.TABLE,
sheetMarkup.contains(Markup.DARK) ? BootstrapClass.TABLE_DARK : null,
sheetMarkup.contains(Markup.STRIPED) ? BootstrapClass.TABLE_STRIPED : null,
sheetMarkup.contains(Markup.BORDERED) ? BootstrapClass.TABLE_BORDERED : null,
sheetMarkup.contains(Markup.HOVER) ? BootstrapClass.TABLE_HOVER : null,
sheetMarkup.contains(Markup.SMALL) ? BootstrapClass.TABLE_SM : null,
!autoLayout ? TobagoClass.TABLE_LAYOUT__FIXED : null);
if (nonLazyUpdate) {
if (showHeader && autoLayout) {
writer.startElement(HtmlElements.THEAD);
encodeHeaderRows(facesContext, sheet, writer, columns);
writer.endElement(HtmlElements.THEAD);
}
if (!autoLayout) {
writeColgroup(facesContext, sheet, writer, columnWidths, columns, false);
}
}
// Print the Content
if (LOG.isDebugEnabled()) {
LOG.debug("first = " + sheet.getFirst() + " rows = " + sheet.getRows());
}
writer.startElement(HtmlElements.TBODY);
final String var = sheet.getVar();
boolean emptySheet = true;
// rows = 0 means: show all
final int first = sheet.isLazy() ? sheet.getLazyFirstRow() : sheet.getFirst();
final int last = sheet.isLazy() ? sheet.getLazyFirstRow() + sheet.getLazyRows()
: sheet.isRowsUnlimited() ? Integer.MAX_VALUE : sheet.getFirst() + sheet.getRows();
AbstractUIRow row = null;
boolean[] columnRendered = new boolean[columns.size()];
for (int i = 0; i < columns.size(); i++) {
UIColumn column = columns.get(i);
if (column.isRendered()) {
columnRendered[i] = true;
if (column instanceof AbstractUIRow) {
row = (AbstractUIRow) column;
// todo: Markup.CLICKABLE ???
}
}
}
for (int rowIndex = first; rowIndex < last; rowIndex++) {
sheet.setRowIndex(rowIndex);
if (!sheet.isRowAvailable()) {
break;
}
final Object rowRendered = sheet.getAttributes().get("rowRendered");
if (rowRendered instanceof Boolean && !((Boolean) rowRendered)) {
continue;
}
emptySheet = false;
if (LOG.isDebugEnabled()) {
LOG.debug("var " + var);
LOG.debug("list " + sheet.getValue());
}
if (sheet.isTreeModel() && sheet.isFolder() && sheet.getExpandedState().isExpanded(sheet.getPath())) {
expandedValue.add(rowIndex);
}
writer.startElement(HtmlElements.TR);
writer.writeAttribute(CustomAttributes.ROW_INDEX, rowIndex);
final boolean selected = selectedRows.contains(rowIndex);
final String parentId = sheet.getRowParentClientId();
if (parentId != null) {
// TODO: replace with writer.writeIdAttribute(parentId + SUB_SEPARATOR + AbstractUITree.SUFFIX_PARENT);
// todo like in TreeListboxRenderer
writer.writeAttribute(DataAttributes.TREE_PARENT, parentId, false);
}
// the row client id depends on the existence of an UIRow component! TBD: is this good?
writer.writeIdAttribute(row != null ? row.getClientId(facesContext) : sheet.getRowClientId());
writer.writeClassAttribute(
selected ? TobagoClass.SELECTED : null,
selected ? BootstrapClass.TABLE_INFO : null,
row != null ? row.getCustomClass() : null,
sheet.isRowVisible() ? null : BootstrapClass.D_NONE);
int colSpan = 0;
AbstractUIColumnPanel panel = null;
for (int i = 0; i < columns.size(); i++) {
AbstractUIColumnBase column = columns.get(i);
if (columnRendered[i]) {
if (column instanceof AbstractUIColumn || column instanceof AbstractUIColumnSelector
|| column instanceof AbstractUIColumnNode) {
colSpan++;
writer.startElement(HtmlElements.TD);
Markup markup = column.getMarkup();
if (markup == null) {
markup = Markup.NULL;
}
writer.writeClassAttribute(
BootstrapClass.textAlign(
column instanceof AbstractUIColumn ? ((AbstractUIColumn) column).getAlign() : null),
BootstrapClass.verticalAlign(
column instanceof AbstractUIColumn ? ((AbstractUIColumn) column).getVerticalAlign() : null),
column.getCustomClass());
if (column instanceof AbstractUIColumnSelector selector) {
writer.startElement(HtmlElements.INPUT);
writer.writeNameAttribute(sheetId + "_data_row_selector_" + rowIndex);
Selectable currentSelectable = getSelectionMode(selectable, selector);
if (currentSelectable.isSingle()) {
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.RADIO);
} else {
writer.writeAttribute(HtmlAttributes.TYPE, HtmlInputTypes.CHECKBOX);
}
writer.writeAttribute(HtmlAttributes.TITLE,
ResourceUtils.getString(facesContext, "sheet.selectRow"), true);
writer.writeAttribute(Arias.LABEL,
ResourceUtils.getString(facesContext, "sheet.selectRow"), true);
writer.writeAttribute(HtmlAttributes.CHECKED, selected);
writer.writeAttribute(HtmlAttributes.DISABLED, selector.isDisabled());
writer.writeClassAttribute(
BootstrapClass.FORM_CHECK_INLINE,
TobagoClass.SELECTED);
writer.endElement(HtmlElements.INPUT);
} else if (column instanceof AbstractUIColumnNode) {
column.encodeAll(facesContext);
} else {
final int childCount = column.getChildCount();
if (childCount > 0) {
final List<UIComponent> children = column.getChildren();
for (int k = 0; k < childCount; k++) {
children.get(k).encodeAll(facesContext);
}
}
}
writer.endElement(HtmlElements.TD);
} else if (column instanceof AbstractUIColumnPanel) {
panel = (AbstractUIColumnPanel) column;
}
}
}
if (!autoLayout) {
writer.startElement(HtmlElements.TD);
writer.writeClassAttribute(TobagoClass.ROW__FILLER);
writer.endElement(HtmlElements.TD);
colSpan++;
}
writer.startElement(HtmlElements.TD);
writer.writeClassAttribute(TobagoClass.BEHAVIOR__CONTAINER);
encodeBehavior(writer, facesContext, row);
writer.endElement(HtmlElements.TD);
writer.endElement(HtmlElements.TR);
if (panel != null) {
writer.startElement(HtmlElements.TR);
writer.writeNameAttribute(String.valueOf(rowIndex));
writer.writeClassAttribute(TobagoClass.COLUMN__PANEL, panel.getCustomClass());
writer.startElement(HtmlElements.TD);
writer.writeAttribute(HtmlAttributes.COLSPAN, colSpan);
panel.encodeAll(facesContext);
writer.endElement(HtmlElements.TD);
writer.endElement(HtmlElements.TR);
}
}
sheet.setRowIndex(-1);
if (emptySheet && showHeader) {
writer.startElement(HtmlElements.TR);
int countColumns = 0;
for (final UIColumn column : columns) {
if (!(column instanceof AbstractUIRow)) {
countColumns++;
}
}
writer.startElement(HtmlElements.TD);
writer.writeAttribute(HtmlAttributes.COLSPAN, countColumns);
final UIComponent emptyFacet = ComponentUtils.getFacet(sheet, Facets.empty);
if (emptyFacet != null) {
emptyFacet.encodeAll(facesContext);
} else {
writer.startElement(HtmlElements.DIV);
writer.writeClassAttribute(BootstrapClass.TEXT_CENTER);
writer.writeText(ResourceUtils.getString(facesContext, "sheet.empty"));
writer.endElement(HtmlElements.DIV);
}
writer.endElement(HtmlElements.TD);
if (!autoLayout) {
writer.startElement(HtmlElements.TD);
writer.startElement(HtmlElements.DIV);
writer.endElement(HtmlElements.DIV);
writer.endElement(HtmlElements.TD);
}
writer.endElement(HtmlElements.TR);
}
writer.endElement(HtmlElements.TBODY);
writer.endElement(HtmlElements.TABLE);
writer.endElement(HtmlElements.DIV);
}