/*
* � Copyright IBM Corp. 2010, 2015
*
* Licensed under the Apache License, Version 2.0 (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.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
* implied. See the License for the specific language governing
* permissions and limitations under the License.
*/
package com.ibm.xsp.extlib.renderkit.html_extended.data;
import java.io.IOException;
import java.util.List;
import java.util.Map;
import javax.faces.component.NamingContainer;
import javax.faces.component.UIComponent;
import javax.faces.context.FacesContext;
import javax.faces.context.ResponseWriter;
import javax.faces.model.DataModel;
import com.ibm.commons.util.StringUtil;
import com.ibm.xsp.component.UIViewColumn;
import com.ibm.xsp.context.FacesContextEx;
import com.ibm.xsp.extlib.component.data.AbstractDataView;
import com.ibm.xsp.extlib.component.data.CategoryColumn;
import com.ibm.xsp.extlib.component.data.ExtraColumn;
import com.ibm.xsp.extlib.component.data.UIDataSourceIterator;
import com.ibm.xsp.extlib.component.data.UIDataView;
import com.ibm.xsp.extlib.component.data.ValueColumn;
import com.ibm.xsp.extlib.component.image.IconEntry;
import com.ibm.xsp.extlib.util.ExtLibRenderUtil;
import com.ibm.xsp.extlib.util.ExtLibUtil;
import com.ibm.xsp.model.TabularDataModel;
import com.ibm.xsp.model.ViewRowData;
import com.ibm.xsp.model.domino.DominoViewDataModel;
import com.ibm.xsp.renderkit.html_basic.HtmlRendererUtil;
import com.ibm.xsp.renderkit.html_extended.RenderUtil;
import com.ibm.xsp.util.DirLangUtil;
import com.ibm.xsp.util.FacesUtil;
import com.ibm.xsp.util.JavaScriptUtil;
import com.ibm.xsp.util.TypedUtil;
/**
* {@link UIDataView} renderer.
*/
public class DataViewRenderer extends AbstractWebDataViewRenderer {
public static final String INTERNAL_CHECKBOX_ID = UIViewColumn.INTERNAL_CHECKBOX_ID;
protected static final int PROP_TABLECLASS = 200;
protected static final int PROP_TABLEROWCLASS = 201;
protected static final int PROP_TABLEFIRSTROWCLASS = 202;
protected static final int PROP_TABLELASTROWCLASS = 203;
protected static final int PROP_TABLEFIRSTCELLCLASS = 204;
protected static final int PROP_TABLELASTCELLCLASS = 205;
protected static final int PROP_TABLEROWINDENTPX = 206;
protected static final int PROP_TABLEROWEXTRA = 207;
protected static final int PROP_TABLEHDRROWCLASS = 210;
protected static final int PROP_TABLEHDRCOLSTYLE = 211;
protected static final int PROP_TABLEHDRFIRSTCOLCLASS = 212;
protected static final int PROP_TABLEHDRCOLCLASS = 213;
protected static final int PROP_TABLEHDRCOLLKASCCLASS = 214;
protected static final int PROP_TABLEHDRCOLLKDESCLASS = 215;
@Override
protected Object getProperty(int prop) {
{
// translating some extra strings that are unused here in the extlib.control plugin,
// but are used in the other themes - e.g. the bootstrap DataViewRenderer.
String str = "";
str = "Unread document";// $NLS-DataViewRenderer.Unreaddocument-1$
str = "Read document"; // $NLS-DataViewRenderer.Readdocument-1$
str = "Sortable column, currently not sorted"; // $NLS-DataViewRenderer.Sortablecolumncurrentlynotsorted-1$
str = "Sortable column, currently sorted in ascending order"; // $NLS-DataViewRenderer.Sortablecolumncurrentlysortedinas-1$
str = "Sortable column, currently sorted in descending order"; // $NLS-DataViewRenderer.Sortablecolumncurrentlysortedinde-1$
str = "Column sortable in descending order, currently not sorted "; // $NLS-DataViewRenderer.Columnsortableindescendingordercu-1$
str.getClass(); // prevent unused variable warning
}// end translating extra string
switch(prop) {
}
return super.getProperty(prop);
}
// ================================================================
// Runtime view definition object
// ================================================================
@Override
protected void initViewDefinition(FacesContext context, AbstractDataView _dataView, ViewDefinition viewDef) {
UIDataView dataView = (UIDataView)_dataView;
super.initViewDefinition(context, dataView, viewDef);
List<UIComponent> children = TypedUtil.getChildren(dataView);
viewDef.columnTitles = dataView.isColumnTitles();
viewDef.collapsibleCategory = dataView.isCollapsibleCategory();
viewDef.collapsibleRows = dataView.isCollapsibleRows();
viewDef.multiColumnCount = Math.max(1,dataView.getMultiColumnCount());
viewDef.categoryColumns = dataView.getCategoryColumn();
viewDef.categoryCount = viewDef.categoryColumns!=null ? viewDef.categoryColumns.size() : 0;
if(!children.isEmpty()) {
UIComponent row = children.get(0);
viewDef.iconFacet = row.getFacet(UIDataView.FACET_ICON);// row facet
}
viewDef.hasCategoryRow = viewDef.categoryCount>0 || getCategoryRowFacet(_dataView, 0)!=null;
viewDef.hasCheckBoxColumn = dataView.isShowCheckbox();
viewDef.hasHeaderCheckBoxColumn = dataView.isShowHeaderCheckbox();
if(viewDef.hasCheckBoxColumn) {
viewDef.checkboxFieldName = dataView.getClientId(context)+":_colcbox"; // $NON-NLS-1$
viewDef.checkboxFieldNamePrefix = dataView.getClientId(context);
viewDef.checkboxFieldNameSuffix = ":_colcbox"; // $NON-NLS-1$
}
viewDef.iconColumn = dataView.getIconColumn();
viewDef.hasIconColumn = viewDef.iconColumn!=null || viewDef.iconFacet!=null;
viewDef.extraColumns = dataView.getExtraColumns();
viewDef.hasExtraColumns = viewDef.extraColumns!=null && !viewDef.extraColumns.isEmpty();
viewDef.nColumns = (viewDef.hasCheckBoxColumn?1:0) // CheckBox
+ (viewDef.hasIconColumn?1:0) // Icon
+ 1 // Data - always
+ (viewDef.hasExtraColumns?(viewDef.extraColumns.size()):0) // Extra columns
+ (viewDef.collapsibleDetails?1:0); // Collapsible details
// Apply different constraints
// In case of multiple columns
if(viewDef.multiColumnCount>1) {
// Expand/collapse details must do a full refresh as we cannot refresh a row cell
viewDef.viewRowRefresh = false;
}
viewDef.isInfiniteScroll = getInfiniteScroll(dataView.getInfiniteScroll(), context);
}
public UIComponent getExtraFacet(AbstractDataView dataView, int index){
// the "extra" facets are row facets [see AbstractDataView.getRowFacetNames()]
List<UIComponent> children = TypedUtil.getChildren(dataView);
if( children.isEmpty() ){
// Note, children will only be empty in JUnit tests
// where UIDataView.buildContents is not called.
return null;
}
UIComponent row = children.get(0);
if(index==0) {
UIComponent c = row.getFacet(UIDataView.FACET_EXTRA_N);
if(c!=null) {
return c;
}
}
return row.getFacet(UIDataView.FACET_EXTRA_N+index);
}
public UIComponent getCategoryRowFacet(AbstractDataView dataView, int index){
// the "categoryRow" facets are row facets [see AbstractDataView.getRowFacetNames()]
List<UIComponent> children = TypedUtil.getChildren(dataView);
if( children.isEmpty() ){
// Note, children will only be empty in JUnit tests
// where UIDataView.buildContents is not called.
return null;
}
UIComponent row = children.get(0);
if(index==0) {
UIComponent c = row.getFacet(UIDataView.FACET_CATEGORY_N);
if(c!=null) {
return c;
}
}
return row.getFacet(UIDataView.FACET_CATEGORY_N+index);
}
@Override
protected void afterRows(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
// In case of a multi column view, we try to fill the missing blanks by reading more rows
if(viewDef.multiColumnCount>1) {
if(viewDef.currentColumn<viewDef.multiColumnCount) {
int index = viewDef.first+viewDef.rows;
while(viewDef.currentColumn<viewDef.multiColumnCount) {
c.setRowIndex(index++);
if(!c.isRowAvailable()) {
break;
}
beforeRow(context, w, c, viewDef);
writeRow(context, w, c, viewDef);
afterRow(context, w, c, viewDef);
}
}
}
super.afterRows(context, w, c, viewDef);
}
// ================================================================
// Decode the messages
// ================================================================
@Override
public void decode(FacesContext context, UIComponent component) {
if (context == null || component == null)
throw new NullPointerException();
if (!component.isRendered())
return;
super.decode(context, component);
UIDataView dataView = (component instanceof UIDataView) ? (UIDataView)component : null;
if(null == dataView){
// Might be the row component
return;
}
// Look for a checkbox field
DataModel dm = dataView.getDataModel();
if(dm instanceof TabularDataModel) {
TabularDataModel tbm = (TabularDataModel)dm;
tbm.clearSelectedIds();
// iterate through the rows of the current data page
dataView.setRowIndex(-1);
Map<String, String> params = TypedUtil.getRequestParameterMap(context.getExternalContext());
// dataView.getRows() returns rows shown on page
int pageFirstIndex = dataView.getFirst();
int pageRowCount = dataView.getRows();
int pageEndPageIndex = pageRowCount < 0 ? pageFirstIndex : pageFirstIndex+pageRowCount;
for (int rowIndex = pageFirstIndex; rowIndex < pageEndPageIndex; rowIndex++) {
dataView.setRowIndex(rowIndex);
if(!dataView.isRowAvailable())
break;
// Note _colcbox is UIViewColumn.INTERNAL_CHECKBOX_ID
String cboxName = dataView.getClientId(context) + ":_colcbox"; // $NON-NLS-1$ $NON-NLS-2$
String cboxValue = params.get(cboxName);
if (StringUtil.isNotEmpty(cboxValue) ) {
if (!StringUtil.isFalseValue(cboxValue)) { // !"false".equals
tbm.addSelectedId(cboxValue);
}
}
}
dataView.setRowIndex(-1);
}
}
// ================================================================
// Body
// ================================================================
@Override
protected void writeContent(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("table",c); // $NON-NLS-1$
writeTableTagAttributes(context, w, c, viewDef);
newLine(w);
// Write the column headers
writeColumnHeaders(context, w, c, viewDef);
// And the rows
int first = c.getFirst();
int count = c.getRows();
w.startElement("tbody",c); // $NON-NLS-1$
writeRows(context, w, c, viewDef, first, count);
w.endElement("tbody"); // $NON-NLS-1$
w.endElement("table"); // $NON-NLS-1$
newLine(w);
}
/* (non-Javadoc)
* @see com.ibm.xsp.extlib.renderkit.html_extended.data.AbstractDataViewRenderer#writeDataView(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, com.ibm.xsp.extlib.component.data.AbstractDataView, com.ibm.xsp.extlib.renderkit.html_extended.data.AbstractDataViewRenderer.ViewDefinition)
*/
@Override
protected void writeDataView(FacesContext context, ResponseWriter w,
AbstractDataView c, ViewDefinition viewDef) throws IOException {
super.writeDataView(context, w, c, viewDef);
if(viewDef.isInfiniteScroll)
{
String theme = "?";
if( context instanceof FacesContextEx ){
theme = ((FacesContextEx)context).getStyleKitId();
}
String msg = "The \"infiniteScroll\" property is not supported for the current theme ({0})."; // $NLX-DataViewRenderer.infiniteScrollpropertyhaslimiteds-1$
msg = StringUtil.format(msg, theme);
throw new IOException(msg);
}
}
protected void writeTableTagAttributes(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.writeAttribute("id", c.getAjaxContainerClientId(context), null); // $NON-NLS-1$
String tc = (String)getProperty(PROP_TABLECLASS);
if(StringUtil.isNotEmpty(tc)) {
w.writeAttribute("class", tc, null); // $NON-NLS-1$
}
w.writeAttribute("border", "0", null); // $NON-NLS-1$
w.writeAttribute("cellspacing", "0", null); // $NON-NLS-1$
w.writeAttribute("cellpadding", "0", null); // $NON-NLS-1$
// Accessibility
w.writeAttribute("role", "grid", null); // $NON-NLS-1$ $NON-NLS-2$
// Summary
String summary = ((UIDataView)c).getSummary();
if(StringUtil.isEmpty(summary)){
summary = "A collection of documents with a summary shown for each document"; // $NLS-DataViewRenderer.Tablesummary-1$
}
w.writeAttribute("summary", summary, null); //$NON-NLS-1$
// ARIA Label
String label = ((UIDataView)c).getAriaLabel();
if (StringUtil.isNotEmpty(label)) {
w.writeAttribute("aria-label", label, null); // $NON-NLS-1$
}
}
protected void writeTableRowTagAttributes(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
DataModel dm = viewDef.dataModel;
String styleClass = c.getRowStyleClass();
if(StringUtil.isEmpty(styleClass)) {
styleClass = (String)getProperty(PROP_TABLEROWCLASS);
}
if(dm.getRowIndex()==viewDef.first) {
styleClass = ExtLibUtil.concatStyleClasses((String)getProperty(PROP_TABLEFIRSTROWCLASS),styleClass);
}
if(dm.getRowIndex()==(viewDef.first+viewDef.rows-1)) {
styleClass = ExtLibUtil.concatStyleClasses((String)getProperty(PROP_TABLELASTROWCLASS),styleClass);
}
if(StringUtil.isNotEmpty(styleClass)) {
w.writeAttribute("class", styleClass, null); // $NON-NLS-1$
}
String style = c.getRowStyle();
if(StringUtil.isNotEmpty(style)) {
w.writeAttribute("style", style, null); // $NON-NLS-1$
}
}
protected void writeTableCategoryRowTagAttributes(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
writeTableRowTagAttributes(context, w, c, viewDef);
// String styleClass = c.getRowStyleClass();
// if(StringUtil.isNotEmpty(styleClass)) {
// w.writeAttribute("class", styleClass, null);
// }
// String style = c.getRowStyle();
// if(StringUtil.isNotEmpty(style)) {
// w.writeAttribute("style", style, null);
// }
}
// ================================================================
// Columns headers
// ================================================================
protected void writeColumnHeaders(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
if(!viewDef.columnTitles) {
return;
}
w.startElement("thead",c); // $NON-NLS-1$
w.startElement("tr",c); // $NON-NLS-1$
w.writeAttribute("role", "row", null); // $NON-NLS-1$ $NON-NLS-2$
String clazz = (String)getProperty(PROP_TABLEHDRROWCLASS);
if(StringUtil.isNotEmpty(clazz)) {
w.writeAttribute("class",clazz,null); // $NON-NLS-1$
}
boolean multiColumn = viewDef.multiColumnCount>1;
if(multiColumn) {
// TODO it seems likely that multiColumn display cannot be made accessible,
// may need to remove this feature.
w.startElement("th",c); // $NON-NLS-1$
int colSpan = (viewDef.nColumns)*(viewDef.multiColumnCount);
w.writeAttribute("colspan",colSpan,null); // $NON-NLS-1$
w.startElement("table",c); // $NON-NLS-1$
String summaryForNthDocumentInRow = "Subsection for each document"; // $NLS-DataViewRenderer.SubtableSummary-1$
w.writeAttribute("summary", summaryForNthDocumentInRow, null); // $NON-NLS-1$
w.startElement("thead",c); // $NON-NLS-1$
w.startElement("tr",c); // $NON-NLS-1$
}
writeColumnHeadersContent(context, w, c, viewDef);
if(multiColumn) {
w.endElement("tr"); // $NON-NLS-1$
w.endElement("thead"); // $NON-NLS-1$
w.endElement("table"); // $NON-NLS-1$
w.endElement("th"); // $NON-NLS-1$
}
w.endElement("tr"); // $NON-NLS-1$
w.endElement("thead"); // $NON-NLS-1$
}
protected void writeColumnHeadersContent(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
int idx = 0;
// Add the checkbox columns
if(viewDef.hasCheckBoxColumn) {
writeHeaderCheckBoxColumn(context, w, c, viewDef);
idx++;
}
// Add an empty column for the icon
if(viewDef.hasIconColumn) {
// Just an empty column
writeColumnHeader(context, w, c, viewDef, null, idx++);
}
// Write the summary column
writeColumnHeader(context, w, c, viewDef, viewDef.summaryColumn, idx++);
// Then the extra columns
if(viewDef.hasExtraColumns) {
List<ExtraColumn> extraColumns = viewDef.extraColumns;
int count = extraColumns.size();
for(int i=0; i<count; i++) {
ExtraColumn col = extraColumns.get(i);
writeColumnHeader(context, w, c, viewDef, col, idx++);
}
}
// Add an empty column for the toggle twistie
if (viewDef.collapsibleDetails) {
// Just an empty column
writeColumnHeader(context, w, c, viewDef, null, idx++);
}
}
protected void writeHeaderCheckBoxColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("th",c); // $NON-NLS-1$
w.writeAttribute("scope", "col", null); // $NON-NLS-1$ $NON-NLS-2$
String colClazz = (String)getProperty(PROP_TABLEFIRSTCELLCLASS);
if(StringUtil.isNotEmpty(colClazz)) {
w.writeAttribute("class",colClazz,null); // $NON-NLS-1$
}
if(viewDef.hasHeaderCheckBoxColumn) {
String fldName = c.getClientId(context)+":_hdrcbox"; // $NON-NLS-1$
w.startElement("input",c); // $NON-NLS-1$
w.writeAttribute("type","checkbox",null); // $NON-NLS-1$ $NON-NLS-2$
w.writeAttribute("name",fldName,null); // $NON-NLS-1$
w.writeAttribute("id",fldName,null); // $NON-NLS-1$
// Specify title attribute for accessibility
String title = "Select all rows"; // $NLS-DataViewRenderer_HeaderCheckboxTitle-1$
w.writeAttribute("title",title,null); // $NON-NLS-1$
w.writeAttribute("role", "checkbox", null);// $NON-NLS-1$ // $NON-NLS-2$
//Add JS onclick code to handle toggling aria-checked attribute
writeHeaderCheckboxAccessibilityAttributes(context, w, c.getClientId(context), fldName);
StringBuilder sBuf = new StringBuilder(256); //$NON-NLS-1$
sBuf.append("XSP.attachViewColumnCheckboxToggler("); //$NON-NLS-1$
JavaScriptUtil.addString(sBuf, c.getClientId(context));
sBuf.append(", "); //$NON-NLS-1$
JavaScriptUtil.addString(sBuf, c.getClientId(context));
sBuf.append("); "); //$NON-NLS-1$
JavaScriptUtil.addScriptOnLoad(sBuf.toString());
}
w.endElement("th"); // $NON-NLS-1$
}
protected void writeColumnHeader(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef, ValueColumn vc, int colIndex) throws IOException {
// Write the summary column
w.startElement("th",c); // $NON-NLS-1$
w.writeAttribute("scope", "col", null); // $NON-NLS-1$ $NON-NLS-2$
String style = ExtLibUtil.concatStyles((String)getProperty(PROP_TABLEHDRCOLSTYLE),vc!=null?vc.getHeaderStyle():null);
if(StringUtil.isNotEmpty(style)) {
w.writeAttribute("style",style,null); // $NON-NLS-1$
}
String clazz = ExtLibUtil.concatStyleClasses((String)getProperty(colIndex==0 ? PROP_TABLEHDRFIRSTCOLCLASS : PROP_TABLEHDRCOLCLASS),vc!=null?vc.getHeaderStyleClass():null);
if(StringUtil.isNotEmpty(clazz)) {
w.writeAttribute("class",clazz,null); // $NON-NLS-1$
}
if(vc!=null) {
String colTitle = vc.getColumnTitle();
if(StringUtil.isNotEmpty(colTitle)) {
w.startElement("span",c); // $NON-NLS-1$
String colName = vc.getColumnName();
// Kind of hard coded here, which is not clean...
boolean dominoStyleIcons = viewDef.dataModel instanceof DominoViewDataModel;
boolean sortable = false;
if(StringUtil.isNotEmpty(colName)) {
sortable = isColumnSortable(context, c, viewDef, colName);
}
if(sortable) {
String linkId = c.getClientId(context) + SORT_DELIMITER + colName;
w.startElement("a",c);
w.writeAttribute("id",linkId,null); // $NON-NLS-1$
String headerTitle = vc.getHeaderLinkTitle();
if(StringUtil.isEmpty(headerTitle)){
headerTitle = "Click to reverse sort"; // $NLS-DataViewRenderer_SortLinkTooltip_ClickToReverseSort-1$
}
//adding the Header accessibility title
w.writeAttribute("title", headerTitle, null); // $NON-NLS-1$
if(!dominoStyleIcons) {
int sortState = getColumnSortState(context, c, viewDef, colName);
if(sortState==TabularDataModel.RESORT_ASCENDING) {
String clazz2 = (String)getProperty(PROP_TABLEHDRCOLLKASCCLASS);
if(StringUtil.isNotEmpty(clazz2)) {
w.writeAttribute("class",clazz2,null); // $NON-NLS-1$
}
} else if(sortState==TabularDataModel.RESORT_DESCENDING) {
String clazz2 = (String)getProperty(PROP_TABLEHDRCOLLKDESCLASS);
if(StringUtil.isNotEmpty(clazz2)) {
w.writeAttribute("class",clazz2,null); // $NON-NLS-1$
}
}
}
w.writeAttribute("href","javascript:;",null); // $NON-NLS-1$ $NON-NLS-2$
//LHEY97CCSZ adding the role=button
w.writeAttribute("role", "button", null); // $NON-NLS-1$ // $NON-NLS-2$
setupSubmitOnClick(context, c, linkId, linkId, null);
}
boolean multiColumn = viewDef.multiColumnCount>1;
if(!multiColumn || sortable) {
w.writeText(colTitle,null);
}
if(sortable) {
w.endElement("a");
}
if(dominoStyleIcons) {
int dominoSortIconCode = getDominoSortIconCode(context, c, viewDef, colName);
String src = getDominoSortIcon(context, c, viewDef, dominoSortIconCode);
if(StringUtil.isNotEmpty(src)) {
w.startElement("img",c); // $NON-NLS-1$
w.writeAttribute("src",HtmlRendererUtil.getImageURL(context,src),null); // $NON-NLS-1$
String sortIconAlt = getDominoSortAlt(context, c, viewDef, dominoSortIconCode);
if( ExtLibRenderUtil.isAltPresent(sortIconAlt) ){
w.writeAttribute("alt", sortIconAlt, null); //$NON-NLS-1$
}
String sortIconWidth = (String) getProperty(PROP_TABLEHDRCOLIMAGE_SORT_WIDTH);
if( StringUtil.isNotEmpty(sortIconWidth) ){
w.writeAttribute("width", sortIconWidth, null); //$NON-NLS-1$
}
String sortIconHeight = (String) getProperty(PROP_TABLEHDRCOLIMAGE_SORT_HEIGHT);
if( StringUtil.isNotEmpty(sortIconHeight) ){
w.writeAttribute("height", sortIconHeight, null); //$NON-NLS-1$
}
w.endElement("img"); // $NON-NLS-1$
}
}
w.endElement("span"); // $NON-NLS-1$
}
}
w.endElement("th"); // $NON-NLS-1$
}
// ================================================================
// View rows
// ================================================================
@Override
protected void writeRows(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef, int first, int rows) throws IOException {
super.writeRows(context, w, c, viewDef, first, rows);
// Ensure that the current row is properly closed
closeOpenedRow(context, w, c, viewDef);
}
@Override
protected void writeRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
if(isCategoryRow(context, c, viewDef)) {
closeOpenedRow(context, w, c, viewDef);
if(viewDef.hasCategoryRow) {
writeCategoryRow(context, w, c, viewDef);
}
} else if(isTotalRow(context, c, viewDef)) {
closeOpenedRow(context, w, c, viewDef);
writeTotalRow(context, w, c, viewDef);
} else {
// Close the current if we exceed the number of desired columns
if(viewDef.currentColumn>=viewDef.multiColumnCount) {
closeOpenedRow(context, w, c, viewDef);
}
writeStandardRow(context, w, c, viewDef);
}
}
protected void closeOpenedRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
// If column was emitted, close it
if(viewDef.currentColumn>0) {
w.endElement("tr"); // $NON-NLS-1$
newLine(w);
viewDef.currentColumn = 0;
}
}
protected void writeCategoryRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("tr",c); // $NON-NLS-1$
w.writeAttribute("role", "row", null); // $NON-NLS-1$ $NON-NLS-2$
String id = viewDef.dataView.getClientId(context)+NamingContainer.SEPARATOR_CHAR+UIDataView.ROW_ID;
w.writeAttribute("id", id, null); // $NON-NLS-1$
// Write the row style attributes
writeTableCategoryRowTagAttributes(context, w, c, viewDef);
// Write the data column
writeCategoryColumn(context, w, c, viewDef);
}
protected void writeCategoryColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("th",c); // $NON-NLS-1$
w.writeAttribute("scope", "row", null); // $NON-NLS-1$ $NON-NLS-2$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
int colSpan = (viewDef.nColumns)*(viewDef.multiColumnCount);
if(colSpan>1) {
w.writeAttribute("colspan",colSpan,null); // $NON-NLS-1$
}
w.startElement("h4",c); // $NON-NLS-1$
int categoryListIndex = findCategoryListIndex(context, c, viewDef, viewDef.categoryColumns);
CategoryColumn categoryColumn = null;
if( -1 != categoryListIndex){
categoryColumn = viewDef.categoryColumns.get(categoryListIndex);
}
if(categoryColumn!=null) {
String styleClass = categoryColumn.getStyleClass();
if(StringUtil.isNotEmpty(styleClass)) {
w.writeAttribute("class",styleClass,null); // $NON-NLS-1$
}
int indentLevel = getIndentLevel(viewDef);
String indentStyle = getIndentStyle(context,c,viewDef,categoryListIndex, indentLevel);
String style = categoryColumn.getStyle();
style = ExtLibUtil.concatStyles(indentStyle,style);
// Ensure that the h4 margin is reset to 0
style = ExtLibUtil.concatStyles("margin:0;",style); // $NON-NLS-1$
w.writeAttribute("style",style,null); // $NON-NLS-1$
} else {
// Ensure that the h4 margin is reset to 0
w.writeAttribute("style","margin: 0",null); // $NON-NLS-1$ $NON-NLS-2$
}
// Expand/collapse icon
if(viewDef.collapsibleCategory) {
writeExpandCollapseIcon(context, w, c, viewDef);
}
if(categoryColumn!=null) {
UIComponent categoryFacet = getCategoryRowFacet(c,categoryListIndex);
if(categoryFacet!=null) {
FacesUtil.renderChildren(context, categoryFacet);
}else{
writeColumnValue(context, w, c, viewDef, categoryColumn);
}
}
w.endElement("h4"); // $NON-NLS-1$
w.endElement("th"); // $NON-NLS-1$
// We mark all the columns as being written
viewDef.currentColumn = viewDef.multiColumnCount;
}
/**
* @param context
* @param c
* @param viewDef
* @param categoryColumns
* @return
*/
protected int findCategoryListIndex(FacesContext context, AbstractDataView c,
ViewDefinition viewDef, List<CategoryColumn> categoryColumns) {
// note this assumes the current row is a category row.
if( null == categoryColumns ){
// this is a category row, but there are no category columns.
return -1;
}
TabularDataModel tdm;
DataModel dm = viewDef.dataModel;
if(dm instanceof TabularDataModel) {
tdm = (TabularDataModel)dm;
}else{
// only know how to figure out categorizations for tabular data
return -1;
}
ViewRowData viewRowData = null;
Object rowData = tdm.getRowData();
if (rowData instanceof ViewRowData){
viewRowData = (ViewRowData)rowData;
}
// first attempt to find a match based on columnName
int length = categoryColumns.size();
for (int i = 0; i < length; i++) {
CategoryColumn categoryColumn = categoryColumns.get(i);
String columnName = categoryColumn.getColumnName();
if( StringUtil.isEmpty(columnName) ){
// columnName is required, but was not present in early openNTF extlib releases
continue;
}
// verify the column is categorized in the view Design Element
// (says nothing about this category row).
if( ! tdm.isColumnCategorized(columnName) ){
continue;
}
// if some value is present under the columnName in this categorizedRow,
// then this column is the categorized column for the category row
Object columnValue = (null == viewRowData)? null : viewRowData.getColumnValue(columnName);
boolean isColumnValuePresent = null != columnValue && ! StringUtil.isEmpty(columnValue.toString());
if( isColumnValuePresent ){
return i;
}
}
// Only empty values found when checking column values by columnName,
// maybe this is the "Not Categorized" category - where documents
// that don't have any value in the category column are placed.
// a category row's position string will be like "outerCatColValue2.innerCatColValue5"
// The number of segments in the position string will correspond
// to the nth category column in the view design element.
String rowPosition = tdm.getRowPosition();
int positionDotCount = countDots(rowPosition);
for (int i = 0; i < length; i++) {
CategoryColumn categoryColumn = categoryColumns.get(i);
String columnName = categoryColumn.getColumnName();
if( StringUtil.isEmpty(columnName) || ! tdm.isColumnCategorized(columnName)){
continue;
}
// The category column index is, in the domino view design element
// this is the nth category column - that is, the index excluding
// non-category columns.
int categoryColumnIndex = tdm.getCategoryColumnIndex(columnName);
if( Integer.MIN_VALUE != categoryColumnIndex ){
if( positionDotCount == categoryColumnIndex ){
return i;
}
}
}
// probably the columnName is missing
// attempt to match by categoryIndentLevel,
// which will only work if the columns in the XPage source exactly
// match the column indexes in the Domino view design element,
// and is likely to display wrong values.
int indentLevel = tdm.getCategoryIndentLevel();
if( indentLevel>= 0 && indentLevel < length ){
return indentLevel;
}
if( length == 1 && StringUtil.isEmpty(categoryColumns.get(0).getColumnName()) ){
// there is only a single categoryColumn, created
// by the UIDataView.buildContents method,
// display all category rows using that column.
return 0;
}
// TODO If the category row also contains a total value
// this is incorrectly displaying the total number instead
// of the category value.
return -1;
}
/**
* @param rowPosition
* @return
*/
private int countDots(String rowPosition) {
int count = 0;
int dotIndex = rowPosition.indexOf('.');
while( -1 != dotIndex ){
count++;
dotIndex = rowPosition.indexOf('.', dotIndex+1);
}
return count;
}
protected void writeTotalRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
// w.startElement("tr",c);
// String id = viewDef.dataView.getClientId(context)+NamingContainer.SEPARATOR_CHAR+UIDataView.ROW_ID;
// w.writeAttribute("id", id, null);
// w.endElement("tr");
// newLine(w);
}
protected void writeStandardRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
// Start a new TR if we start a new row
if(viewDef.currentColumn==0) {
w.startElement("tr",c); // $NON-NLS-1$
w.writeAttribute("role", "row", null); // $NON-NLS-1$ $NON-NLS-2$
String id = viewDef.dataView.getClientId(context)+NamingContainer.SEPARATOR_CHAR+UIDataView.ROW_ID;
w.writeAttribute("id", id, null); // $NON-NLS-1$
// Write the row style attributes
writeTableRowTagAttributes(context, w, c, viewDef);
}
if( viewDef.summaryOrDetailVisible && viewDef.rowDetailVisible ){
writeDetailRow(context, w, c, viewDef);
}else{
// Write the Checkbox column
if(viewDef.hasCheckBoxColumn) {
writeCheckBoxColumn(context, w, c, viewDef);
}
// Write the Icon column
if(viewDef.hasIconColumn) {
writeIconColumn(context, w, c, viewDef);
}
// Write the data column
writeDataColumn(context, w, c, viewDef);
// Write the extra columns
if(viewDef.hasExtraColumns) {
writeExtraColumns(context, w, c, viewDef);
}
// Write the hide/show icon
writeShowHideDetailCell(context, w, c, viewDef);
}
// Leave the row opened for more columns....
//w.endElement("tr");
//newLine(w);
viewDef.currentColumn++;
}
protected void writeDetailRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
boolean displayIconCell = viewDef.hasIconColumn;
boolean displayShowHideCell = viewDef.collapsibleDetails;
if( displayIconCell ){
// empty icon column.
w.startElement("td", c); // $NON-NLS-1$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
w.endElement("td"); // $NON-NLS-1$
}
// start the detail cell
w.startElement("td",c); // $NON-NLS-1$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
// colspan the td
int colSpan = viewDef.nColumns + (displayIconCell? -1 : 0) + (displayShowHideCell? -1 : 0);
if(colSpan>1) {
w.writeAttribute("colspan",colSpan,null); // $NON-NLS-1$
}
// Enclosing divs
w.startElement("div",c); // $NON-NLS-1$
int level = getColumnIndentLevel(context, c, viewDef);
int catLevel = Math.max(0, viewDef.categoryCount-1);
String style = getIndentStyle(context, c, viewDef, level+catLevel);
if(StringUtil.isNotEmpty(style)) {
w.writeAttribute("style",style,null); // $NON-NLS-1$
}
writeDetail(context, w, c, viewDef);
w.endElement("div"); // $NON-NLS-1$
w.endElement("td"); // $NON-NLS-1$
// end the detail cell
if( displayShowHideCell ){
// Write the hide/show icon
writeShowHideDetailCell(context, w, c, viewDef);
}
}
protected void writeCheckBoxColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("td",c); // $NON-NLS-1$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
String colClazz = (String)getProperty(PROP_TABLEFIRSTCELLCLASS);
if(StringUtil.isNotEmpty(colClazz)) {
w.writeAttribute("class",colClazz,null); // $NON-NLS-1$
}
String value = null;
if(viewDef.dataModel instanceof TabularDataModel) {
value = ((TabularDataModel)viewDef.dataModel).getRowId();
}
if(StringUtil.isNotEmpty(value)) {
w.startElement("input",c); // $NON-NLS-1$
w.writeAttribute("type","checkbox",null); // $NON-NLS-1$ $NON-NLS-2$
// For a group of inputs, the name must be the same for each element in
// order to establish the "grouping" of the elements
// the ID is different though.. it should be unique regardless of grouping or not
w.writeAttribute("name",viewDef.checkboxFieldNamePrefix + ":" + c.getRowIndex() + viewDef.checkboxFieldNameSuffix, null); // $NON-NLS-1$
// See xspClientDojo.js _toggleViewColumnCheckBoxes function - we can put row index only in the middle
String id = viewDef.checkboxFieldNamePrefix + ":" + c.getRowIndex() + viewDef.checkboxFieldNameSuffix; // $NON-NLS-1$
w.writeAttribute("id",id,null); // $NON-NLS-1$
w.writeAttribute("value",value,null); // $NON-NLS-1$
// Specify title attribute for accessibility
String title = "Select the current row"; // $NLS-DataViewRenderer_RowCheckboxTitle-1$
w.writeAttribute("title",title,null); // $NON-NLS-1$
w.writeAttribute("aria-label", title, null);// $NON-NLS-1$
w.writeAttribute("role", "checkbox", null);// $NON-NLS-1$ // $NON-NLS-2$
writeCheckboxAccessibilityAttributes(context, w, id);
w.startElement("label", null); // $NON-NLS-1$
w.writeAttribute("for", id, null); // $NON-NLS-1$
w.writeAttribute("style", "display:none", null); // $NON-NLS-1$ $NON-NLS-2$
w.writeText(title, null);
w.endElement("label"); // $NON-NLS-1$
} else {
// Just nothing...
}
w.endElement("td"); // $NON-NLS-1$
}
protected void writeIconColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
w.startElement("td",c); // $NON-NLS-1$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
if(viewDef.iconColumn!=null) {
String colStyle = viewDef.iconColumn.getStyle();
if(StringUtil.isNotEmpty(colStyle)) {
w.writeAttribute("style",colStyle,null); // $NON-NLS-1$
}
String colClazz = viewDef.iconColumn.getStyleClass();
if(!viewDef.hasCheckBoxColumn) {
colClazz = ExtLibUtil.concatStyleClasses(colClazz,(String)getProperty(PROP_TABLEFIRSTCELLCLASS));
}
if(StringUtil.isNotEmpty(colClazz)) {
w.writeAttribute("class",colClazz,null); // $NON-NLS-1$
}
}
if(viewDef.iconFacet!=null) {
FacesUtil.renderComponent(context, viewDef.iconFacet);
} else {
IconEntry entry = findIcon(context, w, c, viewDef);
if(entry!=null) {
String src = entry.getUrl();
if(StringUtil.isNotEmpty(src)) {
w.startElement("img",c); // $NON-NLS-1$
if(StringUtil.isNotEmpty(src)) {
w.writeAttribute("src",HtmlRendererUtil.getImageURL(context,src),null); // $NON-NLS-1$
}
String alt = entry.getAlt();
String title = entry.getTitle();
if(ExtLibRenderUtil.isAltPresent(alt)){
w.writeAttribute("alt", alt, null); //$NON-NLS-1$
if(StringUtil.isEmpty(title)){
w.writeAttribute("title", alt, null); //$NON-NLS-1$
}
}
if(StringUtil.isNotEmpty(title)){
w.writeAttribute("title", title, null); //$NON-NLS-1$
}
String iconStyle = entry.getStyle();
if(StringUtil.isNotEmpty(iconStyle)) {
w.writeAttribute("style",iconStyle,null); // $NON-NLS-1$
}
String iconClass = ExtLibUtil.concatStyleClasses(entry.getStyleClass(),(String)getProperty(PROP_TABLEFIRSTCELLCLASS));
if(StringUtil.isNotEmpty(iconClass)) {
w.writeAttribute("class",iconClass,null); // $NON-NLS-1$
}
w.endElement("img"); // $NON-NLS-1$
}
}
}
w.endElement("td"); // $NON-NLS-1$
}
protected IconEntry findIcon(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
List<IconEntry> icons = viewDef.iconColumn.getIcons();
if(icons!=null && !icons.isEmpty()) {
// Get the value
Object value = getColumnValue(context, c, viewDef, viewDef.iconColumn);
for(IconEntry icon: icons) {
// Check if the value is equal
if(StringUtil.equals(value, icon.getSelectedValue())) {
return icon;
}
// Else, check if it is selected
if(icon.isSelected()) {
return icon;
}
}
}
return null;
}
protected void writeDataColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
// Prevent the column to be diisplayed when no data exists
if(!viewDef.hasSummary && !viewDef.hasDetail) {
return;
}
w.startElement("td",c); // $NON-NLS-1$
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
int width = 100/viewDef.multiColumnCount;
w.writeAttribute("style","width: "+width+"%",null); // $NON-NLS-1$ $NON-NLS-2$
if(!viewDef.hasCheckBoxColumn && !viewDef.hasIconColumn) {
String clazz = (String)getProperty(PROP_TABLEFIRSTCELLCLASS);
if(StringUtil.isNotEmpty(clazz)) {
w.writeAttribute("class",clazz,null); // $NON-NLS-1$
}
}
// Enclosing divs
w.startElement("div",c); // $NON-NLS-1$
if(true) {
int level = getColumnIndentLevel(context, c, viewDef);
int catLevel = Math.max(0, viewDef.categoryCount-1);
String style = getIndentStyle(context, c, viewDef, level+catLevel);
if(StringUtil.isNotEmpty(style)) {
w.writeAttribute("style",style,null); // $NON-NLS-1$
}
}
// Write the summary data
writeSummary(context, w, c, viewDef);
// Write the details
writeDetail(context, w, c, viewDef);
w.endElement("div"); // $NON-NLS-1$
w.endElement("td"); // $NON-NLS-1$
}
protected String getIndentStyle(FacesContext context, AbstractDataView c, ViewDefinition viewDef, int level) throws IOException {
if(level>0) {
Integer indentPx = (Integer)getProperty(PROP_TABLEROWINDENTPX);
if(indentPx>0) {
String paddingDir = DirLangUtil.isRTL(c) ? "padding-right:" : "padding-left:"; //$NON-NLS-1$ //$NON-NLS-2$
String style = paddingDir + (level * indentPx) + "px !important"; // $NON-NLS-1$ $NON-NLS-2$
return style;
}
}
return null;
}
protected String getIndentStyle(FacesContext context, AbstractDataView c, ViewDefinition viewDef, int level, int sublevel) throws IOException {
// Ref SPR# PHAN9E3FUG Subcategories created from backslashes in Categories need to be handled better in the Data View
FacesContextEx ctx = (context instanceof FacesContextEx) ? (FacesContextEx)context : null;
if (ctx != null) {
boolean doAutoIndent = true;
String propAutoIndent = ctx.getProperty("xsp.domino.view.embeddedsubcategories.autoindent"); // $NON-NLS-1$
if (!StringUtil.isEmpty(propAutoIndent)) {
doAutoIndent = Boolean.parseBoolean(propAutoIndent);
}
if (doAutoIndent) {
if(level>0 || sublevel>0) {
Integer indentPxSub = (Integer)getProperty(PROP_TABLEROWINDENTPX);
if(indentPxSub>0) {
// Category column width needs to be wider than the subcategory width
// These properties (PROP_TABLEROWINDENTPX etc) do not appear to be configurable
// WITHOUT subclassing Java classes? Should be handled by themes!
// Quick remedy is just to increase the width by an arbitrary number of pixels
Integer indentPxCol = indentPxSub + 10;
int padValue = (indentPxCol * level) + (indentPxSub * sublevel);
String paddingDir = DirLangUtil.isRTL(c) ? "padding-right:" : "padding-left:"; //$NON-NLS-1$ //$NON-NLS-2$
String style = paddingDir + (padValue) + "px !important"; // $NON-NLS-1$ $NON-NLS-2$
return style;
}
}
} else {
return getIndentStyle(context, c, viewDef, level);
}
}
return null;
}
protected int getIndentLevel(ViewDefinition viewDef) throws IOException {
// assumes that the caller
int level = 0;
TabularDataModel tdm;
DataModel dm = viewDef.dataModel;
if(dm instanceof TabularDataModel) {
tdm = (TabularDataModel)dm;
level = tdm.getColumnIndentLevel();
}
return level;
}
protected void writeShowHideDetailCell(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
if(viewDef.collapsibleDetails) {
w.startElement("td",c); // $NON-NLS-1$
String clazz = (String)getProperty(PROP_TABLELASTCELLCLASS);
if(StringUtil.isNotEmpty(clazz)) {
w.writeAttribute("class",clazz,null); // $NON-NLS-1$
}
if(viewDef.hasSummary && viewDef.hasDetail && !viewDef.rowDisableHideRow) {
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
writeShowHideDetailContent(context, w, c, viewDef);
}
w.endElement("td"); // $NON-NLS-1$
}
}
protected void writeExtraColumns(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException {
List<ExtraColumn> extraColumns = viewDef.extraColumns;
int count = extraColumns.size();
for(int i=0; i<count; i++) {
ExtraColumn col = extraColumns.get(i);
writeExtraColumn(context, w, c, viewDef, col, i);
}
}
protected void writeExtraColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef, ExtraColumn col, int colIdx) throws IOException {
w.startElement("td",c); // $NON-NLS-1$
String value = formatColumnValue(context, c, viewDef, col);
if(!StringUtil.isEmpty(value)) {
w.writeAttribute("role", "gridcell", null); // $NON-NLS-1$ $NON-NLS-2$
}
UIComponent facet = getExtraFacet(c,colIdx);
if(facet!=null) {
// TODO should use the column complex-type's style, and styleClass
// even when using the facet for the column contents.
FacesUtil.renderComponent(context, facet);
} else {
String style = col.getStyle();
if(StringUtil.isNotEmpty(style)) {
w.writeAttribute("style", style, null); // $NON-NLS-1$
}
String clazz = col.getStyleClass();
if(StringUtil.isEmpty(clazz)) {
clazz = (String)getProperty(PROP_TABLEROWEXTRA);
}
if(StringUtil.isNotEmpty(clazz)) {
w.writeAttribute("class", clazz, null); // $NON-NLS-1$
}
// Write a link if there is an href
String href = getColumnUrl(context, c, viewDef, col);
if(StringUtil.isNotEmpty(href)) {
w.startElement("a",c);
RenderUtil.writeLinkAttribute(context,w,href);
// Write the title if there is any
String title = getTitle(context, c, viewDef, col);
if(StringUtil.isNotEmpty(title)) {
w.writeAttribute("title", title,null); // $NON-NLS-1$
}
}else{
w.startElement("div",c); // $NON-NLS-1$
}
writeColumnValue(context, w, c, viewDef, col);
if(StringUtil.isNotEmpty(href)) {
w.endElement("a");
}else{
w.endElement("div"); // $NON-NLS-1$
}
}
w.endElement("td"); // $NON-NLS-1$
}
/* (non-Javadoc)
* @see com.ibm.xsp.extlib.renderkit.html_extended.data.DataSourceIteratorRenderer#writeColumnEmptyValue(javax.faces.context.FacesContext, javax.faces.context.ResponseWriter, com.ibm.xsp.extlib.component.data.UIDataSourceIterator, com.ibm.xsp.extlib.renderkit.html_extended.data.AbstractDataViewRenderer.ViewDefinition, com.ibm.xsp.extlib.component.data.ValueColumn)
*/
@Override
protected void writeColumnEmptyValue(FacesContext context,
ResponseWriter w, UIDataSourceIterator c, ViewDefinition viewDef,
ValueColumn vc) throws IOException {
if( vc instanceof CategoryColumn ){
// For SPR#DEGN8NUCN3, empty categorized columns should say "Not Categorized",
// same as in the DataTable and ViewPanel controls.
// "Not Categorized"
// reusing the translated string from the xpages runtime
String emptyCategoryColumnValue = com.ibm.xsp.extsn.ResourceHandler
.getString("DataTableRendererEx.NotCategorized"); //$NON-NLS-1$
w.writeText(emptyCategoryColumnValue, null);
}else{
// For SPR#TWET98EATX, commenting out the addition of a space character
// as in certain circumstances it creates a link out of the space.
//Adding hidden style to the anchor to pass RPT
//
//super.writeColumnEmptyValue(context, w, c, viewDef, vc);
w.writeAttribute("style","display:none;",null); // $NON-NLS-1$ $NON-NLS-2
}
}
protected void writeCheckboxAccessibilityAttributes(FacesContext context, ResponseWriter w, String checkBoxId) throws IOException {
//Empty here to be over-ridden in subclasses
}
protected void writeHeaderCheckboxAccessibilityAttributes(FacesContext context, ResponseWriter w, String viewId, String headerCheckboxId) throws IOException {
//Empty here to be over-ridden in subclasses
}
}