2010-05-13 3 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.

код 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

К сожалению, на самом деле это не вариант. В этой таблице отображаются определенные справочные данные для всего приложения, за исключением этого конкретного экземпляра, что данные могут отображаться только при определенных условиях. – Elie

+4

Две коллекции тогда, одна со всеми данными, вторая с материалом для отображения? – Naganalf

+0

Проблема в том, что у меня есть 2 строки, и в зависимости от случая иногда отображается строка A, иногда строка B, а иногда и то, и другое. Сохранять несколько наборов означает, что я должен хранить три версии этого, что не идеально. Я надеюсь, что есть еще один способ сделать это. – Elie

0

Я успешно скрытые строки, поставив вынесенное атрибут во всех <h:column> тегов. Проблема в том, что он подавляет заголовки таблиц. Если в таблице нет заголовков таблиц (это теги <f:facet name="header">, встроенные в <h:column>), этот подход может сработать для вас.

В итоге я использовал несколько списков в бэкэнде, поскольку мне нужны заголовки таблиц.

+0

Попробовав это, если я не сделаю что-то неправильно, строки, в которых все столбцы предоставили разрешение 'FALSE', все равно отображаются как пустые строки (то есть' ') –

4

Для людей, использующих richFaces, вы можете использовать атрибут rich: columnExpressionExpression.

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

Если условие не выполнено, полная строка отфильтровывается.

Пример использования шва EL!

+0

Я не понимаю, как это может работать, ваша настройка на выражение фильтра столбца, но все же строка исчезает? – Lyrion

+0

Да, это работает! – mhoms

1

расширение решения Брайана. Для отображения имен столбцов я сделал следующее в 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 метода для достижения этой цели, давая стиль атрибута в table-> т.р. элемента с стоимость дисплей: нет.

Элемент внутри списка привязки должен реализовывать интерфейс TableRow, который имеет только один метод isHide. В конкретном классе вы можете поместить любую логику, которая вам нравится давать логическое значение.

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

Забыл упомянуть предыдущие мои комментарии. Нам нужно добавить следующий новый элемент в гранях-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 ' @ Лейла Агаев –

Смежные вопросы