jsf - example - primefaces showcase
Actualizando toda<p: dataTable> en completo de<p: ajax event="cellEdit"> (4)
Tengo dificultades para volver a generar PrimeFaces Datatable una vez que se ha editado una celda. Cambiar el valor en una celda puede cambiar las entradas en las otras celdas, de ahí la necesidad de actualizar toda la tabla.
Aquí está la página JSF:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{entry.col2}" /></f:facet>
<f:facet name="input"><p:inputText value="#{entry.col2}" /></f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</p:outputPanel>
</h:form>
Y aquí está el bean de respaldo:
@ManagedBean(name = "tableBean", eager = false)
@ViewScoped
public class TableBean {
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void onCellEdit(CellEditEvent event) {
entries.get(event.getRowIndex()).setCol1("Dummy Col 1");
entries.get(event.getRowIndex()).setCol2("Dummy Col 2");
}
}
Al incluir update = ": testForm: testContainer" dentro del evento cellEdit AJAX, al cambiar un valor de celda se borra la tabla de datos en la pantalla y solo se renderiza el contenido de la celda (junto con el botón) - No entiendo por qué ocurre esto. Cuando no se especifica el atributo de actualización, la tabla permanece en la pantalla con la celda activa actualizada, pero ninguna de las otras se actualiza (como era de esperar).
El comportamiento deseado puede lograrse (de forma no automática) al no especificar el atributo de actualización dentro del evento AJAX cellEdit y hacer clic en el botón Volver a mostrar después de editar el valor de una celda. ¿Cómo puedo lograr esto de forma automática y por qué el atributo de actualización no funciona como esperaba?
Estoy usando PrimeFaces 4.0.
La solución BaLusC no ha funcionado directamente para mí. El onCellEdit necesita un CellEditEvent como param. Mi solución es la siguiente:
<p:remoteCommand name="onCellEdit" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
...
</p:dataTable>
Los eventos rowEdit
y cellEdit
, por diseño dentro de la tabla, no actualizan / reproducen nada más que la fila actual, incluso cuando no se especifica explícitamente en el atributo de update
. Es la consecuencia del intento excesivamente entusiasta de PrimeFaces de minimizar el tamaño de la respuesta. Esto tiene sentido en la mayoría de los casos, pero no específicamente en su caso. Vale la pena un informe de problema.
Mientras tanto, hasta que arreglen este comportamiento, lo mejor es usar <p:remoteCommand>
para invocar el método de escucha deseado y realizar una actualización completa de la tabla.
Volver a escribir
<p:dataTable ...>
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
...
</p:dataTable>
a
<p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
<p:dataTable ...>
<p:ajax event="cellEdit" oncomplete="onCellEdit()" />
...
</p:dataTable>
Probé tu código. Primero moví p: commandButton fuera de p: outputPanel. Aquí está el código modificado:
<h:form id="testForm">
<p:outputPanel id="testContainer">
<p:dataTable id="testTable" value="#{tableBean.data}" var="entry" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
(...)
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="testContainer" />
</h:form>
Creo que este código no funciona correctamente. si cambia algo en la tabla, el p: ajax cada vez renderiza la tabla completa. Por lo tanto, el programa carga datos básicos del constructor TableBean y elimina nuevos datos.
Si omito tu código p: ajax, no desaparecerá ningún dato nuevo de la pantalla. El refreshButton
p: commandButton funciona correctamente.
Al incluir update = ": testForm: testContainer" dentro del evento cellEdit AJAX, al cambiar un valor de celda se borra la tabla de datos en la pantalla y solo se renderiza el contenido de la celda (junto con el botón) - No entiendo por qué ocurre esto.
Creo que es un mal diseño agregar update=":testForm:testContainer"
a ajax, porque actualiza su outputPanel más que lo esperado (la primera vez funciona correctamente, la segunda vez no pudo editar la celda, porque la actualización del programa se repite muchas veces en la tabla) .
No sé cuál es tu objetivo. Si quieres renderizar una tabla sin un CommandButton, entonces podrías especificar un evento javascript o un mensaje p: y esto desaparecerá, puedes renderizar la tabla.
Creo que si omite la actualización en p: ajax o especifica la actualización de un p: mensaje, y mueve p.commandButton fuera de testContainer
su código comenzará a funcionar correctamente.
Si ninguna de las soluciones funcionó para usted, esto funcionó para mí
<p:dataTable ... id="theId" widgetVar="theWidget" ...>
<p:ajax event="rowEdit" listener="#{...}"
oncomplete="PF(''theWidget'').filter()"/>
....
Estoy llamando al método de filtro en el widget PF en ajax completo, cualquier método que haga una "recarga" de la tabla debería funcionar, utilicé el filtro porque mi tabla tenía filtros de columna.