/* * � Copyright IBM Corp. 2010, 2013, 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.Iterator; import java.util.List; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; import javax.faces.context.ResponseWriter; import com.ibm.commons.util.StringUtil; import com.ibm.xsp.extlib.component.data.FormLayout; import com.ibm.xsp.extlib.component.data.UIFormLayoutColumn; import com.ibm.xsp.extlib.component.data.UIFormLayoutRow; import com.ibm.xsp.extlib.component.data.UIFormTable; import com.ibm.xsp.extlib.component.dialog.UIDialog; import com.ibm.xsp.extlib.util.ExtLibUtil; import com.ibm.xsp.renderkit.ReadOnlyAdapterRenderer; import com.ibm.xsp.util.DirLangUtil; import com.ibm.xsp.util.FacesUtil; import com.ibm.xsp.util.JSUtil; import com.ibm.xsp.util.TypedUtil; /** * Table layout for a form editing data. */ public class FormTableRenderer extends FormLayoutRenderer { // Header protected static final int PROP_TABLESTYLE = 200; protected static final int PROP_TABLESTYLECLASS = 201; protected static final int PROP_TABLEROLE = 202; @Override protected Object getProperty(int prop) { switch(prop) { // note, in 9.0_N / 9.0.1, this changed from presentation to form case PROP_TABLEROLE: return "form"; // $NON-NLS-1$ case PROP_ERRORROWSTYLE: return "padding: 0 25px;"; //$NON-NLS-1$ case PROP_ERRORROWSTYLENESTED: return "padding-left:15px;"; //$NON-NLS-1$ case PROP_ERRORROWSTYLENESTED_RTL: return "padding-right:15px;"; //$NON-NLS-1$ //Commonly used Strings case PROP_ERRORSUMMARYMAINTEXT: return "Please check the following:"; // $NLS-FormTableRenderer.Pleasecheckthefollowing-1$ case PROP_ERRORIMGALT: return "Error"; // $NLS-FormTableRenderer.Error-1$ case PROP_ERRORMSGALTTEXT: return "Error:"; // $NLS-FormTableRenderer.Error.1-1$ case PROP_FATALMSGALTTEXT: return "Fatal:"; // $NLS-FormTableRenderer.Fatal-1$ case PROP_WARNIMGALT: return "Warning"; // $NLS-FormTableRenderer.Warning-1$ case PROP_WARNMSGALTTEXT: return "Warning:"; // $NLS-FormTableRenderer.Warning.1-1$ case PROP_INFOIMGALT: return "Information"; // $NLS-FormTableRenderer.Information-1$ case PROP_INFOMSGALTTEXT: return "Information:"; // $NLS-FormTableRenderer.Information.1-1$ case PROP_HELPIMGALT: return "Help"; // $NLS-FormTableRenderer.Help-1$ case PROP_HELPMSGALTTEXT: return "Help"; // $NLS-FormTableRenderer.Help-1$ } return super.getProperty(prop); } protected static class ComputedRowData{ protected FormLayout formControl; protected ComputedFormData formData; protected UIFormLayoutRow rowControl; protected String labelPosition; public ComputedRowData(FormLayout formControl,ComputedFormData formData, UIFormLayoutRow rowControl) { super(); this.formControl = formControl; this.formData = formData; this.rowControl = rowControl; } public String getLabelPosition() { if( null == labelPosition ){ boolean inherit = true; labelPosition = rowControl.getLabelPosition(); if( StringUtil.isNotEmpty(labelPosition) ){ inherit = false; if( "inherit".equals(labelPosition) ){ // $NON-NLS-1$ inherit = true; } } if( inherit ){ // check the setting on the form labelPosition = formData.getLabelPosition(); } } return labelPosition; } public boolean isLabelAbove(){ String pos = getLabelPosition(); if( "above".equals(pos) ){ // $NON-NLS-1$ return true; } return false; } public boolean hasLabel(){ String pos = getLabelPosition(); if( "none".equals(pos) ){ // $NON-NLS-1$ return false; } return true; } public boolean hasLabelControl(){ String pos = getLabelPosition(); if( "none".equals(pos) ){ // $NON-NLS-1$ return false; } String labelValue = rowControl.getLabel(); UIComponent labelFacet = rowControl.getFacet("label"); // $NON-NLS-1$ if(StringUtil.isEmpty(labelValue) && null == labelFacet){ return false; } return true; } public boolean hasHelpControl(){ if(!formControl.isFieldHelp()){ return false; } String helpId = rowControl.getHelpId(); UIComponent helpFacet = rowControl.getFacet("help"); // $NON-NLS-1$ if(StringUtil.isEmpty(helpId) && null == helpFacet){ return false; } return true; } public boolean isFormNested(){ if(this.formData != null) { return this.formData.isNested(); } return false; } } protected ComputedRowData createRowData(FacesContext context, FormLayout formControl, ComputedFormData formData, UIFormLayoutRow rowControl){ return new ComputedRowData(formControl, formData, rowControl); } protected static class ComputedFormData{ protected UIFormTable formControl; protected Boolean disableRowError; protected Boolean disableRequiredMarks; protected String labelPosition; protected String labelWidth; protected Boolean nested; protected int colCount; public ComputedFormData(UIFormTable formControl) { this.formControl = formControl; this.labelWidth = formControl.getLabelWidth(); } public String getLabelWidth() { return labelWidth; } public boolean isDisableRowError(){ if( null == disableRowError ){ disableRowError = formControl.isDisableRowError(); } return disableRowError; } public boolean isNested(){ if( null == nested ){ nested = false; for(UIComponent c=formControl.getParent(); c!=null; c=c.getParent()) { // When the parent is a dialog then the form should not be considered as nested if(c instanceof UIDialog) { nested = false; break; } if(c instanceof FormLayout) { nested = true; break; } } } return nested; } public boolean isDisableRequiredMarks(){ if( null == disableRequiredMarks ){ disableRequiredMarks = formControl.isDisableRequiredMarks(); } return disableRequiredMarks; } public String getLabelPosition(){ if( null == labelPosition ){ labelPosition = formControl.getLabelPosition(); if(labelPosition==null) { labelPosition = ""; } } return labelPosition; } public int getColCount() { return colCount; } } protected ComputedFormData createFormData(FacesContext context, FormLayout formControl){ return new ComputedFormData((UIFormTable)formControl); } // ================================================================ // Main Form // ================================================================ @Override protected void writeFormLayout(FacesContext context, ResponseWriter w, FormLayout c) throws IOException { ComputedFormData formData = createFormData(context, c); String style = c.getStyle(); String styleClass = c.getStyleClass(); boolean nested = formData.isNested(); if(!nested) { w.startElement("fieldset", c); // $NON-NLS-1$ } else { w.startElement("div", c); // $NON-NLS-1$ style = ExtLibUtil.concatStyles("margin-left: -25px; margin-right: 0px;", style); // $NON-NLS-1$ } String clientId = c.getClientId(context); w.writeAttribute("id", clientId, "clientId"); // $NON-NLS-1$ $NON-NLS-2$ if(!StringUtil.isEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } if(!StringUtil.isEmpty(styleClass)) { w.writeAttribute("class", styleClass, null); // $NON-NLS-1$ } if(!nested){ String legend = c.getLegend(); if(StringUtil.isNotEmpty(legend)) { w.startElement("legend", c); // $NON-NLS-1$ w.writeText(legend, "legend"); // $NON-NLS-1$ w.endElement("legend"); // $NON-NLS-1$ } } newLine(w); // TODO the xe:formTable is using a HTML TABLE element, but the latest OneUI uses DIVs instead // as they're better for accessibility. This implementation should be changed to use DIVs // before the control is published. See http://rtpgsa.ibm.com/projects/o/oneui/development/OneUI_3.0.0_rc1/docPublic/components/forms.htm // TODO the OneUI spec now has recommendations for subsections in the form control // where as for the initial TeamRoom implementation // we recommended using an inner xe:formTable control within an xe:formRow // Should use the new recommended form table format, with support for sections, // collapsible sections, and tabs. // See http://rtpgsa.ibm.com/projects/o/oneui/development/OneUI_3.0.0_rc1/docPublic/components/forms.htm // TODO the table summary, and other table accessibility attributes w.startElement("table", c); // $NON-NLS-1$ writeMainTableTag(context, w, c); w.startElement("tbody", c); // $NON-NLS-1$ newLine(w); writeErrorSummary(context, w, c, formData); writeHeader(context, w, c); writeForm(context, w, c, formData); writeFooter(context, w, c); w.endElement("tbody"); // $NON-NLS-1$ newLine(w); w.endElement("table"); // $NON-NLS-1$ newLine(w); if(!nested) { w.endElement("fieldset"); // $NON-NLS-1$ } else { w.endElement("div"); // $NON-NLS-1$ } newLine(w); } protected void writeMainTableTag(FacesContext context, ResponseWriter w, FormLayout c) throws IOException { String ariaLabel = c.getAriaLabel(); if (StringUtil.isNotEmpty(ariaLabel)) { w.writeAttribute("aria-label", ariaLabel, null); // $NON-NLS-1$ } String tbStyle = (String)getProperty(PROP_TABLESTYLE); if(StringUtil.isNotEmpty(tbStyle)) { w.writeAttribute("style", tbStyle, null); // $NON-NLS-1$ } String tbStyleClass = (String)getProperty(PROP_TABLESTYLECLASS); if(StringUtil.isNotEmpty(tbStyleClass)) { w.writeAttribute("class", tbStyleClass, null); // $NON-NLS-1$ } String tbRole = (String)getProperty(PROP_TABLEROLE); if(StringUtil.isNotEmpty(tbRole)) { w.writeAttribute("role", tbRole, null); // $NON-NLS-1$ } w.writeAttribute("cellpadding", "0", null); // $NON-NLS-1$ w.writeAttribute("cellspacing", "0", null); // $NON-NLS-1$ w.writeAttribute("border", "0", null); // $NON-NLS-1$ } // ================================================================ // Error Summary // ================================================================ protected void writeErrorSummary(FacesContext context, ResponseWriter w, FormLayout c, ComputedFormData formData) throws IOException { if(!c.isDisableErrorSummary()) { // Should we apply a filter to retain only the message belonging to the controls within the form? // Easy enough with a FilteredIterator Iterator<FacesMessage> msg = getMessages(context); if(msg.hasNext()) { w.startElement("tr", c); // $NON-NLS-1$ String style = (String)getProperty(PROP_STYLEERRORSUMMARY); if(StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } String cls = (String)getProperty(PROP_STYLECLASSERRORSUMMARY); if(StringUtil.isNotEmpty(cls)) { w.writeAttribute("class", cls, null); // $NON-NLS-1$ } w.startElement("td", null); // $NON-NLS-1$ w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ w.startElement("div", c); // $NON-NLS-1$ w.writeAttribute("role", "alert", null); // $NON-NLS-1$ $NON-NLS-2$ writeErrorSummaryContent(context, w, c, msg); w.endElement("div"); // $NON-NLS-1$ w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } } } @SuppressWarnings("unchecked")//$NON-NLS-1$ protected static Iterator<FacesMessage> getMessages(FacesContext context) { return context.getMessages(); } @SuppressWarnings("unchecked")//$NON-NLS-1$ protected static Iterator<FacesMessage> getMessages(FacesContext context, String clientId) { return context.getMessages(clientId); } // ================================================================ // Header // ================================================================ @Override protected void writeFormTitle(FacesContext context, ResponseWriter w, FormLayout c, String title, String description) throws IOException { w.startElement("tr", c); // $NON-NLS-1$ w.startElement("td", c); // $NON-NLS-1$ String style = (String)getProperty(PROP_STYLEHEADER); if(StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } String cls = (String)getProperty(PROP_STYLECLASSHEADER); if(StringUtil.isNotEmpty(cls)) { w.writeAttribute("class", cls, null); // $NON-NLS-1$ } w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ writeFormTitleContent(context, w, c, title, description); w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } @Override protected void writeHeaderFacet(FacesContext context, ResponseWriter w, FormLayout c, UIComponent header) throws IOException { w.startElement("tr", c); // $NON-NLS-1$ w.startElement("td", c); // $NON-NLS-1$ String style = (String)getProperty(PROP_STYLEHEADER); if(StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } String cls = (String)getProperty(PROP_STYLECLASSHEADER); if(StringUtil.isNotEmpty(cls)) { w.writeAttribute("class", cls, null); // $NON-NLS-1$ } w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ writeHeaderFacetContext(context, w, c, header); w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } @Override protected void writeFooterFacet(FacesContext context, ResponseWriter w, FormLayout c, UIComponent footer) throws IOException { w.startElement("tr", c); // $NON-NLS-1$ w.startElement("td", c); // $NON-NLS-1$ String style = (String)getProperty(PROP_STYLEFOOTER); if(StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } String cls = (String)getProperty(PROP_STYLECLASSFOOTER); if(StringUtil.isNotEmpty(cls)) { w.writeAttribute("class", cls, null); // $NON-NLS-1$ } w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ writeFooterFacetContent(context, w, c, footer); w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } // ================================================================ // Form Row // ================================================================ protected void writeForm(FacesContext context, ResponseWriter w, FormLayout c, ComputedFormData formData) throws IOException { writeChildRows(context, w, c, c, formData); } protected void writeChildRows(FacesContext context, ResponseWriter w, FormLayout c, UIComponent parent, ComputedFormData formData) throws IOException { List<UIComponent> children = TypedUtil.getChildren(parent); int count = children.size(); // Calculate if the layout has multiple columns formData.colCount = 0; int colCount = 0; for(int i=0; i<count; i++) { UIComponent child = children.get(i); if(child instanceof UIFormLayoutColumn) { int colspan = Math.max(1,((UIFormLayoutColumn)child).getColSpan()); colCount+=colspan; formData.colCount=Math.max(colCount, formData.colCount); } else if(child instanceof UIFormLayoutRow) { colCount=0; } } if(formData.colCount>0) { writeMultiColumnRows(context, w, c, parent, formData); } else { writeOneColumnRows(context, w, c, parent, formData); } } protected void writeOneColumnRows(FacesContext context, ResponseWriter w, FormLayout c, UIComponent parent, ComputedFormData formData) throws IOException { List<UIComponent> children = TypedUtil.getChildren(parent); for(UIComponent child: children) { if(!child.isRendered()) { continue; } if(child instanceof UIFormLayoutRow) { newLine(w); writeFormRow(context, w, c, formData, (UIFormLayoutRow)child); } else { if( !(child instanceof FormLayout) ){ writeChildRows(context, w, c, child, formData); }// do not recurse through FormLayout descendants } } } protected void writeMultiColumnRows(FacesContext context, ResponseWriter w, FormLayout c, UIComponent parent, ComputedFormData formData) throws IOException { List<UIComponent> children = TypedUtil.getChildren(parent); boolean tr = false; for(UIComponent child: children) { if(!child.isRendered()) { continue; } if(child instanceof UIFormLayoutRow) { if(tr) { w.endElement("tr"); // $NON-NLS-1$ } newLine(w); w.startElement("tr", c); // $NON-NLS-1$ w.startElement("td", c); // $NON-NLS-1$ int colspan = formData.colCount; if(colspan>1) { w.writeAttribute("colspan", Integer.toString(colspan), null); // $NON-NLS-1$ } w.startElement("table", c); // $NON-NLS-1$ w.writeAttribute("role", "presentation", null); // $NON-NLS-1$ $NON-NLS-2$ w.writeAttribute("style", "width: 100%", null); // $NON-NLS-1$ $NON-NLS-2$ writeFormRow(context, w, c, formData, (UIFormLayoutRow)child); w.endElement("table"); // $NON-NLS-1$ w.endElement("td"); // $NON-NLS-1$ w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ newLine(w); tr = false; } else if(child instanceof UIFormLayoutColumn) { UIFormLayoutColumn col = (UIFormLayoutColumn)child; if(!tr) { w.startElement("tr", c); // $NON-NLS-1$ tr = true; } w.startElement("td", c); // $NON-NLS-1$ int colspan = Math.max(1,col.getColSpan()); if(colspan>1) { w.writeAttribute("colspan", Integer.toString(colspan), null); // $NON-NLS-1$ } String colStyle = col.getStyle(); if(StringUtil.isNotEmpty(colStyle)) { w.writeAttribute("style", colStyle, null); // $NON-NLS-1$ } String colClass = col.getStyleClass(); if(StringUtil.isNotEmpty(colClass)) { w.writeAttribute("class", colClass, null); // $NON-NLS-1$ } w.startElement("table", c); // $NON-NLS-1$ w.writeAttribute("role", "presentation", null); // $NON-NLS-1$ $NON-NLS-2$ w.writeAttribute("style", "width: 100%", null); // $NON-NLS-1$ $NON-NLS-2$ for(UIComponent row: TypedUtil.getChildren(col)) { if(row instanceof UIFormLayoutRow) { if(!row.isRendered()) { continue; } writeFormRow(context, w, c, formData, (UIFormLayoutRow)row); } } w.endElement("table"); // $NON-NLS-1$ w.endElement("td"); // $NON-NLS-1$ newLine(w); } else { if( !(child instanceof FormLayout) ){ writeChildRows(context, w, c, child, formData); }// do not recurse through FormLayout descendants } } if(tr) { w.endElement("tr"); // $NON-NLS-1$ newLine(w); } newLine(w); } protected void writeFormRow(FacesContext context, ResponseWriter w, FormLayout c, ComputedFormData formData, UIFormLayoutRow row) throws IOException { ComputedRowData rowData = createRowData(context, c, formData, row); UIInput edit = row.getForComponent(); if(edit!=null) { // Write the error messages, if any if(!formData.isDisableRowError()) { Iterator<FacesMessage> msg = getMessages(context, edit.getClientId(context)); if(msg.hasNext()) { while(msg.hasNext()) { FacesMessage m = msg.next(); writeFormRowError(context, w, c, row, edit, m, rowData); } } } } // The write the children writeFormRowData(context, w, c, formData, row, edit, rowData); } protected void writeFormRowError(FacesContext context, ResponseWriter w, FormLayout c, UIFormLayoutRow row, UIInput edit, FacesMessage m, ComputedRowData rowData) throws IOException { boolean labelAbove = rowData.isLabelAbove(); w.startElement("tr", c); // $NON-NLS-1$ String rowStyle = row.getStyle(); if(StringUtil.isNotEmpty(rowStyle)) { w.writeAttribute("style", rowStyle, null); // $NON-NLS-1$ } String rowClass = row.getStyleClass(); if(StringUtil.isNotEmpty(rowClass)) { w.writeAttribute("class", rowClass, null); // $NON-NLS-1$ } // 1st column, the error message w.startElement("td", c); // $NON-NLS-1$ w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ w.startElement("div", c); // $NON-NLS-1$ w.writeAttribute("role", "alert", null); // $NON-NLS-1$ $NON-NLS-2$ String style; if(!rowData.formData.isNested()) { style = (String)getProperty(PROP_ERRORROWSTYLE); }else{ if( !DirLangUtil.isRTL(row) ){ style = (String)getProperty(PROP_ERRORROWSTYLENESTED); }else{ style = (String)getProperty(PROP_ERRORROWSTYLENESTED_RTL); } } if(StringUtil.isNotEmpty(style)) { w.writeAttribute("style", style, null); // $NON-NLS-1$ } String cls = (String)getProperty(PROP_ERRORROWCLASS); if(StringUtil.isNotEmpty(cls)) { w.writeAttribute("class", cls, null); // $NON-NLS-1$ } writeErrorMessage(context, w, c, m); if(labelAbove) { w.endElement("div"); // $NON-NLS-1$ } w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } protected void writeFormRowData(FacesContext context, ResponseWriter w, FormLayout c, ComputedFormData formData, UIFormLayoutRow row, UIInput edit, ComputedRowData rowData) throws IOException { w.startElement("tr", c); // $NON-NLS-1$ String fieldStyle = row.getStyle(); if(StringUtil.isEmpty(fieldStyle)) { fieldStyle = (String)getProperty(PROP_FIELDROWSTYLE); } if(StringUtil.isNotEmpty(fieldStyle)) { w.writeAttribute("style", fieldStyle, null); // $NON-NLS-1$ } String fieldClass = row.getStyleClass(); if(StringUtil.isEmpty(fieldClass)) { fieldClass = (String)getProperty(PROP_FIELDROWCLASS); } if(StringUtil.isNotEmpty(fieldClass)) { w.writeAttribute("class", fieldClass, null); // $NON-NLS-1$ } boolean hasLabel = rowData.hasLabel(); boolean labelAbove = rowData.isLabelAbove(); // Write the label w.startElement("td", c); // $NON-NLS-1$ if(hasLabel) { String lblStyle = ExtLibUtil.concatStyles("padding-left: 25px",(String)getProperty(PROP_FIELDLABELSTYLE)); // $NON-NLS-1$ String lblClass = (String)getProperty(PROP_FIELDLABELCLASS); if(labelAbove) { w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ w.startElement("div", c); // $NON-NLS-1$ } else { String width = row.getLabelWidth(); if(StringUtil.isEmpty(width)) { width = formData.getLabelWidth(); } if(StringUtil.isEmpty(width)) { width = (String)getProperty(PROP_FIELDLABELWIDTH); } lblStyle = ExtLibUtil.concatStyles("width:"+width,(String)getProperty(PROP_FIELDLABELSTYLE)); // $NON-NLS-1$ } if(StringUtil.isNotEmpty(lblStyle)) { w.writeAttribute("style", lblStyle, null); // $NON-NLS-1$ } if(StringUtil.isNotEmpty(lblClass)) { w.writeAttribute("class", lblClass, null); // $NON-NLS-1$ } String label = row.getLabel(); writeFormRowLabel(context, w, c, formData, row, edit, label); if(labelAbove) { if(c.isFieldHelp()) { writeFormRowHelp(context, w, c, row, edit); } w.endElement("div"); // $NON-NLS-1$ w.startElement("div", c); // $NON-NLS-1$ } else { w.endElement("td"); // $NON-NLS-1$ w.startElement("td", c); // $NON-NLS-1$ } } else { w.writeAttribute("colspan", "3", null); // $NON-NLS-1$ } String editStyle = ExtLibUtil.concatStyles((!hasLabel||labelAbove)?"padding-left: 25px":"",(String)getProperty(PROP_FIELDEDITSTYLE)); // $NON-NLS-1$ if(StringUtil.isNotEmpty(editStyle)) { w.writeAttribute("style", editStyle, null); // $NON-NLS-1$ } String editClass = (String)getProperty(PROP_FIELDEDITCLASS); if(StringUtil.isNotEmpty(editClass)) { w.writeAttribute("class", editClass, null); // $NON-NLS-1$ } writeFormRowDataField(context, w, c, row, edit); if(hasLabel) { if(labelAbove) { w.endElement("div"); // $NON-NLS-1$ } // Write the help if(hasLabel) { if(!labelAbove) { w.startElement("td", c); // $NON-NLS-1$ if(c.isFieldHelp()) { writeFormRowHelp(context, w, c, row, edit); } w.endElement("td"); // $NON-NLS-1$ } } } w.endElement("td"); // $NON-NLS-1$ w.endElement("tr"); // $NON-NLS-1$ } protected void writeFormRowLabel(FacesContext context, ResponseWriter w, FormLayout c, ComputedFormData formData, UIFormLayoutRow row, UIInput edit, String label) throws IOException { if(StringUtil.isNotEmpty(label)) { w.startElement("label", c); // $NON-NLS-1$ if(edit!=null && !ReadOnlyAdapterRenderer.isReadOnly(context, edit)) { w.writeAttribute("for", edit.getClientId(context), null); // $NON-NLS-1$ } // Required mark if(edit!=null && !formData.isDisableRequiredMarks() && edit.isRequired()) { writeFormRowRequiredContent(context, w, c, row, edit); } // Label text writeFormRowDataLabel(context, w, c, row, edit, label); w.endElement("label"); // $NON-NLS-1$ } else { UIComponent facet = row.getFacet(UIFormLayoutRow.FACET_LABEL); if(facet!=null) { writeFormRowDataLabelFacet(context, w, c, row, edit, facet); } else { JSUtil.writeTextBlank(w); //   } } } protected void writeFormRowHelp(FacesContext context, ResponseWriter w, FormLayout c, UIFormLayoutRow row, UIInput edit) throws IOException { String helpId = row.getHelpId(); String helpStyle = (String)getProperty(PROP_HELPROWSTYLE); if(StringUtil.isNotEmpty(helpStyle)) { w.writeAttribute("style", helpStyle, null); // $NON-NLS-1$ } String helpClass = (String)getProperty(PROP_HELPROWCLASS); if(StringUtil.isNotEmpty(helpClass)) { w.writeAttribute("class", helpClass, null); // $NON-NLS-1$ } if(StringUtil.isNotEmpty(helpId)) { String forClientId = null; UIComponent forComponent = FacesUtil.getComponentFor(c, helpId); if(forComponent == null) { UIComponent p = (UIComponent)FacesUtil.getNamingContainer(c); if(p!=null) { forClientId = p.getClientId(context)+":"+helpId; } } else { forClientId = forComponent.getClientId(context); } writeFormRowDataHelp(context, w, c, row, edit, forClientId); } else { UIComponent facet = row.getFacet(UIFormLayoutRow.FACET_HELP); if(facet!=null) { writeFormRowDataHelpFacet(context, w, c, row, edit, facet); } else { JSUtil.writeTextBlank(w); //   } } } public boolean isLabelAbove() { return false; } }