简体   繁体   中英

Datatable does not update after successful ajax call

I have a data table. Each row of the table has a commandButton called 'Remove' , which is supposed to remove that row from the model and the view and perform an update in-place. As a footer, I have another commandButton called 'Remove every row' .

The last button works. I click on it, every row is removed from the model (ie the ArrayList containing the elements becomes empty) and the dataTable and footer facet is re-rendered (or updated) in the view.

On the other hand, when I click a button on one of the rows, to remove it, it partially works. The corresponding element is removed from the model but the view is not updated. That row is still there in the dataTable and the footer facet hasn't changed.

I have the following piece of code in my users.xhtml .

<f:metadata>
    <f:viewParam name="id" value="#{users.id}" />
    <f:event type="preRenderView" listener="#{users.init}" />
</f:metadata>

...

<h:form id="usersForm">
    <p:outputPanel>    
        <p:dataTable id="userTable" value="#{users.user.friendList}" var="friend">
            <p:column>
                <h:outputText value="#{friend.name}" />
            </p:column>
            <p:column>
                <p:commandButton action="#{users.user.removeFriend(friend)}"
                    ajax="true"
                    update="userTable somethingElse" process="@this"
                    onerror="errorDialog.show();"
                    icon="ui-icon-delete"
                    title="delete user">
                </p:commandButton>
            </p:column>

            <f:facet id="somethingElse" name="footer">  
                    aye: ${users.user.xxx}
            </f:facet>
        </p:dataTable>

    </p:outputPanel>

    <p:commandButton action="#{users.user.removeAllFriends()}" ajax="true"
                update="userTable somethingElse"
                process="@this"
                icon="ui-icon-close"
                value="delete all friends?">
    </p:commandButton>


</h:form>

So, what do you think is the problem here?

I'm using JSF 2.0 and Primefaces 3.0

I recognize this problem form one of our current PF 3.0 pages. It will work if you use update="@form" instead. I haven't really had the time to investigate the real cause so that I can report it to the PF guys, because this problem does not manifest in all pages. Even in the same table, a different button works as intented.

Give it a try:

<p:commandButton update="@form" ... />

Update : coming to think about it, it's maybe related to the presence of process="@this" .

You are probably using Primefaces 2.2.1 as this seems like it is due to a common bug with the Primefaces dataTable component. Essentially what occurs is that ajax postbacks occurring from within elements of a dataTable will not result in a partial page update of elements in the dataTable.

The simplest workaround is to invoke a postback from a button outside of the dataTable where its sole purpose is simply to partial page update the dataTable. This is not the most efficient solution as it results in two postbacks, however it does work.

See my previous answer to this problem Here

If you want to use server IDs for updating components (like userTable , somethingElse , ...), these components need to be in the same naming container as the component which triggers the update (your button for example). Otherwise you need to use an expression like this within the update attribute: update=":usersForm:userTable" .

The main problem is to identify the naming containers. The outer button does work, because it is in the same naming container (the form) as the table with the ID userTable . The facet gets updated because the whole table gets updated, but since datatable is a naming container itself, it should not be possible to update the footer by just using update="somethingElse" on the outer button.

I'm not sure, why the inner button does not work. I guess there is another naming container within the datatable. PrimeFaces does log an INFO, if the component could not be found using the findComponent algorithm of the UIComponent implementation. INFO: Cannot find component with identifier "userTable" in view.

This is the solution to refresh in jsf 2.0

<p:dataTable  id="empl1" var="emp" value="#{dtEmployeeView.employee}" selectionMode="multiple"  rowKey="#{emp.id}"
                              paginator="true" rows="5" tableStyleClass="ui-table-columntoggle">
    <p:column width="20" headerText="Id"  priority="1">
        <h:link value="#{emp.id}" />
    </p:column>
    <p:column headerText="Employee Name" priority="2">
        <h:outputText value="#{emp.pname}" />
    </p:column>

</p:dataTable>
<p:commandButton update="form1:empl1" ajax="true" value="Submit" action="#{empService.addEmployee(employee)}" >
    <f:event type="preRenderView" listener="#{dtEmployeeView.init()}"/>
</p:commandButton>

I had filters in my datatable. So here I resolved the problem with

oncomplete="PF('myWidgetVar').filter()" and update="@form"

I was using update="@form" and it didn't completely work: it wasn't updating the number of rows in the dataTable, for instance. What I already had in place was this on the button that updated the form:

process="@this" oncomplete="updateRC();"

and then just below I had:

<p:remoteCommand name="updateRC" process="@this" update="@form" />


What I did to fix the rows update problem is add a styleClass to the dataTable, eg "myTable", and then add a jQuery selector to that class in the above remoteCommand, eg:

<p:remoteCommand name="updateRC" process="@this" update="@form @(.myTable)" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM