2010-05-13 46 views
14

Tengo un código JSF que funciona actualmente (como se muestra a continuación), y tengo que modificarlo para suprimir condicionalmente la visualización de ciertas filas de la tabla. Sé cómo suprimir condicionalmente la visualización de una celda en particular, pero eso parece crear una celda vacía, mientras que lo que intento hacer es no mostrar la fila en absoluto.Muestra condicional fila utilizando JSF Datatable

¿Alguna sugerencia?

<h:dataTable styleClass="resultsTable" id="t1" value="#{r.common}" var="com" headerClass="headerBackgrnd" rowClasses="rowOdd, rowEven" columnClasses="leftAlign, rightAlign, leftAlign"> 
    <h:column> 
     <h:outputText rendered="#{com.rendered}" styleClass="inputText" value="#{com.description}: " /> 
    </h:column> 
    <h:column> 
     <h:outputText styleClass="outputText" value="#{com.v1}" /> 
    </h:column> 
    <h:column> 
     <h:inputText styleClass="inputText" value="#{com.v2}" /> 
    </h:column> 
</h:dataTable> 

Básicamente, la línea que dice #{com.rendered} mostrará condicionalmente el contenido de una sola célula, produciendo una celda vacía cuando com.rendered es falso. Pero quiero omitir toda una fila de la pantalla bajo ciertas condiciones: ¿cómo podría hacer eso?

Respuesta

11

Las filas corresponden a objetos de datos en la colección de su tabla. Si no quiere la fila, no coloque el objeto en la colección.

Como alternativa, puede usar el parámetro rowClasses para dataTable.

código Bean:

public String getRowClasses() { 
    StringBuilder sb = new StringBuilder(); 
    for (Data data : myData) { 
     sb.append(data.hide ? 'hide,' : 'show,'); 
    } 
    return sb.toString(); 
} 

CSS:

tr.hide {display:none;} 
+0

Lo lamentamos, esta no es una opción: esta tabla muestra ciertos datos de referencia de toda la aplicación, excepto en esta instancia particular, que los datos solo se pueden mostrar bajo ciertas condiciones. – Elie

+4

¿Dos colecciones entonces, una con todos los datos, la segunda con las cosas para mostrar? – Naganalf

+0

El problema es que tengo 2 filas, y dependiendo del caso, algunas veces veo la fila A, a veces la fila B, y algunas veces ambas. Mantener varios conjuntos significa que tengo que mantener tres versiones de esto, lo cual no es ideal. Espero que haya otra forma de hacer esto. – Elie

0

he escondido con éxito filas por poner un atributo ejecute en todas las etiquetas <h:column>. El problema es que suprime los encabezados de la tabla. Si su tabla no tiene encabezados de tabla (son etiquetas <f:facet name="header"> incrustadas en <h:column>), este enfoque podría funcionar para usted.

Terminé usando múltiples listas en el bean de respaldo, ya que necesitaba los encabezados de tabla.

+0

Después de haber intentado esto, a menos que esté haciendo algo mal las filas donde todas las columnas han resuelto resolver 'FALSE', todavía se representan como filas vacías (es decir,' ') –

4

Para las personas que usan richFaces, puede usar el atributo rich: filter's filterExpression.

<rich:column filterExpression="#{put your expression here}"> 
    ... 
</rich> 

Si no se cumple esta condición, se filtra la fila completa.

¡El ejemplo está usando la costura EL!

+0

No entiendo cómo puede funcionar esto, su configuración en la expresión de filtro de columna, pero aún la fila desaparece? – Lyrion

+0

sí, ¡funciona! – mhoms

1

extensión a la solución de Brian. Para mostrar los nombres de columna hice lo siguiente en PrimeFaces

<p:dataTable value="#{eiBean.dce.ilDbConns}" var="c"> 
    <p:columnGroup type="header"> 
     <p:row> 
      <p:column colspan="1" /> 
      <p:column colspan="1" /> 
     </p:row> 
     <p:row> 
      <p:column headerText="DataBase Type" width="auto" /> 
      <p:column headerText="URL" width="400" /> 
     </p:row> 
    </p:columnGroup> 
    <p:column rendered='#{c.conType == "TARGET"}'> 
     <p:outputLabel value="#{c.dbType}" /> 
    </p:column> 
    <p:column rendered='#{c.conType == "TARGET"}'> 
     <p:outputLabel value="#{c.dbUrl}" /> 
    </p:column>   
</p:dataTable> 
0

extiendo HtmlTableRenderer procesador defecto y sobrescribir renderRowStart método para lograr esto dando estilo de atributo en table-> tr elemento con valor pantalla: ninguna.

El elemento dentro de la lista de enlaces necesita implementar la interfaz TableRow que solo tiene un método de isHide. En la clase concreta puedes poner cualquier lógica que desees para dar un valor booleano.

Por cierto, en este renderizador personalizado también tiene la función PrimeFaces como función que da el mensaje cuando la tabla está vacía y table-> tr calculará automáticamente cuántas columnas en la tabla y dará el valor adecuado al atributo colspan.

public class MyDataTableRenderer extends HtmlTableRenderer { 
    private static final Integer[] ZERO_INT_ARRAY = new Integer[] { 0 }; 
    private static final String NO_RESULT_MESSAGE_ATTR_NAME = "noResultMessage"; 
    private static final String defaultEmptyMessage = "No records found"; 
    private static final Logger log = Logger.getLogger(DHSDataTableRenderer.class.getName()); 

@Override 
public void encodeInnerHtml(FacesContext facesContext, UIComponent component) throws IOException { 
    UIData uiData = (UIData) component; 
    String message = (String) uiData.getAttributes().get(NO_RESULT_MESSAGE_ATTR_NAME); 
    if (message == null || "".equals(message.trim())) { 
     message = defaultEmptyMessage; 
    } 

    ResponseWriter writer = facesContext.getResponseWriter(); 

    int rowCount = uiData.getRowCount(); 

    int newspaperColumns = getNewspaperColumns(component); 

    int columnNumber = getChildCount(component); 

    if (rowCount == -1 && newspaperColumns == 1) { 
     encodeInnerHtmlUnknownRowCount(facesContext, component); 
     return; 
    } 

    if (rowCount == 0) { 
     // nothing to render, to get valid xhtml we render an empty dummy 
     // row 
     writer.startElement(HTML.TBODY_ELEM, uiData); 
     writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element", null); 
     writer.startElement(HTML.TR_ELEM, uiData); 
     writer.startElement(HTML.TD_ELEM, uiData); 
     writer.writeAttribute(HTML.COLSPAN_ATTR, columnNumber, null); 
     writer.writeAttribute(HTML.CLASS_ATTR, "dhs-empty-table", null); 
     writer.write(message); 
     writer.endElement(HTML.TD_ELEM); 
     writer.endElement(HTML.TR_ELEM); 
     writer.endElement(HTML.TBODY_ELEM); 
     return; 
    } 

    // begin the table 
    // get the CSS styles 
    Styles styles = getStyles(uiData); 

    int first = uiData.getFirst(); 
    int rows = uiData.getRows(); 
    int last; 

    if (rows <= 0) { 
     last = rowCount; 
    } else { 
     last = first + rows; 
     if (last > rowCount) { 
      last = rowCount; 
     } 
    } 

    int newspaperRows; 
    if ((last - first) % newspaperColumns == 0) { 
     newspaperRows = (last - first)/newspaperColumns; 
    } else { 
     newspaperRows = ((last - first)/newspaperColumns) + 1; 
    } 
    boolean newspaperHorizontalOrientation = isNewspaperHorizontalOrientation(component); 

    // get the row indizes for which a new TBODY element should be created 
    Integer[] bodyrows = getBodyRows(facesContext, component); 
    int bodyrowsCount = 0; 

    // walk through the newspaper rows 
    for (int nr = 0; nr < newspaperRows; nr++) { 
     boolean rowStartRendered = false; 
     // walk through the newspaper columns 
     for (int nc = 0; nc < newspaperColumns; nc++) { 

      // the current row in the 'real' table 
      int currentRow; 
      if (newspaperHorizontalOrientation) { 
       currentRow = nr * newspaperColumns + nc + first; 
      } else { 
       currentRow = nc * newspaperRows + nr + first; 
      } 

      // if this row is not to be rendered 
      if (currentRow >= last) { 
       continue; 
      } 

      // bail if any row does not exist 
      uiData.setRowIndex(currentRow); 
      if (!uiData.isRowAvailable()) { 
       log.severe("Row is not available. Rowindex = " + currentRow); 
       break; 
      } 

      if (nc == 0) { 
       // first column in table, start new row 
       beforeRow(facesContext, uiData); 

       // is the current row listed in the bodyrows attribute 
       if (ArrayUtils.contains(bodyrows, currentRow)) { 
        // close any preopened TBODY element first 
        if (bodyrowsCount != 0) { 
         HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
         writer.endElement(HTML.TBODY_ELEM); 
        } 
        HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
        writer.startElement(HTML.TBODY_ELEM, uiData); 
        // Do not attach bodyrowsCount to the first TBODY 
        // element, because of backward compatibility 
        writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element" + (bodyrowsCount == 0 ? "" : bodyrowsCount), 
          null); 
        bodyrowsCount++; 
       } 

       HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
       renderRowStart(facesContext, writer, uiData, styles, nr); 
       rowStartRendered = true; 
      } 

      List<UIComponent> children = null; 
      for (int j = 0, size = getChildCount(component); j < size; j++) { 
       if (children == null) { 
        children = getChildren(component); 
       } 
       UIComponent child = children.get(j); 
       if (child.isRendered()) { 
        boolean columnRendering = child instanceof UIColumn; 

        if (columnRendering) { 
         beforeColumn(facesContext, uiData, j); 
        } 

        encodeColumnChild(facesContext, writer, uiData, child, styles, nc * uiData.getChildCount() + j); 

        if (columnRendering) { 
         afterColumn(facesContext, uiData, j); 
        } 
       } 
      } 

      if (hasNewspaperTableSpacer(uiData)) { 
       // draw the spacer facet 
       if (nc < newspaperColumns - 1) { 
        renderSpacerCell(facesContext, writer, uiData); 
       } 
      } 
     } 
     if (rowStartRendered) { 
      renderRowEnd(facesContext, writer, uiData); 
      afterRow(facesContext, uiData); 
     } 
    } 

    if (bodyrowsCount != 0) { 
     // close the last TBODY element 
     HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
     writer.endElement(HTML.TBODY_ELEM); 
    } 
} 

@Override 
protected void renderRowStart(FacesContext facesContext, ResponseWriter writer, UIData uiData, Styles styles, int rowStyleIndex) throws IOException { 
    writer.startElement(HTML.TR_ELEM, null); // uiData); 

    renderRowStyle(facesContext, writer, uiData, styles, rowStyleIndex); 
    Object obj = uiData.getRowData(); 
    boolean isHide = false; 
    if (obj instanceof TableRow) { 
     isHide = ((TableRow) obj).isHide(); 
    } 
    if (isHide) { 
     writer.writeAttribute("style", "display: none;", null); 
    } 
    Object rowId = uiData.getAttributes().get(org.apache.myfaces.shared.renderkit.JSFAttr.ROW_ID); 

    if (rowId != null) { 
     writer.writeAttribute(HTML.ID_ATTR, rowId.toString(), null); 
    } 
} 

private void encodeInnerHtmlUnknownRowCount(FacesContext facesContext, UIComponent component) throws IOException { 
    UIData uiData = (UIData) component; 
    ResponseWriter writer = facesContext.getResponseWriter(); 

    Styles styles = getStyles(uiData); 

    Integer[] bodyrows = getBodyRows(facesContext, component); 
    int bodyrowsCount = 0; 

    int first = uiData.getFirst(); 
    int rows = uiData.getRows(); 
    int currentRow = first; 
    boolean isRowRendered = false; 

    while (true) { 
     uiData.setRowIndex(currentRow); 
     if (!uiData.isRowAvailable()) { 
      break; 
     } 

     isRowRendered = true; 

     // first column in table, start new row 
     beforeRow(facesContext, uiData); 

     // is the current row listed in the bodyrows attribute 
     if (ArrayUtils.contains(bodyrows, currentRow)) { 
      // close any preopened TBODY element first 
      if (bodyrowsCount != 0) { 
       HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
       writer.endElement(HTML.TBODY_ELEM); 
      } 
      HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
      writer.startElement(HTML.TBODY_ELEM, uiData); 
      // Do not attach bodyrowsCount to the first TBODY element, 
      // because of backward compatibility 
      writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element" + (bodyrowsCount == 0 ? "" : bodyrowsCount), null); 
      bodyrowsCount++; 
     } 

     HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
     renderRowStart(facesContext, writer, uiData, styles, currentRow); 

     List<UIComponent> children = null; 
     for (int j = 0, size = getChildCount(component); j < size; j++) { 
      if (children == null) { 
       children = getChildren(component); 
      } 
      UIComponent child = children.get(j); 
      if (child.isRendered()) { 
       boolean columnRendering = child instanceof UIColumn; 

       if (columnRendering) { 
        beforeColumn(facesContext, uiData, j); 
       } 

       encodeColumnChild(facesContext, writer, uiData, child, styles, j); 

       if (columnRendering) { 
        afterColumn(facesContext, uiData, j); 
       } 
      } 
     } 

     renderRowEnd(facesContext, writer, uiData); 
     afterRow(facesContext, uiData); 

     currentRow++; 

     if (rows > 0 && currentRow - first > rows) { 
      break; 
     } 
    } 

    if (!isRowRendered) { 
     // nothing to render, to get valid xhtml we render an empty dummy 
     // row 
     writer.startElement(HTML.TBODY_ELEM, uiData); 
     writer.writeAttribute(HTML.ID_ATTR, component.getClientId(facesContext) + ":tbody_element", null); 
     writer.startElement(HTML.TR_ELEM, uiData); 
     writer.startElement(HTML.TD_ELEM, uiData); 
     writer.endElement(HTML.TD_ELEM); 
     writer.endElement(HTML.TR_ELEM); 
     writer.endElement(HTML.TBODY_ELEM); 
     return; 
    } 

    if (bodyrowsCount != 0) { 
     // close the last TBODY element 
     HtmlRendererUtils.writePrettyLineSeparator(facesContext); 
     writer.endElement(HTML.TBODY_ELEM); 
    } 
} 

private Integer[] getBodyRows(FacesContext facesContext, UIComponent component) { 
    Integer[] bodyrows = null; 
    String bodyrowsAttr = (String) component.getAttributes().get(JSFAttr.BODYROWS_ATTR); 
    if (bodyrowsAttr != null && !"".equals(bodyrowsAttr)) { 
     String[] bodyrowsString = StringUtils.trim(StringUtils.splitShortString(bodyrowsAttr, ',')); 
     // parsing with no exception handling, because of JSF-spec: 
     // "If present, this must be a comma separated list of integers." 
     bodyrows = new Integer[bodyrowsString.length]; 
     for (int i = 0; i < bodyrowsString.length; i++) { 
      bodyrows[i] = new Integer(bodyrowsString[i]); 
     } 

    } else { 
     bodyrows = ZERO_INT_ARRAY; 
    } 
    return bodyrows; 
} 

}

+0

Olvidé mencionar en los comentarios anteriores míos. Tenemos que añadir siguiente elemento nuevo en faces-config.xml ' \t \t \t \t \t javax.faces.Data \t \t \t javax.faces.Table \t \t \t <-clase de procesador> xxx.xxx.MyDataTableRenderer \t \t \t ' @Laila Agaev –

Cuestiones relacionadas