2010-05-13 56 views
14

我有一些當前工作的JSF代碼(如下所示),我需要修改它以有條件地禁止顯示某些表的行。我知道如何有條件地抑制特定單元格的顯示,但似乎會創建一個空單元格,而我試圖做的是不顯示該行。使用JSF有條件地顯示行Datatable

有什麼建議嗎?

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

基本上,這說#{com.rendered}將有條件地顯示一個單一的單元格的內容,產生一個空單元時com.rendered爲假的行。但是我想在某些條件下跳過整行顯示 - 我該怎麼做呢?

回答

11

行對應於表中集合中的數據對象。如果您不想要該行,請不要將該對象放入集合中。可以使用rowClasses參數作爲dataTable。

豆代碼:

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

對不起,這不是一個真正的選項 - 此表顯示某些應用程序範圍的參考數據,除了在特定情況下數據只能在特定條件下顯示。 – Elie 2010-05-13 19:03:28

+4

然後兩個集合,一個包含所有數據,另一個包含顯示的內容? – Naganalf 2010-05-13 19:08:47

+0

問題是我有2行,並根據情況,有時顯示行A,有時行B,有時兩個。保持多套將意味着我必須保留這三個版本,這是不理想的。我希望有另一種方式來做到這一點。 – Elie 2010-05-13 19:43:55

0

我已經成功地隱藏的行通過將渲染屬性中的所有<h:column>標籤。問題是它壓制了表頭。如果您的表格沒有表格標題(它們是嵌入在<h:column>中的<f:facet name="header">標籤),則此方法可能適用於您。

我結束了在支持bean中使用多個列表,因爲我需要表頭。

+0

已經嘗試了這一點,除非我做錯了行所有列已渲染的行解析爲'FALSE',仍然呈現爲空行(即,'') – 2013-11-14 14:37:36

4

對於使用richFaces的用戶,可以使用rich:column的filterExpression屬性。

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

如果條件不符合,則完整的行被過濾掉。

示例使用接縫EL!

+0

我不明白這可以工作,你在列過濾器表達式上的設置,但行消失? – Lyrion 2013-05-15 09:33:07

+0

是的,它的工作原理! – mhoms 2015-05-28 13:28:47

1

對Brian的解決方案的擴展。 要顯示的列名我並在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

我延伸HtmlTableRenderer默認渲染並覆蓋renderRowStart方法通過給予風格屬性轉換表 - > TR與元素來實現這一值顯示:無

綁定列表中的項目需要實現TableRow接口,它只有一個isHide方法。在具體的類中,你可以放任何你喜歡的邏輯給布爾值。

順便說一下,在這個自定義渲染器中還有PrimeFaces實現,就像函數一樣,當表爲空時,表格> tr將自動計算表中的多少列,併爲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

在我以前的評論中忘了提及。我們需要以下新元素添加到faces-config.xml中 ' \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 – 2016-04-18 23:37:09