2010-05-13 7 views
14

Ich habe einige JSF-Code, der derzeit funktioniert (wie unten gezeigt), und ich muss es ändern, um die Anzeige bestimmter Zeilen der Tabelle bedingt zu unterdrücken. Ich weiß, wie man die Anzeige einer bestimmten Zelle bedingt unterdrückt, aber das scheint eine leere Zelle zu erzeugen, während ich versuche, die Zeile überhaupt nicht anzuzeigen.Bedingte Anzeigezeile mit JSF Datatable

Irgendwelche Vorschläge? Grundsätzlich

<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> 

, die Linie, die sagt #{com.rendered} bedingt den Inhalt einer Einzelzelle angezeigt wird, eine leere Zelle zu erzeugen, wenn com.rendered falsch ist. Aber ich möchte unter bestimmten Bedingungen eine ganze Reihe des Displays überspringen - wie würde ich das machen?

Antwort

11

Zeilen entsprechen Datenobjekten in der Auflistung Ihrer Tabelle. Wenn Sie die Zeile nicht möchten, legen Sie das Objekt nicht in die Sammlung.

Alternativ können Sie den Parameter rowClasses für dataTable verwenden.

Bean Code:

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

Entschuldigung, das ist nicht wirklich eine Option - diese Tabelle zeigt bestimmte anwendungsweite Referenzdaten, außer in diesem speziellen Fall, dass Daten nur unter bestimmten Bedingungen angezeigt werden können. – Elie

+4

Dann zwei Sammlungen, eine mit allen Daten, die zweite mit dem Zeug zur Anzeige? – Naganalf

+0

Das Problem ist, dass ich 2 Zeilen habe, und je nach Fall manchmal Zeile A, manchmal Zeile B und manchmal beides anzeigen. Mehrere Sätze zu behalten würde bedeuten, dass ich drei Versionen davon behalten muss, was nicht ideal ist. Ich hoffe, es gibt noch einen anderen Weg, dies zu tun. – Elie

0

ich ein gerendertes Attribut, indem sie in allen <h:column> Tags erfolgreich versteckt Reihen haben. Das Problem ist, dass es die Tabellenüberschriften unterdrückt. Wenn Ihre Tabelle keine Tabellenüberschriften hat (sie sind <f:facet name="header"> Tags, die in <h:column> eingebettet sind), könnte dieser Ansatz für Sie funktionieren.

Ich endete mit mehreren Listen in der Backing-Bean, wie ich die Tabellenköpfe benötigt.

+0

Nachdem ich dies versucht habe, werden die Zeilen, in denen alle Spalten gerendert wurden, immer noch als leere Zeilen gerendert (dh,) –

4

Für Personen, die richFaces verwenden, können Sie das Attribut expression von rich: column verwenden.

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

Wenn die Bedingung nicht erfüllt ist, wird die komplette Zeile ausgefiltert.

Beispiel verwendet Naht EL!

+0

Ich verstehe nicht, wie das funktionieren kann. Ihre Einstellung auf den Spaltenfilter Ausdruck aber noch die Zeile verschwindet? – Lyrion

+0

Ja, es funktioniert! – mhoms

1

Erweiterung zu Brians Lösung. Um die Spaltennamen angezeigt I in primefaces folgendes hat

<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

Ich erweitere HtmlTableRenderer Renderer Standard und überschreiben renderRowStart Methode diese Stil, indem Attribut in Tabellen-> tr Element zu erreichen, mit Wert Anzeige: keine.

Der Eintrag innerhalb der Bindungsliste muss die TableRow-Schnittstelle implementieren, die nur eine Methode von isHide hat. In der konkreten Klasse können Sie jeder beliebigen Logik einen booleschen Wert zuweisen.

BTW, in diesem benutzerdefinierten Renderer hat auch PrimeFaces Implementierung wie Funktion, die die Nachricht gibt, wenn die Tabelle leer ist und die Tabelle-> tr automatisch berechnet, wie viele Spalten in der Tabelle und geben Sie Colspan Attribut den richtigen Wert.

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

Vergessen zu erwähnen in den vorherigen Kommentaren von mir. Wir müssen folgendes neues Element in faces-config.xml hinzufügen ' \t \t \t \t \t javax.faces.Data \t \t \t javax.faces.Table \t \t \t xxx.xxx.MyDataTableRenderer \t \t \t ' @Laila Agaev –