How to partially split each row of a Primefaces datatable?

1k Views Asked by At

The problem I have is the following:

I have a datatable with a list of the class Producto, which internally consists of several fields of simple type and 2 objects of type Proveedor. Categoria and TipoProveedor are enums.

public class Producto {
    
    private int idProducto;
    private String nombre;
    private Categoria categoria;
    private Proveedor proveedorUno;
    private Proveedor proveedorDos;
    
}


public class Proveedor {

    private int idProveedor;
    private TipoProveedor tipoProveedor;
    private String nombre;
    private BigDecimal precio;
    
}

My problem is that in each row of the datatable all the information must be displayed so that if a single filled provider comes, it will be displayed normal but if both fillings come, the part of the provider information is divided into 2 rows. Example:

|------------------------------------------------------------------|
| Nombre | Categoria | idProveedor | Nombre Proveedor    | Precio  |
|------------------------------------------------------------------|
| DIN-A4 | Papel     | 10256       | Proveedor Manolito  | 10.59 € |
|        |           | 24747       | Proveedor Fulanito  | 10.75 € |
|------------------------------------------------------------------|
| DIN-A5 | Papel     | 10256       | Proveedor Menganito | 4.77 €  |
|------------------------------------------------------------------|
| DIN-A3 | Papel     | 44787       | Proveedor Saturnino | 14.77 € |
|------------------------------------------------------------------|

I had tried to do it with a datatable like this but it does not look exactly as I need:

<p:dataTable id="listadoProductos" widgetVar="listadoProductos" 
        value="#{listadoProductosBean.listadoProductos}" var="producto"
        emptyMessage="#{messages['tabla.VACIA']}">
        
        <p:column headerText="#{messages['listado.NOMBRE']}">
            <h:outputText value="#{producto.nombre}" />
        </p:column>
        <p:column headerText="#{messages['listado.CATEGORIA']}">
            <h:outputText value="#{producto.categoria.desc}" />
        </p:column>
        <p:column headerText="#{messages['listado.ID_PROVEEDOR']}" 
            rendered="#{producto.proveedorUno != null && producto.proveedorDos != null}">
            <p:panelGrid columns="1">
                <p:row>
                    <h:outputText value="#{producto.proveedorUno.idProveedor}" />
                </p:row>
                <p:row>
                    <h:outputText value="#{producto.proveedorDos.idProveedor}" />
                </p:row>
            </p:panelGrid>
            
        </p:column>
        <p:column headerText="#{messages['listado.ID_PROVEEDOR']}" 
            rendered="#{producto.proveedorUno != null && producto.proveedorDos == null}">
            <p:panelGrid columns="1">
                <p:row>
                    <h:outputText value="#{producto.proveedorUno.idProveedor}" />
                </p:row>
            </p:panelGrid>
            
        </p:column>
        <p:column headerText="#{messages['listado.ID_PROVEEDOR']}" 
            rendered="#{producto.proveedorUno == null && producto.proveedorDos != null}">
            <p:panelGrid columns="1">
                <p:row>
                    <h:outputText value="#{producto.proveedorDos.idProveedor}" />
                </p:row>
            </p:panelGrid>
            
        </p:column>
        
    </p:dataTable>

Is it possible to do what I say?

My version of Primefaces is 6.2 but I could upgrade if I can get what I want.

Many Thanks.

NOTE: it could be worth it (although it is not desired) that the part of the providers divided into 2 appears even if there is only one. Example:

|------------------------------------------------------------------|
| Nombre | Categoria | idProveedor | Nombre Proveedor    | precio  |
|------------------------------------------------------------------|
| DIN-A4 | Papel     | 10256       | Proveedor Manolito  | 10.59 € |
|        |           | 24747       | Proveedor Fulanito  | 10.75 € |
|------------------------------------------------------------------|
| DIN-A5 | Papel     | 10256       | Proveedor Menganito | 4.77 €  |
|        |           |             |                     |         |
|------------------------------------------------------------------|
| DIN-A3 | Papel     | 44787       | Proveedor Saturnino | 14.77 € |
|        |           |             |                     |         |
|------------------------------------------------------------------|
1

There are 1 best solutions below

3
On

You can use the groupRow attribute on the columns you want to group, so:

<p:column headerText="#{messages['listado.NOMBRE']}" groupRow="true">
    <h:outputText value="#{producto.nombre}" />
</p:column>
<p:column headerText="#{messages['listado.ID_PROVEEDOR']}">
    <h:outputText value="#{producto.proveedorUno.idProveedor}" />
</p:column>

See:

To use a fixed row height, give your table a styleClass and style the table cells to have a min-height using CSS.

See: