/* * � 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.mobile; import java.io.IOException; import javax.faces.component.NamingContainer; import javax.faces.component.UIComponent; import javax.faces.context.ExternalContext; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import lotus.domino.ViewEntry; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.component.UIDataIterator; import com.ibm.xsp.context.FacesContextEx; import com.ibm.xsp.extlib.component.data.*; import com.ibm.xsp.extlib.component.image.IconEntry; import com.ibm.xsp.extlib.renderkit.html_extended.data.DataViewRenderer; import com.ibm.xsp.extlib.renderkit.html_extended.data.ViewRowDataOverride; import com.ibm.xsp.extlib.resources.ExtLibResources; import com.ibm.xsp.extlib.util.ExtLibUtil; import com.ibm.xsp.model.ViewRowData; import com.ibm.xsp.renderkit.FacesRenderer; import com.ibm.xsp.renderkit.html_basic.HtmlRendererUtil; import com.ibm.xsp.renderkit.html_extended.RenderUtil; import com.ibm.xsp.util.FacesUtil; /** * The MobileViewRenderer is a DataViewRenderer specifically tailored for * displaying a DataView control on mobile devices. * * @author jpierma * */ public class MobileViewRenderer extends DataViewRenderer { protected static final String ID_DETAIL = "_detail"; // $NON-NLS-1$ public static final int PROP_CONTAINERTAG = 100; public static final int PROP_CONTAINERDOJOTYPE = 101; public static final int PROP_CONTAINERSTYLECLASS = 102; public static final int PROP_LISTTAG = 103; public static final int PROP_LISTDOJOTYPE = 104; public static final int PROP_LISTSTYLECLASS = 105; public static final int PROP_ITEMDIVSTYLE = 110; public static final int PROP_ITEMDIVSTYLECLASS = 111; public static final int PROP_ITEMTAG = 112; public static final int PROP_ITEMDOJOTYPE = 113; public static final int PROP_ITEMSTYLECLASS = 114; public static final int PROP_ITEMTRANSITION = 115; public static final int PROP_SUBHEADTAG = 120; public static final int PROP_SUBHEADDOJOTYPE = 121; public static final int PROP_SUBHEADDIVSTYLE = 122; public static final int PROP_SUBHEADSTYLECLASS = 123; public static final int PROP_SUBHEADSTYLECLASS_STD = 124; public static final int PROP_SUMMARYCOLSTYLE = 130; public static final int PROP_SUMMARYCOLSTYLECLASS = 131; public static final int PROP_CATEGORYCOLSTYLE = 132; public static final int PROP_CATEGORYCOLSTYLECLASS = 133; public static final int PROP_ICONCOLSTYLE = 134; public static final int PROP_ICONCOLSTYLECLASS = 135; public static final int PROP_EXTRACOLSTYLE = 136; public static final int PROP_EXTRACOLSTYLECLASS = 137; public static final int PROP_SUMMARYCOLTEXTSTYLECLASS = 138; public static final int PROP_CATEGORYROWSTYLECLASS = 139; public static final int PROP_DATAROWSTYLECLASS = 140; // public static final int PROP_CATEGORYROWSCRIPT = 141; public static final int PROP_DATAROWICONSTYLECLASS = 142; public static final int PROP_WRAPPERTAG = 160; public static final int PROP_WRAPPERDOJOTYPE = 161; public static final int PROP_WRAPPERSTYLECLASS = 162; private static final int PROP_WRAPPERSTYLECLASS_MULTIPLE = 164; public static final String HIDDEN = "hidden"; // $NON-NLS-1$ public static final String SUBMIT_SCROLL = "$$xspscroll"; //$NON-NLS-1$ // getProperty is used as a property dispatcher. The intended use of // getProperty // is to abstract away the direct use of a property in a method call. In // doing so, // we only have to change the value of a property in this method to modify // it // everywhere in the class. This is especially helpful if a new renderer // needs to // be created with device specific properties. Just override the ones that // need // new values and you're done. @Override protected Object getProperty(int prop) { switch (prop) { case PROP_CONTAINERTAG: return "ul"; // $NON-NLS-1$ case PROP_CONTAINERDOJOTYPE: return "dojox.mobile.EdgeToEdgeList"; // $NON-NLS-1$ case PROP_CONTAINERSTYLECLASS: return "mblDataView"; // $NON-NLS-1$ // case PROP_HEADERDOJOTYPE: return "dojox.mobile.ListItem"; // // $NON-NLS-1$ // case PROP_HEADERCLASS: return "mblVariableHeight"; // $NON-NLS-1$ case PROP_HEADERSTYLE: return "height: 2em"; // $NON-NLS-1$ case PROP_HEADERCLASS: return "mblVariableHeight mblListItem"; // $NON-NLS-1$ // case PROP_FOOTERDOJOTYPE: return "dojox.mobile.ListItem"; // // $NON-NLS-1$ // case PROP_FOOTERCLASS: return "mblVariableHeight"; // $NON-NLS-1$ case PROP_FOOTERCLASS: return "mblVariableHeight mblListItem mblFooter"; // $NON-NLS-1$ case PROP_FOOTER_PAGER_AREA_TAG: return "li"; // $NON-NLS-1$ case PROP_LISTTAG: return "div"; // $NON-NLS-1$ case PROP_ITEMDIVSTYLECLASS: return "mblListItemWrapper"; // $NON-NLS-1$ case PROP_CATEGORYROWSTYLECLASS: return "mblCategoryRow"; // $NON-NLS-1$ case PROP_DATAROWSTYLECLASS: return "mblDataRow"; // $NON-NLS-1$ case PROP_DATAROWICONSTYLECLASS: return "mblDataRowIcon"; // $NON-NLS-1$ case PROP_ITEMTAG: return "li"; // $NON-NLS-1$ case PROP_ITEMDOJOTYPE: return "extlib.dijit.mobile.ListItem"; // $NON-NLS-1$ case PROP_ITEMSTYLECLASS: return "mblVariableHeight"; // $NON-NLS-1$ case PROP_ITEMTRANSITION: return "slide"; // $NON-NLS-1$ case PROP_SUBHEADTAG: return "li"; // $NON-NLS-1$ case PROP_SUBHEADDOJOTYPE: return ""; // $NON-NLS-1$ case PROP_SUBHEADDIVSTYLE: return ""; // $NON-NLS-1$ case PROP_SUBHEADSTYLECLASS: return "mblDataViewCategoryRow"; // $NON-NLS-1$ case PROP_SUBHEADSTYLECLASS_STD: return "mblEdgeToEdgeCategory"; // $NON-NLS-1$ case PROP_SUMMARYCOLSTYLE: return ""; // $NON-NLS-1$ case PROP_SUMMARYCOLSTYLECLASS: return "mblDataViewTextTitle"; // $NON-NLS-1$ case PROP_SUMMARYCOLTEXTSTYLECLASS: return "mblDataViewTextContent"; // $NON-NLS-1$ // case PROP_CATEGORYROWSCRIPT: return "XSP.accordionifyCategory"; case PROP_FOOTERSTYLE: return ""; // $NON-NLS-1$ case PROP_FOOTERLEFTSTYLE: return "width:100%"; // $NON-NLS-1$ case PROP_FOOTERRIGHTSTYLE: return "width:100%"; // $NON-NLS-1$ case PROP_FOOTERMIDDLESTYLE: return "width:100%"; // $NON-NLS-1$ case PROP_FOOTERLEFTCLASS: return "mblFooterText mblLeft"; // $NON-NLS-1$ case PROP_FOOTERRIGHTCLASS: return "mblFooterText mblRight"; // $NON-NLS-1$ case PROP_FOOTERMIDDLECLASS: return "mblFooterText mblCenter"; // $NON-NLS-1$ case PROP_WRAPPERTAG: return "div"; // $NON-NLS-1$ case PROP_WRAPPERDOJOTYPE: return "extlib.dijit.mobile.ScrollablePane"; // $NON-NLS-1$ case PROP_WRAPPERSTYLECLASS: return "mblScrollablePane"; // $NON-NLS-1$ case PROP_WRAPPERSTYLECLASS_MULTIPLE: return "mblScrollablePaneMultiple"; // $NON-NLS-1$ } return super.getProperty(prop); } // ================================================================ // Main data view container // ================================================================ @Override protected void writeDataView(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { String style = c.getStyle(); String viewId = c.getClientId(context); String spId = ""; if (viewDef.isInfiniteScroll) { //Add the dojo module ExtLibResources.addEncodeResource(context, ExtLibResources.extlibScrollablePane); String pane = (String) getProperty(PROP_WRAPPERTAG); startElement(w, pane, null, PROP_WRAPPERSTYLECLASS, PROP_WRAPPERDOJOTYPE); w.writeAttribute("id", viewId, null);//$NON-NLS-1$ spId = viewId; w.writeAttribute("dataRows", viewDef.rows, null);//$NON-NLS-1$ //changing the id because the partial refresh requires the outermost id to be sent in the request. viewId+="_is"; //$NON-NLS-1$ w.writeAttribute("dataViewId", viewId , null);//$NON-NLS-1$ w.writeAttribute("roundCornerMask", "true", null);//$NON-NLS-1$ //$NON-NLS-2$ w.writeAttribute("radius","5",null);//$NON-NLS-1$ // adding the scrollPosition as a div attribute to pass it at the ScrollablePane.js String scroll = (String)context.getExternalContext().getRequestParameterMap().get(SUBMIT_SCROLL + "_" + spId); //$NON-NLS-1$ if(scroll != null) { w.writeAttribute("scrollToPos",scroll,null);//$NON-NLS-1$ } ExternalContext ctx = context.getExternalContext(); String servletPath = ctx.getRequestServletPath(); if(servletPath != null) { w.writeAttribute("servletPath",servletPath,null);//$NON-NLS-1$ } if(style != null) { w.writeAttribute("style",style,null);//$NON-NLS-1$ int hIndex = style.indexOf("height:"); //$NON-NLS-1$ if(hIndex > -1 ) { String hVal = style.substring(hIndex + "height:".length()); //$NON-NLS-1$ int commaIndex = hVal.indexOf(";"); //$NON-NLS-1$ if(commaIndex > 0) { hVal = hVal.substring(0,commaIndex); } w.writeAttribute("height",hVal, null);//$NON-NLS-1$ } } } String tag = (String) getProperty(PROP_CONTAINERTAG); startElement(w, tag, null, PROP_CONTAINERSTYLECLASS, PROP_CONTAINERDOJOTYPE); w.writeAttribute("id", viewId, null);//$NON-NLS-1$ newLine(w); // Write the header boolean hasHeader = (Boolean) getProperty(PROP_HASHEADERFACET); if (hasHeader) { writeHeader(context, w, c, viewDef); } // And write the content UIComponent noRowsFacet = c.getFacet(AbstractDataView.FACET_NOROWS); if (!hasMoreRowsToRender(c) && noRowsFacet != null) { writeNoRowsContent(context, w, c, viewDef); } else { writeContent(context, w, c, viewDef); } // Write the footer boolean hasFooter = (Boolean) getProperty(PROP_HASFOOTERFACET); if (hasFooter) { writeFooter(context, w, c, viewDef); } w.endElement(tag); if (viewDef.isInfiniteScroll) { w.startElement(FacesRenderer.INPUT, null); w.writeAttribute(FacesRenderer.TYPE, HIDDEN, null); w.writeAttribute(FacesRenderer.NAME, SUBMIT_SCROLL + "_" + spId, null); //$NON-NLS-1$ w.writeAttribute(FacesRenderer.ID, spId + "_hif", null); //$NON-NLS-1$ w.endElement(FacesRenderer.INPUT); String pane = (String) getProperty(PROP_WRAPPERTAG); w.endElement(pane); } newLine(w); } @Override protected void writeContent(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { String tag = (String) getProperty(PROP_LISTTAG); startElement(w, tag, null, PROP_LISTSTYLECLASS, PROP_LISTDOJOTYPE); String aid = c.getAjaxContainerClientId(context); w.writeAttribute("id", aid, null); //$NON-NLS-1$ newLine(w); // And the rows int first = c.getFirst(); int count = c.getRows(); writeRows(context, w, c, viewDef, first, count); w.endElement(tag); newLine(w); } @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); } @Override protected void writeRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { if (isCategoryRow(context, c, viewDef)) { if (viewDef.hasCategoryRow) { writeCategoryRow(context, w, c, viewDef); } } else if (isTotalRow(context, c, viewDef)) { writeTotalRow(context, w, c, viewDef); } else { writeStandardRow(context, w, c, viewDef); } } protected void writeRowStart(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { w.startElement("div", null); // $NON-NLS-1$ boolean isCategoryRow = isCategoryRow(context, c, viewDef); String tableId = c.getClientId(context); String id = tableId + NamingContainer.SEPARATOR_CHAR + UIDataView.ROW_ID; String divStyleClass = (String) getProperty(PROP_ITEMDIVSTYLECLASS); if (isCategoryRow) { divStyleClass = ExtLibUtil.concatStyleClasses(divStyleClass, (String) getProperty(PROP_CATEGORYROWSTYLECLASS)); boolean expanded = isRowExpanded(context, c, viewDef); id += (expanded ? SHRINK_DELIMITER : EXPAND_DELIMITER) + viewDef.rowPosition; } else { divStyleClass = ExtLibUtil.concatStyleClasses(divStyleClass, (String) getProperty(PROP_DATAROWSTYLECLASS)); if (viewDef.hasIconColumn) { divStyleClass = ExtLibUtil.concatStyleClasses(divStyleClass, (String) getProperty(PROP_DATAROWICONSTYLECLASS)); } } w.writeAttribute("id", id, null); // $NON-NLS-1$ if (StringUtil.isNotEmpty(divStyleClass)) { w.writeAttribute("class", divStyleClass, null); // $NON-NLS-1$ } String divStyle = (String) getProperty(PROP_ITEMDIVSTYLE); if (StringUtil.isNotEmpty(divStyle)) { w.writeAttribute("style", divStyle, null); // $NON-NLS-1$ } if (isCategoryRow) { // add JavaScript to handle custom show/hide functionality setupSubmitOnClick(context, c, id, id, null); String tag = (String) getProperty(PROP_SUBHEADTAG); w.startElement(tag, null); String themeName = ((FacesContextEx) context).getStyleKit() .getName(); String styleClass; if (!themeName .equalsIgnoreCase(ApplicationRenderer.IPHONE_THEME_NAME) && !themeName .equalsIgnoreCase(ApplicationRenderer.ANDROID_THEME_NAME) && !themeName .equalsIgnoreCase(ApplicationRenderer.BLACKBERRY_THEME_NAME)) { styleClass = (String) getProperty(PROP_SUBHEADSTYLECLASS_STD); } else { styleClass = (String) getProperty(PROP_SUBHEADSTYLECLASS); } if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } } else { // Dojo list item String tag = (String) getProperty(PROP_ITEMTAG); w.startElement(tag, null); String djType = (String) getProperty(PROP_ITEMDOJOTYPE); if (StringUtil.isNotEmpty(djType)) { w.writeAttribute("dojoType", djType, null); // $NON-NLS-1$ } String styleClass = (String) getProperty(PROP_ITEMSTYLECLASS); if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } String transition = (String) getProperty(PROP_ITEMTRANSITION); if (StringUtil.isNotEmpty(transition)) { w.writeAttribute("transition", transition, null); // $NON-NLS-1$ } if (viewDef.hasIconColumn) { String icon = getIconColumnUrl(context, w, c, viewDef); if (StringUtil.isNotEmpty(icon)) { // TODO not writing out icon column Alt text w.writeAttribute("icon", icon, null);//$NON-NLS-1$ } } String href = getRowUrl(context, c, viewDef); if (StringUtil.isNotEmpty(href) && !href.startsWith("#")) { // $NON-NLS-1$ href = "#" + href; // $NON-NLS-1$ } if (StringUtil.isNotEmpty(href)) { w.writeAttribute("moveTo", href, null); // $NON-NLS-1$ } } newLine(w); } protected void writeRowListAttributes(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { String djType = (String) getProperty(PROP_ITEMDOJOTYPE); if (StringUtil.isNotEmpty(djType)) { w.writeAttribute("dojoType", djType, null); // $NON-NLS-1$ } } protected String getRowUrl(FacesContext context, AbstractDataView c, ViewDefinition viewDef) { // Try a fixed href on the summary column String href = getColumnUrl(context, c, viewDef, viewDef.summaryColumn); if (StringUtil.isNotEmpty(href)) { return href; } // Try a URL for the row String pageUrl = getPageUrl(context, c, viewDef); if (StringUtil.isNotEmpty(pageUrl)) { return pageUrl; } return null; } @Override protected String getColumnUrl(FacesContext context, AbstractDataView c, ViewDefinition viewDef, ValueColumn col) { if (col != null) { String href = col.getHref(); if (StringUtil.isNotEmpty(href)) { return href; } } return null; } protected String getPageUrl(FacesContext context, AbstractDataView c, ViewDefinition viewDef) { String pageName = c.getPageName(); if (StringUtil.isNotEmpty(pageName)) { Object row = viewDef.dataModel.getRowData(); if (row instanceof ViewRowData) { ViewRowData viewRowData = (ViewRowData) row; boolean readOnly = c.isOpenDocAsReadonly(); ViewRowDataOverride helper = new ViewRowDataOverride( (ViewEntry) viewRowData); String url = helper.getOpenPageURL(pageName, readOnly); return url.replace("?", "&"); } } return null; } protected void writeRowEnd(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { if (isCategoryRow(context, c, viewDef)) { String tag = (String) getProperty(PROP_SUBHEADTAG); w.endElement(tag); } else { String tag = (String) getProperty(PROP_ITEMTAG); w.endElement(tag); } w.endElement("div"); // $NON-NLS-1$ newLine(w); } @Override protected void writeStandardRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { writeRowStart(context, w, c, viewDef); // Write the data column writeDataColumn(context, w, c, viewDef); if (viewDef.hasExtraColumns) { writeExtraColumns(context, w, c, viewDef); } writeRowEnd(context, w, c, viewDef); } @Override protected void writeCategoryRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { writeRowStart(context, w, c, viewDef); // Write the category data // writeDataColumn(context, w, c, viewDef); writeCategory(context, w, c, viewDef); writeRowEnd(context, w, c, viewDef); } @Override protected void writeTotalRow(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { writeRowStart(context, w, c, viewDef); // Write the total data // writeDataColumn(context, w, c, viewDef); writeRowEnd(context, w, c, viewDef); } @Override protected void writeDataColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { // Write the summary data writeSummary(context, w, c, viewDef); // Write the details writeDetail(context, w, c, viewDef); } // Writes out main content of a category row protected void writeCategory(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { int categoryListIndex = findCategoryListIndex(context, c, viewDef, viewDef.categoryColumns); CategoryColumn categoryColumn = (-1 == categoryListIndex) ? null : viewDef.categoryColumns.get(categoryListIndex); if (null == categoryColumn) { return; } UIComponent categoryFacet = getCategoryRowFacet(c, categoryListIndex); // Add the enclosing tag if (categoryFacet == null) { w.startElement("div", c); // $NON-NLS-1$ String styleClass = ExtLibUtil.concatStyleClasses( (String) getProperty(PROP_EXTRACOLSTYLECLASS), categoryColumn.getStyleClass()); if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } String style = ExtLibUtil.concatStyles( (String) getProperty(PROP_EXTRACOLSTYLE), categoryColumn.getStyle()); if (StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } writeColumnValue(context, w, c, viewDef, categoryColumn); w.endElement("div"); // $NON-NLS-1$ } else { // Write the content column FacesUtil.renderChildren(context, categoryFacet); } } @Override protected void writeSummary(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { if (viewDef.summaryColumn == null && viewDef.summaryFacet == null) { return; } // Add the enclosing tag if (viewDef.summaryFacet == null) { w.startElement("div", c); // $NON-NLS-1$ String styleClass = ExtLibUtil.concatStyleClasses( (String) getProperty(PROP_SUMMARYCOLSTYLECLASS), viewDef.summaryColumn.getStyleClass()); if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } String style = ExtLibUtil.concatStyles( (String) getProperty(PROP_SUMMARYCOLSTYLE), viewDef.summaryColumn.getStyle()); if (StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } writeColumnValue(context, w, c, viewDef, viewDef.summaryColumn); w.endElement("div"); // $NON-NLS-1$ } else { // Write the content column FacesUtil.renderChildren(context, viewDef.summaryFacet); } } @Override protected void writeDetail(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { UIComponent detail = viewDef.detailFacet; if (detail != null) { String id = c.getClientId(context) + ID_DETAIL; w.startElement("div", c); // $NON-NLS-1$ w.writeAttribute("id", id, null); // $NON-NLS-1$ String styleClass = (String) getProperty(PROP_SUMMARYCOLTEXTSTYLECLASS); if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } String style = viewDef.summaryColumn != null ? viewDef.summaryColumn .getStyle() : null; if (StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } FacesUtil.renderComponent(context, detail); w.endElement("div"); // $NON-NLS-1$ } } @Override protected void writeExtraColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef, ExtraColumn col, int colIdx) throws IOException { w.startElement("div", c); // $NON-NLS-1$ UIComponent facet = getExtraFacet(c, colIdx); if (facet != null) { FacesUtil.renderComponent(context, facet); } else { String styleClass = ExtLibUtil.concatStyleClasses( (String) getProperty(PROP_EXTRACOLSTYLECLASS), col.getStyleClass()); if (StringUtil.isNotEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } String style = ExtLibUtil.concatStyles( (String) getProperty(PROP_EXTRACOLSTYLE), col.getStyle()); if (StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, 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); }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("div"); // $NON-NLS-1$ } @Override protected void writeIconColumn(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { if (viewDef.iconFacet != null) { w.startElement("div", c); // $NON-NLS-1$ 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$ } } FacesUtil.renderComponent(context, viewDef.iconFacet); w.endElement("div"); // $NON-NLS-1$ } } protected String getIconColumnUrl(FacesContext context, ResponseWriter w, AbstractDataView c, ViewDefinition viewDef) throws IOException { if (viewDef.iconFacet != null) // we are using an icon facet, this is // handled later in writeStandardRow return null; IconEntry entry = findIcon(context, w, c, viewDef); if (entry != null) { String src = entry.getUrl(); if (StringUtil.isNotEmpty(src)) { return HtmlRendererUtil.getImageURL(context, src); } } return null; } @Override public void encodeRows(FacesContext context, UIDataIterator iterator, int first, int rows) throws IOException { ResponseWriter w = context.getResponseWriter(); AbstractDataView c = (AbstractDataView) iterator; ViewDefinition viewDef = createViewDefinition(context); initViewDefinition(context, c, viewDef); writeRows(context, w, c, viewDef, first, rows); } }