How to output data of primefaces DataGrid component by columns instead of by rows (transpose data)?

StackOverflow https://stackoverflow.com/questions/23620513

  •  21-07-2023
  •  | 
  •  

Pergunta

There is a DataGrid component in Primefaces 5.0. It shows input data split by rows. How to show data split by columns?

A B C       A D G
D E F  -->  B E H 
G H         C F 
Foi útil?

Solução

My solution to have transposed data in DataGrid component of Primefaces is to override encodeTable() method of DataGridRenderer class.

@Override
protected void encodeTable(FacesContext context, DataGrid grid) throws IOException {
    ResponseWriter writer = context.getResponseWriter();

    int columns = grid.getColumns();
    int firstRowIndex = grid.getFirst();
    int rowIndex = firstRowIndex;
    int rows = grid.getRows();
    int itemsToRender = rows != 0 ? rows : grid.getRowCount();
    int numberOfRowsToRender = (itemsToRender + columns - 1) / columns;

    String transpose = (String) grid.getAttributes().get("transpose");
    boolean isTranspose = transpose != null ? Boolean.valueOf(transpose) : false;

    writer.startElement("table", grid);
    writer.writeAttribute("class", DataGrid.TABLE_CLASS, null);
    writer.startElement("tbody", null);

    for (int i = 0; i < numberOfRowsToRender; i++) {

        writer.startElement("tr", null);
        writer.writeAttribute("class", DataGrid.TABLE_ROW_CLASS, null);

        for (int j = 0; j < columns; j++) {
            writer.startElement("td", null);
            writer.writeAttribute("class", DataGrid.TABLE_COLUMN_CLASS, null);

            if (isTranspose) {
                writer.writeAttribute("style", String.format("width: %d%%;", 100 / columns), null);
            }

            grid.setRowIndex(isTranspose ? numberOfRowsToRender * j + i + firstRowIndex : rowIndex);

            if (grid.isRowAvailable()) {
                renderChildren(context, grid);
            }
            rowIndex++;

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

    grid.setRowIndex(-1);    //cleanup

    writer.endElement("tbody");
    writer.endElement("table");
}

And register Renderer element within the faces-config.xml:

<render-kit>
    <renderer>
        <component-family>org.primefaces.component</component-family>
        <renderer-type>org.primefaces.component.DataGridRenderer</renderer-type>
        <renderer-class>org.primefaces.component.datagrid.TransposableDataGridRenderer</renderer-class>
    </renderer>
</render-kit>

Now I can specify transposable="true" attribute for <p:dataGrid> tag. The code is also 'fixing' stylesheet to have the same number of columns for every page even if on the last page there is not enough data to cover all columns.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top