Условно отобразить строку, используя JSF Datatable - PullRequest
14 голосов
/ 13 мая 2010

У меня есть некоторый код JSF, который в настоящее время работает (как показано ниже), и мне нужно изменить его, чтобы условно подавить отображение определенных строк таблицы. Я знаю, как условно подавить отображение определенной ячейки, но это, кажется, создает пустую ячейку, в то время как я пытаюсь вообще не отображать строку.

Есть предложения?

<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 ложно. Но я хочу при определенных условиях пропустить целый ряд экрана - как бы я это сделал?

Ответы [ 6 ]

13 голосов
/ 13 мая 2010

Строки соответствуют объектам данных в коллекции вашей таблицы. Если вам не нужна строка, не помещайте объект в коллекцию.

В качестве альтернативы вы можете использовать параметр 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;}
5 голосов
/ 21 июня 2011

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

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

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

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

2 голосов
/ 08 июля 2014

расширение решения Брайана. Чтобы отобразить названия столбцов, я выполнил следующие действия в виде простых чисел

<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 голосов
/ 10 июня 2016

Используйте пустой селектор css, как предложено здесь, но с tr вместо td. Это сработало для меня.

https://stackoverflow.com/a/19177424

Как описано здесь: https://developer.mozilla.org/en-US/docs/Web/CSS/:empty Этот селектор работает во всех текущих браузерах.

<style>
  tr:empty {
    display: none;
  }
</style>
0 голосов
/ 31 марта 2016

Я расширяю HtmlTableRenderer по умолчанию для рендеринга и перезаписи renderRowStart метод для достижения этого путем передачи атрибута style в элемент table-> 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 голосов
/ 02 июня 2010

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...