/* * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * "The contents of this file are subject to the Mozilla Public License * Version 1.1 (the "License"); you may not use this file except in * compliance with the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See the * License for the specific language governing rights and limitations under * the License. * * The Original Code is ICEfaces 1.5 open source software code, released * November 5, 2006. The Initial Developer of the Original Code is ICEsoft * Technologies Canada, Corp. Portions created by ICEsoft are Copyright (C) * 2004-2006 ICEsoft Technologies Canada, Corp. All Rights Reserved. * * Contributor(s): _____________________. * * Alternatively, the contents of this file may be used under the terms of * the GNU Lesser General Public License Version 2.1 or later (the "LGPL" * License), in which case the provisions of the LGPL License are * applicable instead of those above. If you wish to allow use of your * version of this file only under the terms of the LGPL License and not to * allow others to use your version of this file under the MPL, indicate * your decision by deleting the provisions above and replace them with * the notice and other provisions required by the LGPL License. If you do * not delete the provisions above, a recipient may use your version of * this file under either the MPL or the LGPL License." * */ package com.icesoft.faces.component.ext.renderkit; import com.icesoft.faces.component.CSS_DEFAULT; import com.icesoft.faces.component.PORTLET_CSS_DEFAULT; import com.icesoft.faces.component.commandsortheader.CommandSortHeader; import com.icesoft.faces.component.ext.HeaderRow; import com.icesoft.faces.component.ext.ColumnGroup; import com.icesoft.faces.component.ext.HtmlDataTable; import com.icesoft.faces.component.ext.RowSelector; import com.icesoft.faces.component.ext.UIColumns; import com.icesoft.faces.component.ext.taglib.Util; import com.icesoft.faces.context.DOMContext; import com.icesoft.faces.renderkit.dom_html_basic.HTML; import com.icesoft.faces.renderkit.dom_html_basic.DomBasicRenderer; import com.icesoft.faces.util.CoreUtils; import org.w3c.dom.Element; import org.w3c.dom.Node; import javax.faces.component.UIColumn; import javax.faces.component.UIComponent; import javax.faces.context.FacesContext; import java.io.IOException; import java.util.*; import com.icesoft.util.pooling.ClientIdPool; import com.icesoft.util.pooling.CSSNamePool; public class TableRenderer extends com.icesoft.faces.renderkit.dom_html_basic.TableRenderer { private static final String SELECTED_ROWS = "sel_rows"; public String getComponentStyleClass(UIComponent uiComponent) { return (String) uiComponent.getAttributes().get("styleClass"); } public String getHeaderClass(UIComponent component) { return (String) component.getAttributes().get("headerClass"); } public String getFooterClass(UIComponent component) { return (String) component.getAttributes().get("footerClass"); } // row styles are returned by reference public String[] getRowStyles(UIComponent uiComponent) { if (((String[]) getRowStyleClasses(uiComponent)).length <= 0) { String[] rowStyles = new String[2]; rowStyles[0] = Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_ROW_CLASS1); rowStyles[1] =Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_ROW_CLASS2); return rowStyles; } else { return getRowStyleClasses(uiComponent); } } public String[] getHeaderStyles(UIComponent uiComponent) { String headerClass = getHeaderClass(uiComponent). replaceAll(CSS_DEFAULT.TABLE_STYLE_CLASS + CSS_DEFAULT.TABLE_HEADER_CLASS, ""); if (((String[]) getHeaderStyleClasses(uiComponent)).length <= 0) { String[] headerStyles = new String[2]; headerStyles[0] = CSSNamePool.get(Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS1) + ((headerClass.length() > 0) ? headerClass : "")); headerStyles[1] = CSSNamePool.get(Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS2)+ ((headerClass.length() > 0) ? headerClass : "")); return headerStyles; } else { return getHeaderStyleClasses(uiComponent); } } public void writeColStyles(String[] columnStyles, int columnStylesMaxIndex, int columnStyleIndex, Element td, int colNumber, UIComponent uiComponent ) { if (columnStyles.length > 0) { if (columnStylesMaxIndex >= 0) { td.setAttribute("class", columnStyles[columnStyleIndex]); } } } protected void renderFacet(FacesContext facesContext, UIComponent uiComponent, DOMContext domContext, boolean header) throws IOException { String facet, tag, element, facetClass; if (header) { facet = "header"; tag = HTML.THEAD_ELEM; element = HTML.TH_ELEM; facetClass = getHeaderClass(uiComponent); } else { facet = "footer"; tag = HTML.TFOOT_ELEM; element = HTML.TD_ELEM; facetClass = getFooterClass(uiComponent); } HtmlDataTable uiData = (HtmlDataTable) uiComponent; uiData.setRowIndex(-1); Element root = (Element) domContext.getRootNode(); if (isScrollable(uiComponent)) { if (header) { // First table in first div path : table/tr/td/div/div0/table root = getScrollableHeaderTableElement(root); ((Element)root.getParentNode()).setAttribute(HTML.CLASS_ATTR, Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_SCRL_SPR)); } else { // First table in second div path table/tr/td/div/div2/table if (uiData.isScrollFooter()) { root = getScrollableBodyTableElement(root); } else { root = getScrollableFooterTableElement(root); ((Element)root.getParentNode()).setAttribute(HTML.CLASS_ATTR, Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_SCRL_SPR+CSS_DEFAULT.TABLE_FOOTER_CLASS)); } } } UIComponent headerFacet = getFacetByName(uiData, facet); boolean childHeaderFacetExists = childColumnHasFacetWithName(uiData, facet); Element thead = null; if (headerFacet != null || childHeaderFacetExists) { thead = domContext.createElement(tag); root.appendChild(thead); if (header) { if(CoreUtils.getPortletStyleClass(PORTLET_CSS_DEFAULT .PORTLET_SECTION_HEADER).length() > 1) { thead.setAttribute(HTML.CLASS_ATTR, PORTLET_CSS_DEFAULT .PORTLET_SECTION_HEADER); } renderTableHeader(facesContext, uiComponent, headerFacet, thead, facetClass, element); renderColumnGroup(facesContext, uiComponent, headerFacet, thead, facetClass, element); if (childHeaderFacetExists) { renderColumnHeader(facesContext, uiComponent, thead, facet, element, header); if (!uiData.isClientOnly()) { Element clientOnly = domContext.createElement(HTML.INPUT_ELEM); clientOnly.setAttribute(HTML.TYPE_ATTR, "hidden"); clientOnly.setAttribute(HTML.ID_ATTR, uiData.getClientId(facesContext) + "clientOnly"); clientOnly.setAttribute(HTML.NAME_ATTR, uiData.getClientId(facesContext) + "clientOnly"); root.appendChild(clientOnly); uiData.resetResizableTblColumnsWidthIndex(); } } } else { if(CoreUtils.getPortletStyleClass(PORTLET_CSS_DEFAULT .PORTLET_SECTION_FOOTER).length() > 1) { thead.setAttribute(HTML.CLASS_ATTR, PORTLET_CSS_DEFAULT .PORTLET_SECTION_FOOTER); } if (childHeaderFacetExists) { renderColumnHeader(facesContext, uiComponent, thead, facet, element, header); } renderColumnGroup(facesContext, uiComponent, headerFacet, thead, facetClass, element); renderTableHeader(facesContext, uiComponent, headerFacet, thead, facetClass, element); } domContext.setCursorParent(root); } } private void renderColumnHeader(FacesContext facesContext, UIComponent uiComponent, Element thead, String facet, String element, boolean header) throws IOException { StringTokenizer columnWitdths = getColumnWidths(uiComponent); DOMContext domContext = DOMContext.getDOMContext(facesContext, uiComponent); Element tr = domContext.createElement("tr"); thead.appendChild(tr); List childList = uiComponent.getChildren(); Iterator childColumns = childList.iterator(); String width = null; int columnIndex = 1; int headerStyleLength = getHeaderStyles(uiComponent).length; int styleIndex = 0; while (childColumns.hasNext()) { UIComponent nextColumn = (UIComponent) childColumns.next(); if (columnWitdths != null && columnWitdths.hasMoreTokens()) { width = columnWitdths.nextToken(); } else { if (isScrollable(uiComponent)) { width = "100%"; } else { width = null; } } if (!nextColumn.isRendered()) continue; if (nextColumn instanceof UIColumn) { processUIColumnHeader(facesContext, uiComponent, (UIColumn) nextColumn, tr, domContext, facet, element, width, columnIndex, styleIndex, !childColumns.hasNext()); columnIndex++; } else if (nextColumn instanceof UIColumns) { columnIndex = processUIColumnsHeader(facesContext, uiComponent, (UIColumns) nextColumn, tr, domContext, facet, element, width, columnIndex, styleIndex, headerStyleLength); } if (styleIndex++ == (headerStyleLength-1)) { styleIndex = 0; } } if (header && isScrollable(uiComponent)) { tr.appendChild(scrollBarSpacer(domContext, facesContext)); //being compatible with the XHTML DTD /* commented out for ICE-2974 Element tbody = (Element) domContext.createElement(HTML.TBODY_ELEM); tbody.setAttribute(HTML.STYLE_ATTR, "display:none"); thead.getParentNode().appendChild(tbody); Element tbodyTr = (Element) domContext.createElement(HTML.TR_ELEM); tbody.appendChild(tbodyTr); tbodyTr.appendChild(domContext.createElement(HTML.TD_ELEM)); */ } } private void renderColumnGroup(FacesContext facesContext, UIComponent uiComponent, UIComponent headerFacet, Element thead, String facetClass, String element ) throws IOException{ DOMContext domContext = DOMContext.getDOMContext(facesContext, uiComponent); if (headerFacet== null || !(headerFacet instanceof ColumnGroup)) return; if (!headerFacet.isRendered()) return; String sourceClass = CSS_DEFAULT.TABLE_HEADER_CLASS; if (!"th".equals(element)) { sourceClass = CSS_DEFAULT.TABLE_FOOTER_CLASS; } String baseClass= Util.getQualifiedStyleClass(uiComponent, "ColGrp"+sourceClass); HtmlDataTable htmlDataTable = (HtmlDataTable)uiComponent; Iterator children = headerFacet.getChildren().iterator(); while (children.hasNext()) { UIComponent child = (UIComponent) children.next(); if (child instanceof HeaderRow) { if(!child.isRendered()) continue; Element tr = domContext.createElement("tr"); String rowStyleClass = ((HeaderRow)child).getStyleClass(); if (rowStyleClass == null) { rowStyleClass = baseClass.replaceAll(sourceClass, sourceClass+"Row"); } else { rowStyleClass = baseClass.replaceAll(sourceClass, sourceClass+"Row ") + rowStyleClass; } tr.setAttribute(HTML.CLASS_ATTR, CSSNamePool.get(rowStyleClass)); String rowStyle = ((HeaderRow)child).getStyle(); if (rowStyle != null) { tr.setAttribute(HTML.STYLE_ATTR, rowStyle); } thead.appendChild(tr); Iterator columns = child.getChildren().iterator(); while (columns.hasNext()) { UIComponent column = (UIComponent) columns.next(); if (!(column instanceof UIColumn) || !column.isRendered()) { continue; } Element th = domContext.createElement(element); tr.appendChild(th); String styleClass = ((com.icesoft.faces.component.ext.UIColumn) column).getStyleClass(); if(styleClass == null) { styleClass = baseClass.replaceAll(sourceClass, sourceClass+"Col"); } else { styleClass = baseClass.replaceAll(sourceClass, sourceClass+"Col ")+ styleClass; } String sortColumn = htmlDataTable.getSortColumn(); if (sortColumn != null) { Iterator it = column.getChildren().iterator(); while (it.hasNext()) { UIComponent columnChild = (UIComponent) it.next(); if (columnChild instanceof CommandSortHeader) { String columnName = ((CommandSortHeader) columnChild).getColumnName(); if (sortColumn.equals(columnName)) { styleClass += CSS_DEFAULT.TABLE_ACTIVE_SORT_COLUMN ; } break; } } } th.setAttribute(HTML.CLASS_ATTR, CSSNamePool.get(styleClass)); Integer colspan = null; try { colspan = Integer.valueOf(((com.icesoft.faces.component.ext.UIColumn) column).getColspan()); } catch (Exception e) {} if (htmlDataTable.isResizable()) { if (colspan != null) { colspan = new Integer(colspan.intValue()+ colspan.intValue()); } else { colspan = new Integer(2); } } if (colspan != null) { th.setAttribute(HTML.COLSPAN_ATTR, colspan.toString()); } String rowspan = ((com.icesoft.faces.component.ext.UIColumn) column).getRowspan(); if (rowspan != null) { th.setAttribute(HTML.ROWSPAN_ATTR, rowspan); } String style = ((com.icesoft.faces.component.ext.UIColumn)column) .getStyle(); if (style != null) { th.setAttribute(HTML.STYLE_ATTR, style); } domContext.setCursorParent(th); encodeParentAndChildren(facesContext, column); } if (isScrollable(uiComponent)) { tr.appendChild(scrollBarSpacer(domContext, facesContext)); } } } } private void renderTableHeader(FacesContext facesContext, UIComponent uiComponent, UIComponent headerFacet, Element thead, String facetClass, String element ) throws IOException{ DOMContext domContext = DOMContext.getDOMContext(facesContext, uiComponent); if (headerFacet != null && headerFacet.isRendered()) { if (headerFacet instanceof ColumnGroup)return; resetFacetChildId(headerFacet); Element tr = domContext.createElement("tr"); thead.appendChild(tr); Element th = domContext.createElement(element); tr.appendChild(th); if (facetClass != null) { th.setAttribute("class", facetClass); } th.setAttribute("colspan", String.valueOf(getNumberOfChildColumns(uiComponent))); th.setAttribute("scope", "colgroup"); domContext.setCursorParent(th); encodeParentAndChildren(facesContext, headerFacet); if (isScrollable(uiComponent)) { tr.appendChild(scrollBarSpacer(domContext, facesContext)); } } } private void processUIColumnHeader(FacesContext facesContext, UIComponent uiComponent, UIColumn nextColumn, Element tr, DOMContext domContext, String facet, String element, String width, int columnIndex, int styleIndex, boolean lastChild) throws IOException { HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent; Element th = domContext.createElement(element); tr.appendChild(th); Element cursorParent = th; if (htmlDataTable.isResizable()) { if (!lastChild) { Element handlerTd = domContext.createElement(element); handlerTd.setAttribute("valign", "top"); handlerTd.setAttribute(HTML.CLASS_ATTR, "iceDatTblResBor"); handlerTd.setAttribute(HTML.ONMOUSEOVER_ATTR, "ResizableUtil.adjustHeight(this)"); Element resizeHandler = domContext.createElement(HTML.DIV_ELEM); resizeHandler.setAttribute(HTML.STYLE_ATTR, "cursor: e-resize; display:block; height:100%;"); resizeHandler.setAttribute(HTML.ONMOUSEDOWN_ATTR, "new Ice.ResizableGrid(event);"); resizeHandler.setAttribute(HTML.CLASS_ATTR, "iceDatTblResHdlr"); resizeHandler.appendChild(domContext.createTextNode(" ")); handlerTd.appendChild(resizeHandler); tr.appendChild(handlerTd); } Element columnHeaderDiv = domContext.createElement(HTML.DIV_ELEM); columnHeaderDiv.setAttribute(HTML.ID_ATTR, "hdrDv"+ columnIndex); th.appendChild(columnHeaderDiv); if (htmlDataTable.isResizable()) { String nextWidth = htmlDataTable.getNextResizableTblColumnWidth(); if (nextWidth != null) { columnHeaderDiv.setAttribute(HTML.STYLE_ATTR, "width:"+ nextWidth +";"); } } cursorParent = columnHeaderDiv; } if ("header".equalsIgnoreCase(facet) ){ String styles = this.getHeaderStyles(uiComponent)[styleIndex]; String sortColumn = htmlDataTable.getSortColumn(); UIComponent headerFacet = nextColumn.getFacet("header"); if (sortColumn != null && (headerFacet instanceof CommandSortHeader)) { String columnName = ((CommandSortHeader) headerFacet).getColumnName(); if (sortColumn.equals(columnName)) { styles += CSS_DEFAULT.TABLE_ACTIVE_SORT_COLUMN; } } th.setAttribute("class", styles); } else { th.setAttribute("class",getFooterClass(htmlDataTable)); } if (width != null) { th.setAttribute("style", "width:" + width + ";overflow:hidden;"); } //th.setAttribute("colgroup", "col"); UIComponent nextFacet = getFacetByName(nextColumn, facet); if (nextFacet != null) { resetFacetChildId(nextFacet); domContext.setCursorParent(cursorParent); encodeParentAndChildren(facesContext, nextFacet); } } private int processUIColumnsHeader(FacesContext facesContext, UIComponent uiComponent, UIColumns nextColumn, Element tr, DOMContext domContext, String facet, String element, String width, int columnIndex, int styleIndex, int headerStyleLength) throws IOException { HtmlDataTable htmlDataTable = (HtmlDataTable) uiComponent; int rowIndex = nextColumn.getFirst(); //syleIndex should be increment here nextColumn.encodeBegin(facesContext); nextColumn.setRowIndex(rowIndex); String sortColumn = htmlDataTable.getSortColumn(); while (nextColumn.isRowAvailable()) { UIComponent headerFacet = getFacetByName(nextColumn, facet); if (headerFacet != null) { Node oldParent = domContext.getCursorParent(); Element th = domContext.createElement(element); tr.appendChild(th); String styleClass = getHeaderStyles(uiComponent)[styleIndex]; if (headerFacet instanceof CommandSortHeader) { String columnName = ((CommandSortHeader) headerFacet).getColumnName(); if (sortColumn.equals(columnName)) { styleClass += CSS_DEFAULT.TABLE_ACTIVE_SORT_COLUMN ; } } th.setAttribute("class",styleClass); if (width != null) { th.setAttribute("style", "width:" + width + ";"); } //th.setAttribute("colgroup", "col"); domContext.setCursorParent(th); encodeParentAndChildren(facesContext, headerFacet); domContext.setCursorParent(oldParent); } if (styleIndex++ == (headerStyleLength-1)) { styleIndex = 0; } rowIndex++; columnIndex++; nextColumn.setRowIndex(rowIndex); } nextColumn.setRowIndex(-1); return columnIndex; } public void encodeChildren(FacesContext facesContext, UIComponent uiComponent) throws IOException { validateParameters(facesContext, uiComponent, null); DOMContext domContext = DOMContext.getDOMContext(facesContext, uiComponent); Element root = (Element) domContext.getRootNode(); Element originalRoot = root; boolean scrollable = isScrollable(uiComponent); if (scrollable) { Element hdrTbl = this.getScrollableHeaderTableElement(root); hdrTbl.setAttribute(HTML.CLASS_ATTR, Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_SCRL_HDR_TBL)); root = getScrollableBodyTableElement(root); root.setAttribute(HTML.CLASS_ATTR, Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_SCRL_BDY_TBL)); } DOMContext.removeChildrenByTagName(root, HTML.TBODY_ELEM); Element tBody = (Element) domContext.createElement(HTML.TBODY_ELEM); /* if (CoreUtils.getPortletStyleClass(PORTLET_CSS_DEFAULT. PORTLET_SECTION_BODY).length() > 1) { tBody.setAttribute(HTML.CLASS_ATTR, PORTLET_CSS_DEFAULT.PORTLET_SECTION_BODY); } */ root.appendChild(tBody); HtmlDataTable uiData = (HtmlDataTable) uiComponent; uiData.ensureFirstRowInRange(); // ICE-2783 int rowIndex = uiData.getFirst(); int rowCount = uiData.getRowCount(); if (rowCount == 0) { Element tr = (Element) domContext.createElement(HTML.TR_ELEM); tBody.appendChild(tr); int cols = getNumberOfChildColumns(uiData); if( cols == 0 ) cols = 1; for(int i = 0 ; i < cols ; i++ ){ Element td = (Element) domContext.createElement(HTML.TD_ELEM); tr.appendChild(td); } domContext.stepOver(); return; } if (rowCount >=0 && rowCount <= rowIndex) { domContext.stepOver(); return; } uiData.setRowIndex(rowIndex); int numberOfRowsToDisplay = uiData.getRows(); int countOfRowsDisplayed = 0; String rowStyles[] = getRowStyles(uiComponent); int rowStyleIndex = 0; int rowStylesMaxIndex = rowStyles.length - 1; RowSelector rowSelector = getRowSelector(uiComponent); boolean rowSelectorFound = rowSelector != null; boolean toggleOnClick = false; String rowSelectionFunctionName = null; String rowSelectionUseEvent = "false"; boolean rowSelectorCodeAdded = false; // Row selector code needs to be added to the first TD, adding it to the table body breaks safari Element scriptNode = null; Element hiddenInputNode = null; UIComponent form = DomBasicRenderer.findForm(uiComponent); String formId = form == null ? "" : form.getClientId(facesContext); String paramId = getSelectedRowParameterName(uiComponent.getClientId(facesContext)); if (rowSelectorFound) { toggleOnClick = rowSelector.getToggleOnClick().booleanValue(); Element rowSelectedField = domContext.createElement(HTML.INPUT_ELEM); // toggleOnInput = true/default ==> rowSelectionUseEvent = false // toggleOnInput = false ==> rowSelectionUseEvent = true // since we use the event to thwart toggling from an input boolean toggleOnInput = rowSelector.getToggleOnInput().booleanValue(); rowSelectionUseEvent = toggleOnInput ? "false" : "true"; //rowSelectedField.setAttribute(HTML.ID_ATTR, paramId); rowSelectedField.setAttribute(HTML.NAME_ATTR, paramId); rowSelectedField.setAttribute(HTML.TYPE_ATTR, "hidden"); hiddenInputNode = rowSelectedField; rowSelectionFunctionName = "Ice.tableRowClicked"; } List columnWidthList = getColumnWidthsAsList(uiComponent); Boolean isResizable = null; String columnStyles[] = getColumnStyleClasses(uiComponent); int columnStyleIndex; int columnStylesMaxIndex = columnStyles.length - 1; resetGroupState(uiData); while (uiData.isRowAvailable()) { columnStyleIndex = 0; String selectedClass = null; if (rowStylesMaxIndex >= 0) { selectedClass = rowStyles[rowStyleIndex]; } Iterator childs = uiData.getChildren().iterator(); Element tr = (Element) domContext.createElement(HTML.TR_ELEM); if (rowSelectorFound && toggleOnClick) { tr.setAttribute("onclick", rowSelectionFunctionName + "(event, "+rowSelectionUseEvent+",'"+uiData.getRowIndex()+ "', '"+ formId +"', '"+ paramId +"');"); } String id = uiComponent.getClientId(facesContext); tr.setAttribute(HTML.ID_ATTR, ClientIdPool.get(id)); if (rowSelectorFound) { if (Boolean.TRUE.equals(rowSelector.getValue())){ selectedClass += " "+ rowSelector.getSelectedClass(); tr.setAttribute(HTML.ONMOUSEOVER_ATTR, "this.className='"+ CoreUtils.getPortletStyleClass("portlet-section-body-hover") + " "+ rowSelector.getSelectedMouseOverClass() +"'"); } else { selectedClass += " "+ rowSelector.getStyleClass(); tr.setAttribute(HTML.ONMOUSEOVER_ATTR, "this.className='"+ CoreUtils.getPortletStyleClass("portlet-section-body-hover") + " "+ rowSelector.getMouseOverClass() +"'"); } // tr.setAttribute(HTML.ONMOUSEOUT_ATTR, "this.className='"+ selectedClass +"'"); commented out for ICE-2571 tr.setAttribute(HTML.ONMOUSEOUT_ATTR, "this.className='" + getPortletAlternateRowClass(selectedClass, rowIndex) + "'"); // ICE-2571 } domContext.setCursorParent(tBody); tBody.appendChild(tr); selectedClass = getPortletAlternateRowClass(selectedClass, rowIndex); tr.setAttribute(HTML.CLASS_ATTR, CSSNamePool.get(selectedClass)); if(rowStylesMaxIndex >= 0){ // Thanks denis tsyplakov if (++rowStyleIndex > rowStylesMaxIndex) { rowStyleIndex = 0; } } int colNumber = 1; Iterator columnWidths = null; if (columnWidthList != null) { columnWidths = columnWidthList.iterator(); } while (childs.hasNext()) { String width = "100%"; if (scrollable && columnWidths != null && columnWidths.hasNext()) { width = (String) columnWidths.next(); } UIComponent nextChild = (UIComponent) childs.next(); if (nextChild.isRendered()) { if (nextChild instanceof UIColumn) { Element td = domContext.createElement(HTML.TD_ELEM); String iceColumnStyle = null; String iceColumnStyleClass = null; //we want to perform this operation on ice:column only if (nextChild instanceof com.icesoft.faces.component.ext.UIColumn) { com.icesoft.faces.component.ext.UIColumn iceColumn = (com.icesoft.faces.component.ext.UIColumn)nextChild; iceColumnStyle = iceColumn.getStyle(); iceColumnStyleClass = iceColumn.getStyleClass(); if (iceColumn.getGroupOn() != null) { if (iceColumn.groupFound()) { Element groupedTd = iceColumn.getGroupedTd(); groupedTd.setAttribute(HTML.ROWSPAN_ATTR, String.valueOf(iceColumn.getGroupCount())); if (isResizable == null) { // Lazily get this once isResizable = Boolean.valueOf(uiData.isResizable()); } if (isResizable.booleanValue() && childs.hasNext()) { Element eTd = domContext.createElement(HTML.TD_ELEM); eTd.setAttribute(HTML.CLASS_ATTR, "iceDatTblBlkTd"); Element img = domContext.createElement(HTML.IMG_ELEM); img.setAttribute(HTML.SRC_ATTR, CoreUtils.resolveResourceURL( FacesContext.getCurrentInstance(), "/xmlhttp/css/xp/css-images/spacer.gif") ); eTd.appendChild(img); tr.appendChild(eTd); } continue; } else { iceColumn.setGroupedTd(td); } } } // if (uiData.isResizable()) { // td.setAttribute(HTML.COLSPAN_ATTR, "2"); // } if(!rowSelectorCodeAdded && scriptNode != null){ td.appendChild(scriptNode); } if (null != hiddenInputNode) { td.appendChild(hiddenInputNode); } writeColStyles(columnStyles, columnStylesMaxIndex, columnStyleIndex, td, colNumber++, uiComponent); if (scrollable && width != null) { td.setAttribute("style", "width:" + width + ";overflow:hidden;"); } if (iceColumnStyle != null) { String existingStyle = td.getAttribute(HTML.STYLE_ATTR); if (existingStyle != null) { td.setAttribute(HTML.STYLE_ATTR, existingStyle + ";"+ iceColumnStyle); } else { td.setAttribute(HTML.STYLE_ATTR, iceColumnStyle); } } if (iceColumnStyleClass != null) { String existingStyleClass = td.getAttribute(HTML.CLASS_ATTR); if (existingStyleClass != null) { td.setAttribute(HTML.CLASS_ATTR, CSSNamePool.get(existingStyleClass + " "+ iceColumnStyleClass)); } else { td.setAttribute(HTML.CLASS_ATTR, CSSNamePool.get(iceColumnStyleClass)); } } tr.appendChild(td); // if column styles exist, then apply the appropriate one if (isResizable == null) { // Lazily get this once isResizable = Boolean.valueOf(uiData.isResizable()); } if (isResizable.booleanValue() && childs.hasNext()) { Element eTd = domContext.createElement(HTML.TD_ELEM); eTd.setAttribute(HTML.CLASS_ATTR, "iceDatTblBlkTd"); Element img = domContext.createElement(HTML.IMG_ELEM); img.setAttribute(HTML.SRC_ATTR, CoreUtils.resolveResourceURL( FacesContext.getCurrentInstance(), "/xmlhttp/css/xp/css-images/spacer.gif") ); eTd.appendChild(img); tr.appendChild(eTd); } if (++columnStyleIndex > columnStylesMaxIndex) { columnStyleIndex = 0; } Node oldCursorParent = domContext.getCursorParent(); domContext.setCursorParent(td); encodeParentAndChildren(facesContext, nextChild); domContext.setCursorParent(oldCursorParent); } else if (nextChild instanceof UIColumns) { nextChild.encodeBegin(facesContext); encodeColumns(facesContext, nextChild, domContext, tr, columnStyles, columnStylesMaxIndex, columnStyleIndex, colNumber, width, hiddenInputNode); nextChild.encodeEnd(facesContext); colNumber = uiData.getColNumber(); } } } rowIndex++; countOfRowsDisplayed++; if ((numberOfRowsToDisplay > 0 && countOfRowsDisplayed >= numberOfRowsToDisplay) || (rowCount >=0 && rowIndex >= rowCount)) { break; } uiData.setRowIndex(rowIndex); } uiData.setRowIndex(-1); domContext.stepOver(); } private void encodeColumns(FacesContext facesContext, UIComponent columns, DOMContext domContext, Node tr, String[] columnStyles, int columnStylesMaxIndex, int columnStyleIndex, int colNumber, String width, Element rowSelectorHiddenField) throws IOException { UIColumns uiList = (UIColumns) columns; int rowIndex = uiList.getFirst(); uiList.setRowIndex(rowIndex); int numberOfRowsToDisplay = uiList.getRows(); int countOfRowsDisplayed = 0; domContext.setCursorParent(tr); Node oldCursorParent = domContext.getCursorParent(); while (uiList.isRowAvailable()) { if ((numberOfRowsToDisplay > 0) && (countOfRowsDisplayed >= numberOfRowsToDisplay)) { break; } Iterator childs; childs = columns.getChildren().iterator(); Element td = domContext.createElement(HTML.TD_ELEM); if (null != rowSelectorHiddenField) { td.appendChild(rowSelectorHiddenField); } if (width != null) { td.setAttribute("style", "width:" + width + ";overflow:hidden;"); } domContext.setCursorParent(oldCursorParent); tr.appendChild(td); while (childs.hasNext()) { UIComponent nextChild = (UIComponent) childs.next(); if (nextChild.isRendered()) { domContext.setCursorParent(td); writeColStyles(columnStyles, columnStylesMaxIndex, columnStyleIndex, td, colNumber++, columns.getParent()); if (++columnStyleIndex > columnStylesMaxIndex) { columnStyleIndex = 0; } encodeParentAndChildren(facesContext, nextChild); domContext.setCursorParent(oldCursorParent); } } rowIndex++; countOfRowsDisplayed++; uiList.setRowIndex(rowIndex); } ((HtmlDataTable) uiList.getParent()).setColNumber(colNumber); uiList.setRowIndex(-1); } protected List getRenderedChildColumnsList(UIComponent component) { List results = new ArrayList(); Iterator kids = component.getChildren().iterator(); while (kids.hasNext()) { UIComponent kid = (UIComponent) kids.next(); if (((kid instanceof UIColumn) && kid.isRendered()) || kid instanceof UIColumns) { results.add(kid); } } return results; } protected boolean childColumnHasFacetWithName(UIComponent component, String facetName) { Iterator childColumns = getRenderedChildColumnsIterator(component); while (childColumns.hasNext()) { UIComponent nextChildColumn = (UIComponent) childColumns.next(); if (getFacetByName(nextChildColumn, facetName) != null) { return true; } } return false; } public static String getSelectedRowParameterName(String dataTableId) { // strip the last ':' because the Datatables client Id changes for each iterator int i = dataTableId.lastIndexOf(":"); dataTableId = dataTableId.substring(0, i); return dataTableId + SELECTED_ROWS; } public static RowSelector getRowSelector(UIComponent comp) { if (comp instanceof RowSelector) { return (RowSelector) comp; } Iterator iter = comp.getChildren().iterator(); while (iter.hasNext()) { UIComponent kid = (UIComponent) iter.next(); if (kid instanceof HtmlDataTable){ // Nested HtmlDataTable might be a peer of // a later, valid RowSelector, so don't // traverse in, but keep looking continue; } RowSelector rs = getRowSelector(kid); if (rs != null) { if(!rs.isRendered()) return null; return rs; } } return null; } private int rowSelectorNumber(FacesContext context){ Map m = context.getExternalContext().getRequestMap(); String key = RowSelector.class.getName() + "-Selector"; Integer I = (Integer)m.get(key); int i = 0; if(I != null){ i = I.intValue(); i++; } I = new Integer(i); m.put(key, I); return i; } protected int getNumberOfChildColumns(UIComponent component) { int size = getRenderedChildColumnsList(component).size(); Iterator it = getRenderedChildColumnsList(component).iterator(); while (it.hasNext()) { UIComponent uiComponent = (UIComponent)it.next(); if (uiComponent instanceof UIColumns) { size +=((UIColumns)uiComponent).getRowCount(); } } return size; } protected String[] getColumnStyleClasses(UIComponent uiComponent) { String[] columnStyles = super.getColumnStyleClasses(uiComponent); if (columnStyles.length == 0) { columnStyles = new String[2]; columnStyles[0] = Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_COLUMN_CLASS1); columnStyles[1] = Util.getQualifiedStyleClass(uiComponent, CSS_DEFAULT.TABLE_COLUMN_CLASS2); } else { for (int i=0; i < columnStyles.length; i++) { columnStyles[i] = Util.getQualifiedStyleClass(uiComponent, columnStyles[i], CSS_DEFAULT.TABLE_COLUMN_CLASS, "columnClasses" ); } } return columnStyles; } public String[] getRowStyleClasses(UIComponent uiComponent) { String[] rowClasses = super.getRowStyleClasses(uiComponent); for (int i=0; i < rowClasses.length; i++) { rowClasses[i] = Util.getQualifiedStyleClass(uiComponent, rowClasses[i], CSS_DEFAULT.TABLE_ROW_CLASS, "rowClasses" ); } return rowClasses; } public String[] getHeaderStyleClasses(UIComponent uiComponent) { String headerClass = getHeaderClass(uiComponent). replaceAll(CSS_DEFAULT.TABLE_STYLE_CLASS + CSS_DEFAULT.TABLE_HEADER_CLASS, ""); String[] headerClasses = getStyleClasses(uiComponent, "headerClasses"); for (int i=0; i < headerClasses.length; i++) { headerClasses[i] = CSSNamePool.get(Util.getQualifiedStyleClass(uiComponent, headerClasses[i], CSS_DEFAULT.TABLE_COLUMN_HEADER_CLASS, "headerClasses" )+ ((headerClass.length() > 0) ? headerClass : "")); } return headerClasses; } String getPortletAlternateRowClass(String selectedClass, int rowIndex) { String rowClass = PORTLET_CSS_DEFAULT.PORTLET_SECTION_ALTERNATE; if ((rowIndex % 2) == 0) { rowClass = PORTLET_CSS_DEFAULT.PORTLET_SECTION_BODY; } if (selectedClass.indexOf(' ') > 1) { return selectedClass.replaceFirst(" ", " " + CoreUtils.getPortletStyleClass(rowClass + " ")); } else { return selectedClass += CoreUtils.getPortletStyleClass("" + rowClass); } } void resetGroupState(UIComponent uiComponent) { Iterator childs = uiComponent.getChildren().iterator(); while(childs.hasNext()) { UIComponent child = (UIComponent) childs.next(); if (child instanceof com.icesoft.faces.component.ext.UIColumn) { ((com.icesoft.faces.component.ext.UIColumn)child).resetGroupState(); } } } }