Primefaces checkboxes inside p:dataTable mixed on row deleted

malavock Source

Spring Webflow 2.4.1, Spring 1.1, JSF 2.2.3 and Primefaces 5.1

I have a dataTable for which, in every row, are present 2 boolean checkboxes to modify a field. The user can modify the entries or remove a whole row.

<h:form id="editForm">
<p:dataTable id="permissionTable" var="sdp" rowIndexVar="rowIndex" value="${serverDirectoryPermissions}">                  
<p:column>
   <f:facet name="header">
      <h:outputText value="name" />
   </f:facet>
   <div>
      <h:outputText value="${sdp.name}"/>
   </div>
</p:column>
<p:column>
   <f:facet name="header">
      <h:outputText value="upload permission" />
   </f:facet>
   <div>
      <p:selectBooleanCheckbox id="canUploadCheck" value="${sdp.hasUploadPermission}" />
   </div>
</p:column>
<p:column>
   <f:facet name="header">
      <h:outputText value="delete permission" />
   </f:facet>
   <div>
      <p:selectBooleanCheckbox id="canDeleteCheck" value="${sdp.hasDeletePermission}" />
   </div>
</p:column>
<p:column>
   <f:facet name="header">
      <h:outputText value="&nbsp;&nbsp;" />
   </f:facet>
   <div>
      <p:commandButton id="removePermission" value="${tmsg.messages.sys_button_remove}" action="${documentManager.removeServerDirectoryPermission(serverDirectoryPermissions,sdp)}" ajax="true" process=":editForm" update=":editForm" immediate="true"/>
   </div>
</p:column>
</p:dataTable>
</h:form>

When clicked the remove button fires an action that removes the selected entry from the original list, and then the ajax call refreshes the form (and so the table)

public void removeServerDirectoryPermission(List<ServerDirectoryPermission> sdps, ServerDirectoryPermission sdpToRemove) {
   sdps.remove(sdpToRemove);

}

When the table refreshes, the correct row is removed. The problem is that all the checkboxes below the deleted row take the value of the row that was directly above them.

e.g.

row1 true false row2 false true row3 true true row4 false false

after I delete row2:

row1 true false row3 false true row4 true true

I debugged the back end and the values in the beans for row3 and row4 are not being updated yet, so it's only the GUI that displays the wrong values. Offc ourse if I save the new values are saved.

Am I doing something wrong in the way I delete entries and update the datatable?

For completenes the serverDirectoryPermissions is a list in a flowScope variable and it get persisted in the database when a save button is pressed. The save process works correctly so I omitted the code.

Thanks a lot

>>> EDIT <<<

I added some ids to the Primefaces components and I noticed that when JSF rebuild the table after the Ajax update, all the ids are shifted. So, in the example above:

row1 checkbox_id0 row2 checkbox_id1 row3 checkbox_id2 row4 checkbox_id3

after delete:

row1 checkbox_id0 row3 checkbox_id1 row4 checkbox_id2

As I can verify that the correct row has been deleted from the list, I suspect that JSF is storing the input values by ids. After the row is removed the ids are shift, but JSF ignores this and keeps a map of values based on the original ids. In fact if after this I add a new row, this one is automatically populated with the values of checkbox_id3.

How could I tell JSF that a row has been removed? should I try to manipulate directly the dataTable from the backend?

springjsfprimefaces

Answers

comments powered by Disqus