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

Question

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 
Was it helpful?

Solution

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.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top