Updating entire

on complete of

前端 未结 5 1789
旧巷少年郎
旧巷少年郎 2020-11-30 02:01

I am having difficulty re-rendering a PrimeFaces Datatable once a cell has been edited. Changing the value in one cell may change entries in the other cells, hence the need

相关标签:
5条回答
  • 2020-11-30 02:25

    After 5 years, this problem still exists. Unfortunately, while Baukes solution is extremly helpful and includes important insights it's still incomplete, as ltlBeBoy already pointed out in his comment. Subsequent edits without change lead to an inconsistent table state, where no more edits are possible. The reason is, that the oncomplete remote update comes after the edit mode of the new cell is already activated. So the edit mode of the new cell is destroyed by the update. However, the update can't be done in Ajax listener tableBean#onCellEdit, as this would display the table erroneously with one cell only.

    The solution is, to execute the update in the remote commands listener and only, if a change happend. So, in tableBean you implement a programmatic update, a remote listener and a flag that indicates change:

    public static void update(String id) {
       PrimeFaces pf = PrimeFaces.current(); //RequestContext.getCurrentInstance() for <PF 6.2
       if(pf.isAjaxRequest()) pf.ajax().update(id);
    }
    
    /** Whether onCellEdit changed the value */
    boolean onCellEditChange;
    
    public void onCellEditRemote() { 
        if(!onCellEditChange) update("testContainer");
    }
    
    public void onCellEdit(CellEditEvent event) {
        ...  onCellEditChange= /*Change happend*/ ...
    }
    

    The remote command has no update attribute any more:

    <p:remoteCommand name="onCellEdit" actionListener="#{tabelBean.onCellEditRemote}"/>
    
    0 讨论(0)
  • 2020-11-30 02:31

    The BaLusC solution has not worked directly for me. The onCellEdit needs a CellEditEvent as param. My workaround is as following:

    <p:remoteCommand name="onCellEdit" update="testContainer" />
    <p:dataTable ...>
        <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="onCellEdit()" />
        ...
    </p:dataTable>
    
    0 讨论(0)
  • 2020-11-30 02:39

    If none of the solutions worked for you, this worked for me

    <p:dataTable ... id="theId" widgetVar="theWidget" ...>
                    <p:ajax event="rowEdit" listener="#{...}"
                            oncomplete="PF('theWidget').filter()"/> 
    ....
    

    I'm calling the filter method on the PF widget on ajax complete, any method that does a "reload" of the table should work, I used filter because my table had column filters.

    0 讨论(0)
  • 2020-11-30 02:39

    I tested your code. First I moved p:commandButton out of p:outputPanel. Here is modified code:

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

    I think this code doesn't work correctly. if you change anything in table, the p:ajax every time render full table. So, the program load basic data from TableBean constructor and deleted new data.

    basic data

    If I omit your p:ajax code there is not disapears any new data from screen. The refreshButton p:commandButton work correctly.

    When including update=":testForm:testContainer" within the cellEdit AJAX event, changing a cell value deletes the datatable on screen and only renders the cell content (along with the button) -- I do not understand why this is.

    I think it is bad design add update=":testForm:testContainer" to ajax, because it's update your outputPanel more than as exepted (first time work correctly, second time couldn't edit cell, because the program update to many times table).

    I don't know what is your goal. If you want render table without a commandButton, then could you specify one javascript event or p:message and this disappear you can render table.

    I think if you omit update in p:ajax or specify update of one p:message, and move p.commandButton out of testContainer your code start work correctly.

    0 讨论(0)
  • 2020-11-30 02:40

    The rowEdit and cellEdit events does by design inside the table not update/re-render anything else than the current row, even not when explicitly specified in update attribute. It's the consequence of PrimeFaces' a bit overzealous attempt to minimize the response size. This makes sense in most of the cases, but not in specifically your case. It's worth an issue report.

    In the meanwhile, until they fix this behavior, your best bet is using <p:remoteCommand> to invoke the desired listener method and perform a full update of the table.

    Rewrite

    <p:dataTable ...>
        <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update=":testForm:testContainer" />
        ...
    </p:dataTable>
    

    to

    <p:remoteCommand name="onCellEdit" action="#{tableBean.onCellEdit}" update="testContainer" />
    <p:dataTable ...>
        <p:ajax event="cellEdit" oncomplete="onCellEdit()" />
        ...
    </p:dataTable>
    
    0 讨论(0)
提交回复
热议问题