Actualización completa en completa de


Estoy teniendo dificultades para volver a renderizar un 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 de 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 frijol 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");        
    }   
}

Cuando se incluye update=":testForm:testContainer" dentro del evento cellEdit AJAX, cambiar un valor de celda elimina la datatable en la pantalla y solo renderiza el contenido de la celda (junto con button) not No entiendo por qué es esto. Cuando no se especifica el atributo update, la tabla permanece en pantalla con la celda activa actualizada, pero ninguna de las otras celdas se actualiza (como era de esperar).

El comportamiento deseado se puede lograr (de una manera no automatizada) no especificando el atributo update dentro del evento AJAX cellEdit y haciendo clic en el botón Redisplay después de editar el valor de una celda. ¿Cómo puedo lograr esto de una manera automatizada, y por qué el atributo update no funciona como esperaba?

Estoy usando PrimeFaces 4.0.

Author: BalusC, 2013-10-23

4 answers

Los eventos rowEdit y cellEdit no actualizan/vuelven a representar nada más que la fila actual, incluso cuando se especifica explícitamente en el atributo update. Es la consecuencia del intento demasiado 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.

Mientras tanto, hasta que arreglen este comportamiento, lo mejor es usar <p:remoteCommand> para invocar al oyente deseado método y realizar una actualización completa de la tabla.

Reescribir

<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>
 54
Author: BalusC,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-12 11:10:48

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>
 20
Author: Tim Long,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-07 14:59:28

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 filter en el widget PF en ajax complete, cualquier método que haga una "recarga" de la tabla debería funcionar, usé filter porque mi tabla tenía filtros de columna.

 5
Author: Lance Reid,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2016-06-15 13:42:53

He probado 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 de TableBean constructor y elimina nuevos datos.

datos básicos

Si omito su código p:ajax no desaparecerá ningún dato nuevo de la pantalla. El botón de comando refreshButton p:funciona correctamente.

Al incluir update=": testForm: testContainer " dentro de la Celleditar AJAX evento, cambiar un valor de celda elimina la datatable en la pantalla y solo renderiza el contenido de la celda (junto con el botón) not No entiende por qué es esto.

Creo que es un mal diseño agregar update=":testForm:testContainer" a ajax, porque es actualizar su outputPanel más que como exepted (primera vez funciona correctamente, segunda vez no pudo editar la celda, porque el programa actualizar a la tabla de muchas veces).

No se cual es tu meta. Si desea renderizar la tabla sin un botón de comando, entonces podría especificar un evento javascript o p: mensaje y esto desaparecerá puede renderizar la tabla.

Creo que si omites update en p:ajax o especificas update de un mensaje p:, y mueves p. commandButton fuera de testContainer tu código empieza a funcionar correctamente.

 0
Author: herry,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2013-11-02 12:09:44