tablas registros example dinamicas custom consulta columns column buscar jsf-2 primefaces datatable dynamic-columns

jsf-2 - registros - primefaces datatable dynamic columns



Primefaces columnas estáticas y dinámicas en tabla de datos (2)

Estoy utilizando Primefaces 5.0 para crear una tabla de datos dinámica.

My DataObject tiene algunos campos obligatorios y una Lista de "tupel" opcional (par clave-valor). La lista opcional puede variar en tamaño. Por lo tanto, necesito un mecanismo dinámico para mostrar una lista de DataObject en Primefaces.DataTable.

Mi enfoque se ve así:

public class DataObject { private String staticval1; private String staticval2; private List<Tupel> optionalValues; // .. getter, setter, hashCode, toString..... } public class Tupel{ private String id; private String value; } @ManagedBean @ViewScoped public class TableOverviewBean { private List<DataObject> data; @EJB private IMyDao myDao; @PostConstruct public void init() { data = myDao.findAll(); } public List<DataObject> getData() { return data; } public void setData(List<DataObject> data) { this.data = data; } }

<h:form> <p:dataTable value="#{tableOverviewBean.data}" var="data"> <p:column headerText="static1"> <h:outputText value="#{data.staticval1}" /> </p:column> <p:column headerText="static2"> <h:outputText value="#{data.staticval2}" /> </p:column> <p:columns value="#{data.optionalValues}" var="opt" headerText="#{opt.id}"> <h:outputText value="#{opt.value}" /> </p:columns> </p:dataTable> </h:form>

Pero esto no funciona. Las columnas dinámicas no se representan. ¿Cómo puedo resolver mi problema?

EDITAR: Resultado esperado:

staticval1 | staticval2 | dynamic_id1 | dynamic_id2 | ... | dynmic_idn ---------------------------------------------------------------------- static1a | static2a | dyna_value1a| dyna_value2a | ... | dyna_valu3a static1b | static2b | dyna_value1b| dyna_value2b | ... | dyna_valu3b static1c | static2c | dyna_value1c| dyna_value2c | ... | dyna_valu3c


No es posible definir columnas basadas en datos de fila. Imagine que la fila 1 tiene 2 columnas, la fila 2 tiene 6 columnas, la fila 3 tiene 1 columna, etc. ¿cómo podría alguna vez producir una tabla técnicamente válida en HTML? Cada fila debe tener la misma cantidad de columnas.

Tiene 2 opciones, dependiendo de si puede cambiar el modelo o no:

  1. Si no puede cambiar el modelo, debe reemplazar ese <p:columns> por un único <p:column> y recorrer el #{data.optionalValues} utilizando un bucle anidado con, por ejemplo, <ui:repeat> o tal vez incluso otra <p:dataTable><p:columns> :

    <p:column> <p:dataTable value=""><!-- Empty string as value forces 1 row. --> <p:columns value="#{data.optionalValues}" var="opt" headerText="#{opt.id}"> #{opt.value} </p:columns> </p:dataTable> </p:column>

  2. Si puede cambiar el modelo, debe permitir que <p:columns value> señale una propiedad de bean en lugar de una propiedad de fila, de modo que sea exactamente igual para cada fila. Esto funciona si reemplaza List<Tupel> optionalValues por Map<String, Tupel> optionalValues donde la clave es Tupel#id y agrega una propiedad List<String> al bean que contiene todos los valores de Tupel#id disponibles.

    <p:columns value="#{tableOverviewBean.availableTupelIds}" var="id" headerText="#{id}"> #{data.optionalValues[id].value} </p:columns>


Java:

@Named @ViewScoped public class LiveRangeService implements Serializable { private List< Map<String, ColumnModel> > tableData; private List<ColumnModel> tableHeaderNames; public List<Map<String, ColumnModel>> getTableData() { return tableData; } public List<ColumnModel> getTableHeaderNames() { return tableHeaderNames; } public void PlayListMB() { tableData = new ArrayList< Map<String, ColumnModel> >(); //Generate table header. tableHeaderNames = new ArrayList<ColumnModel>(); for (int j = 0; j < 5; j++) { tableHeaderNames.add(new ColumnModel("header "+j, " col:"+ String.valueOf(j+1))); } //Generate table data. for (int i = 0; i < 10; i++) { Map<String, ColumnModel> playlist = new HashMap<String, ColumnModel>(); for (int j = 0; j < 5; j++) { playlist.put(tableHeaderNames.get(j).key,new ColumnModel(tableHeaderNames.get(j).key,"row:" + String.valueOf(i+1) +" col:"+ String.valueOf(j+1))); } tableData.add(playlist); } } static public class ColumnModel implements Serializable { private String key; private String value; public ColumnModel(String key, String value) { this.key = key; this.value = value; } public String getKey() { return key; } public String getValue() { return value; } }

////////////////////////////////////////////

<h:form> <p:dataTable id="tbl" var="result" value="#{liveRangeService.tableData}" rendered="#{not empty liveRangeService.tableData}" rowIndexVar="rowIndex" > <f:facet name="header"> header table </f:facet> <p:column> <f:facet name="header"> <h:outputText value="序号" /> </f:facet> <h:outputText value="#{rowIndex+1}" /> </p:column> <p:columns value="#{liveRangeService.tableHeaderNames}" var="mycolHeader" columnIndexVar="colIndex"> <f:facet name="header"> <h:outputText value="#{mycolHeader.value}" /> </f:facet> <h:outputText value="#{result[mycolHeader.key].value}" /> <br /> </p:columns> </p:dataTable> </h:form>

Ese es un ejemplo.