Objeto selecionado em DataTable
estava sendo enviado para o servidor como null
O problema que eu estava enfrentando era que quando eu tentava no botão de “deletar” (como mostra na imagem acima), o valor de selectedUserPermission
era definido para o objeto referente a linha na qual eu clicava, devido a seguinte configuração do componente setPropertyActionListener
que adiciona o objeto userPermission
na propriedade selectedUserPermission
no servidor.
<p:commandButton class="ui-button-warning rounded-button" icon="pi pi-trash"
process="@this dt-permission"
oncomplete="PF('deletePermissionDialog').show()">
<f:setPropertyActionListener value="#{userPermission}"
target="#{permissionController.selectedUserPermission}"/>
</p:commandButton>
Note
Além disso é necessário adicionar os seguintes atributos no componente
Data Table
do Primefaces:rowKey="#{userPermission.fiscalCode}" selection="#{permissionController.selectedUserPermission}"
O valor de
rowKey
deve ser uma String para o Primefaces poder recuperar o objeto da linha selecionada emselection
.
Porém ao confirmar a exclusão do registro, clicando em “Sim”, como mostra o dialog abaixo:
O JSF definia o campo selectedUserPermission
para null
no servidor (antes estava com o valor correto).
Código do dialog:
<p:confirmDialog widgetVar="deletePermissionDialog"
showEffect="fade" width="300"
message="Excluir as permissões deste usuário?"
header="Confirmar"
severity="warn"
>
<p:commandButton value="Sim" icon="pi pi-check"
actionListener="#{permissionController.deletePermission()}"
oncomplete="PF('deletePermissionDialog').hide()"/>
<p:commandButton value="Não" type="button"
styleClass="ui-button-secondary" icon="pi pi-times"
onclick="PF('deletePermissionDialog').hide()"/>
</p:confirmDialog>
Como solução foi a adição do atributo process="@this"
no componente commandButton
de confirmação da exclusão, pois dessa forma na requisição AJAX feito pelo botão para o servidor é enviado apenas o estado e a ação do botão. Sem esse atributo, por padrão é enviado todo o estado dos campos presentes na página, incluindo o estado de selectedUserPermission
que estava null
uma vez que as informações da Data Table
são resetadas assim que um nova view é renderizada (no caso o Dialog).
Solução:
@Controller
@Scope("session")
@Data
public class PermissionController {
private ArrayList<CompanyPermissionResponse> permissions;
private CompanyPermissionResponse selectedUserPermission;
// ...
public void deletePermission() {
try {
microserviceCompanyPermission
.deletePermission(
currentCompany.getIdCompany(),
selectedUserPermission.getIdUser()
);
FacesContext
.getCurrentInstance()
.addMessage(
null,
new FacesMessage(
FacesMessage.SEVERITY_INFO,
"Sucesso.", ""
)
);
} catch (Exception e) {
FacesContext
.getCurrentInstance()
.addMessage(
null,
new FacesMessage(
FacesMessage.SEVERITY_ERROR,
"Erro", e.getMessage()
)
);
} finally {
resetFieldsState();
}
}
}
Página XHTML:
<p:dataTable id="dt-permission" widgetVar="dtUsers"
var="userPermission"
value="#{permissionController.permissions}"
reflow="true"
rowKey="#{userPermission.fiscalCode}"
selection="#{permissionController.selectedUserPermission}"
paginator="true" rows="10" paginatorPosition="bottom">
<!-- Outros campos -->
<p:column exportable="false">
<!-- Outras ações -->
<p:commandButton class="ui-button-warning rounded-button" icon="pi pi-trash"
process="@this dt-permission"
oncomplete="PF('deletePermissionDialog').show()">
<f:setPropertyActionListener value="#{userPermission}"
target="#{permissionController.selectedUserPermission}"/>
</p:commandButton>
</p:column>
</p:dataTable>
<!-- Delete Dialog -->
<p:confirmDialog widgetVar="deletePermissionDialog" showEffect="fade" width="300"
message="Excluir as permissões deste usuário?" header="Confirmar" severity="warn">
<p:commandButton value="Sim" icon="pi pi-check"
process="@this"
actionListener="#{permissionController.deletePermission()}"
oncomplete="PF('deletePermissionDialog').hide()"/>
<p:commandButton value="Não" type="button"
styleClass="ui-button-secondary" icon="pi pi-times"
onclick="PF('deletePermissionDialog').hide()"/>
</p:confirmDialog>