4

「サブテーブル」でPrimefaces「データテーブル」を使用しています。2行のヘッダー列がいくつかあります。
最初の行には、5 つのヘッダー列があります。2 行目には、8 つのヘッダー列があります。
データテーブルの最初のレベルの列で、「アイテム」の情報を 5 つの列に表示したいと考えています。
2 番目のレベルで、選択したアイテムの子を表示するときに、アイテムのステータス情報を (8 列で) 表示したいと考えています。

ステータス情報はサブテーブルに含まれています。
ヘッダーの最初の行の列の下に、ヘッダーの2番目の行のいくつかの列をパックしたかったのです。それを可能にするために、ヘッダーの最初の行の列、値「3」を持つ属性「colspan」、および値「2」を持つ別の列を参照しました。

問題は、最初のレベルの行のデータ値列もパックすることです。これは、5 列ではなく 8 列に入力する必要があり、それらがパックされていることを意味します。最初のレベルに 5 つの列、2 番目のレベル (ステータス情報) に 8 つの列が必要です。

本文ではなくヘッダー列にのみ colspan を追加することは可能ですか?

ここに私のコードのサンプルがあります:

        <p:columnGroup type="header">
            <p:row>
                <p:column>
                </p:column>

                <p:column headerText="#{bundle.form_name}" filterBy="#{item.name}"
                    sortBy="#{item.name}" colspan="3">
                </p:column>

                <p:column headerText="#{bundle.form_designation}"
                    style="width:140px;" filterBy="#{item.designation}"
                    sortBy="#{item.designation}" colspan="2">
                </p:column>

                <p:column headerText="#{bundle.form_status}"
                    filterBy="#{item.status}"
                    filterOptions="#{itemStatusListBean.options}">
                </p:column>

                <p:column headerText="#{bundle.form_date}"
                    filterBy="#{item.statusDate}" sortBy="#{item.statusDate}">
                </p:column>
            </p:row>

            <p:row>
                <p:column />
                <p:column headerText="Status" style="width:25px;" />
                <p:column headerText="Type" style="width:25px;" />
                <p:column headerText="Marché" style="width:25px;" />
                <p:column headerText="Groupe" />
                <p:column headerText="Produit" />
                <p:column headerText="Désignation Produit" />
                <p:column headerText="EAN" />
            </p:row>
        </p:columnGroup>

        <p:column style="width:4%">
            <p:rowToggler>
            </p:rowToggler>
        </p:column>

        <p:column>
            <h:outputText value="#{item.name}" />
        </p:column>

        <p:column>
            <h:outputText value="#{item.designation}" />
        </p:column>

        <p:column>
            <h:outputText value="#{item.status.label}" />
        </p:column>

        <p:column>
            <h:outputText value="#{item.statusDate}">
                <f:convertDateTime pattern="dd/MM/yyyy" timeZone="Europe/Paris" />
            </h:outputText>
        </p:column>

        <p:rowExpansion>
            <p:subTable var="status" value="#{item.status}">
                <p:column>
                </p:column>

                <p:column>
                </p:column>

                <p:column>
                </p:column>

                <p:column>
                </p:column>

                <p:column>
                </p:column>

                <p:column>
                </p:column>

                <p:column>
                </p:column>
            </p:subTable>
        </p:rowExpansion>
    </p:dataTable>
4

2 に答える 2

2

さて、今私は解決策を見つけました。
まず第一に、解決策は Primefaces の微調整を意味します。実際、DataTable 内に含まれる「column」タグに属性「colspan」を追加できるようにする必要があります。

これを可能にするには、「org.primefaces.component.datatable」パッケージを作成し、実際の「DataTableBeanRenderer」を拡張する「MyDataTableBeanRenderer」という名前のクラスを作成する必要があります。
このクラスでは、DataTable の本体セルのレンダリング (encodeRegularCell)、行拡張のレンダリング、およびページネーターのレンダリング (使用する場合) を処理するメソッドを「オーバーライド」する必要があります。
また、ヘッダー列グループの 2 行目に含まれる行数を取得するメソッドを追加する必要があります。dataTable のこの 2 番目のレベルに 2 番目よりも多くの行が含まれている場合、現在の "td" または "th" colspan (メソッドに応じて) が調整されます。各メソッドで、「getMaximumNumberOfColumns」の場所を確認します

さて、対応するJavaコードは次のとおりです。

@Override
    protected void encodeRegularCell(FacesContext context, DataTable table, Column column, String clientId,
            boolean selected) throws IOException {
        final ResponseWriter writer = context.getResponseWriter();
        final boolean selectionEnabled = column.getSelectionMode() != null;
        final String style = column.getStyle();
        String styleClass = "";

        if (selectionEnabled) {
            styleClass = DataTable.SELECTION_COLUMN_CLASS;
        } else if (column.getCellEditor() != null) {
            styleClass = DataTable.EDITABLE_COLUMN_CLASS;
        }

        styleClass = column.getStyleClass() == null ? styleClass : styleClass + " " + column.getStyleClass();

        writer.startElement("td", null);
        writer.writeAttribute("role", "gridcell", null);
        if (column.getColspan() != 1) {
            writer.writeAttribute("colspan", column.getColspan(), null);
        }

        if (style != null) {
            writer.writeAttribute("style", style, null);
        }
        if (!isValueBlank(styleClass)) {
            writer.writeAttribute("class", styleClass.trim(), null);
        }

        if (selectionEnabled) {
            writer.startElement("div", null);
            writer.writeAttribute("class", DataTable.COLUMN_CONTENT_WRAPPER, null);
            encodeColumnSelection(context, table, clientId, column, selected);
            writer.endElement("div");
        } else {
            writer.startElement("div", null);
            writer.writeAttribute("class", DataTable.COLUMN_CONTENT_WRAPPER, null);
            column.encodeAll(context);
            writer.endElement("div");
        }

        writer.endElement("td");
    }

    @Override
    protected void encodePaginatorMarkup(FacesContext context, DataTable table, String position, String tag,
            String styleClass) throws IOException {
        final ResponseWriter writer = context.getResponseWriter();
        if (!table.isPaginatorAlwaysVisible() && table.getPageCount() <= 1) {
            return;
        }

        final String id = table.getClientId(context) + "_paginator_" + position;

        writer.startElement("tr", null);
        writer.startElement(tag, null);
        writer.writeAttribute("id", id, null);
        writer.writeAttribute("class", styleClass, null);

        final Integer rowsCount = getMaximumNumberOfColumns(table);

        if (rowsCount == null || (rowsCount != null && rowsCount < table.getColumnsCount())) {
            writer.writeAttribute("colspan", table.getColumnsCount(), null);
        } else {
            writer.writeAttribute("colspan", rowsCount, null);
        }

        final String[] elements = table.getPaginatorTemplate().split(" ");
        for (final String element : elements) {
            final PaginatorElementRenderer renderer = paginatorElements.get(element);
            if (renderer != null) {
                renderer.render(context, table);
            } else {
                writer.write(element + " ");
            }
        }

        writer.endElement(tag);
        writer.endElement("tr");
    }

    @Override
    protected void encodeRowExpansion(FacesContext context, DataTable table) throws IOException {
        final ResponseWriter writer = context.getResponseWriter();
        final Map<String, String> params = context.getExternalContext().getRequestParameterMap();
        final int expandedRowIndex = Integer.parseInt(params.get(table.getClientId(context) + "_expandedRowIndex"));
        final String rowIndexVar = table.getRowIndexVar();

        table.setRowIndex(expandedRowIndex);

        if (rowIndexVar != null) {
            context.getExternalContext().getRequestMap().put(rowIndexVar, expandedRowIndex);
        }

        writer.startElement("tr", null);
        writer.writeAttribute("style", "display:none", null);
        writer.writeAttribute("class", DataTable.EXPANDED_ROW_CONTENT_CLASS + " ui-widget-content", null);

        writer.startElement("td", null);

        final Integer rowsCount = getMaximumNumberOfColumns(table);

        // Fix the number of columns of the second level with its appropriate
        // number of rows
        if (rowsCount == null || (rowsCount != null && rowsCount < table.getColumnsCount())) {
            writer.writeAttribute("colspan", table.getColumnsCount(), null);
        } else {
            writer.writeAttribute("colspan", rowsCount, null);
        }

        table.getRowExpansion().encodeAll(context);

        writer.endElement("td");

        writer.endElement("tr");

        table.setRowIndex(-1);
    }

    // get the maximum number of rows if the datatable can be expanded
    private Integer getMaximumNumberOfColumns(DataTable table) {
        Integer count = null;
        // If the datatable contains a column group it means it can be expanded
        // and contains 2 levels
        if (table.getChildren().get(0) != null && table.getChildren().get(0) instanceof ColumnGroup) {
            final ColumnGroup columnGroup = (ColumnGroup) table.getChildren().get(0);
            if (columnGroup.getChildren().get(1) != null && columnGroup.getChildren().get(1) instanceof Row) {
                final Row row = (Row) columnGroup.getChildren().get(1);
                if (row.getChildren() != null) {
                    count = row.getChildren().size();
                }
            }
        }
        return count;
    }

そして、これが私のビューに含まれる「dataTable」部分で、オーバーライドされた関数によって処理される動作に適合します。

<p:columnGroup type="header">
                <p:row>
                    <p:column >
                    </p:column>

                    <p:column headerText="#{bundle.form_name}" filterBy="#{item.name}"
                        sortBy="#{item.name}" colspan="3">
                    </p:column>

                    <p:column headerText="#{bundle.form_designation}"
                        style="width:140px;" filterBy="#{item.designation}"
                        sortBy="#{item.designation}" colspan="2">
                    </p:column>

                    <p:column headerText="#{bundle.form_status}"
                        filterBy="#{item.status}"
                        filterOptions="#{itemStatusListBean.options}">
                    </p:column>

                    <p:column headerText="#{bundle.form_date}"
                        filterBy="#{item.statusDate}" sortBy="#{item.statusDate}">
                    </p:column>
                </p:row>

                <p:row>
                    <p:column />
                    <p:column headerText="Status" />
                    <p:column headerText="Type" />
                    <p:column headerText="Marché" />
                    <p:column headerText="Groupe" />
                    <p:column headerText="Produit" />
                    <p:column headerText="Désignation Produit" />
                    <p:column headerText="EAN" />
                </p:row>
            </p:columnGroup>

            <p:column style="width:4%">
                <p:rowToggler/>
            </p:column>

            <p:column colspan="3">
                <h:outputText value="#{item.name}"  />
            </p:column>

            <p:column colspan="2">
                <h:outputText value="#{item.designation}" />
            </p:column>

            <p:column>
                <h:outputText value="#{item.status.label}" />
            </p:column>

            <p:column>
                <h:outputText value="#{item.statusDate}">
                    <f:convertDateTime pattern="dd/MM/yyyy" timeZone="Europe/Paris" />
                </h:outputText>
            </p:column>

            <p:rowExpansion>
            <p:dataTable id="relationDataTable"
            widgetVar="relationDataTable" var="relation"
            value="#{relationDataTableBean.dataModel}"
            rows="10">
                <p:column></p:column>
                <p:column><h:outputText value="#{relation.status}"/></p:column>
                <p:column><h:outputText value="#{relation.type}"/></p:column>
                <p:column><h:outputText value="#{relation.market}"/></p:column>
                <p:column><h:outputText value="#{relation.group}"/></p:column>
                <p:column><h:outputText value="#{relation.produit}"/></p:column>
                <p:column><h:outputText value="#{relation.desiProduit}"/></p:column>
                <p:column><h:outputText value="#{relation.ean}"/></p:column>

            </p:dataTable>

            </p:rowExpansion>

したがって、基本的には、2 番目のレベルからヘッダー列をパックする必要がある最初の行のヘッダー列に colspan 値を配置するだけです。
この場合、「名称」と「名称」を扱う欄を確認してください。

<p:column headerText="#{bundle.form_name}" filterBy="#{item.name}"
                            sortBy="#{item.name}" colspan="3">
                        </p:column>

                        <p:column headerText="#{bundle.form_designation}"
                            style="width:140px;" filterBy="#{item.designation}"
                            sortBy="#{item.designation}" colspan="2">
                        </p:column>

次に、同じ「colspan」属性と値を対応する列インデックスに追加しますが、dataTable 本体 (オブジェクトのデータを表示するための列) に追加します。

        <p:column colspan="3">
            <h:outputText value="#{item.name}"  />
        </p:column>

        <p:column colspan="2">
            <h:outputText value="#{item.designation}" />
        </p:column>

私の実装では、状況によってはいくつかのデフォルトが表示される場合がありますが、ほとんどの場合は正常に機能します。いつか同じ問題が発生した場合に役立つことを願っています。

于 2012-10-11T09:04:14.297 に答える
0

内に<h:panelGrid>ネストされた または別のものを挿入してみてください。<p:dataTable><p:rowExpansion>

テーブル セル内にネストされた (colspan=5 の) 別のテーブルを作成し、ネストされたセルに 8 つの列を配置して、メイン テーブルには 5 つの列のみを残します。

HTML テーブルは、すべての行 (ヘッダーを含む) の中で最大量の列でレンダリングされますhttp://www.w3.org/TR/html401/struct/tables.html#h-11.2.4.3を確認してください

あなたのrowExpansionは次のようになります:

<p:rowExpansion>
<p:dataTable>
    <p:columnGroup>
        <p:row>
            <p:column />
            <p:column headerText="Status" style="width:25px;" />
            <p:column headerText="Type" style="width:25px;" />
            <p:column headerText="Marché" style="width:25px;" />
            <p:column headerText="Groupe" />
            <p:column headerText="Produit" />
            <p:column headerText="Désignation Produit" />
            <p:column headerText="EAN" />
        </p:row>
    </p:columnGroup>
    <p:column></p:column>
    <p:column></p:column>
    <p:column></p:column>
    <p:column></p:column>
    <p:column></p:column>
    <p:column></p:column>
    <p:column></p:column>
</p:dataTable>
</p:rowExpansion>
于 2012-10-10T13:39:18.167 に答える