[Primefaces] [Datatable] [Form] [CommandButton] ligne sélectionnée null après rafraichissement des données
Bonjour,
voilà j'ai un petit soucis.
J'ai un datatable avec un formulaire, ainsi qu'un bean pour gérer le tout.
Dans ce datatable quand je sélectionne une ligne les données sont propagées dans le formulaire.
Jusque là pas de soucis.
Lorsque je mets à jour certaines données du formulaire et que les sauvegarde, je demande ensuite de recharger les données du datatable, cela se passe sans aucun soucis.
Ensuite lorsque je resélectionne une ligne dans le datatable, cela me jette un NPE. Je mets un breakpoint dans le setter de mon managed bean, je remarque que l'instance du bean représentant la ligne de ma table est null.
Et je ne comprends pas pourquoi. A mon avis je dois avoir oublié quelque chose après le rafraichissement des données.
Voici mes deux compositions ainsi que mon bean
Mon datatable
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui"
xmlns:rich="http://richfaces.org/rich">
<p:dialog modal="true" widgetVar="statusDialog" header="#{messages['MEMBER.DATA.LOADING']}" draggable="false" closable="false">
<p:graphicImage value="/images/ajaxloadingbar.gif" />
</p:dialog>
<p:dataTable id="membersTableId" var="member" value="#{membersTable.members}" filteredValue="#{membersTable.filteredMembers}" widgetVar="membersTableVar" paginator="true" rows="10" tableStyle="width:98%" selectionMode="single" selection="#{membersTable.selectedMember}"
rowKey="#{member}" paginatorPosition="bottom">
<p:ajax event="rowSelect" listener="#{membersTable.onRowSelect}"
update="@([id$=memberFormGrid], [id$=memberAbonnementsTable], [id$=memberCotisationsTable], [id$=memberBenevolatsTable], [id$=memberTravels])" />
<p:column headerText="#{messages['NUMERO.MEMBRE']}">
<h:outputText value="#{member.memberNumber}" />
</p:column>
<p:column headerText="#{messages['NOM']}" filterBy="#{member.name}" filterMatchMode="startsWith" filterFunction="#{membersTable.filterByName}">
<h:outputText value="#{member.name}" />
</p:column>
<p:column headerText="#{messages['PRENOM']}" filterBy="#{member.firstname}" filterMatchMode="startsWith" filterFunction="#{membersTable.filterByFirstName}">
<h:outputText value="#{member.firstname}" />
</p:column>
<p:column headerText="#{messages['ADRESSE']}">
<h:outputText value="#{member.address}" />
</p:column>
<p:column headerText="#{messages['VILLE']}">
<h:outputText value="#{member.postalCode} #{member.city}" />
</p:column>
<p:column headerText="#{messages['TELEPHONE']}">
<h:outputText value="#{member.phone}" />
</p:column>
<f:facet name="footer">
<h:outputText value=" " />
</f:facet>
</p:dataTable>
</ui:composition> |
Mon formulaire
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125
| <ui:composition xmlns="http://www.w3.org/1999/xhtml" xmlns:ui="http://java.sun.com/jsf/facelets" xmlns:f="http://java.sun.com/jsf/core" xmlns:h="http://java.sun.com/jsf/html" xmlns:p="http://primefaces.org/ui">
<p:messages id="displayMemberMessages" showDetail="true" autoUpdate="true" closable="true" />
<p:tooltip />
<h:form id="memberForm">
<p:panelGrid style="width:100%" styleClass="my-panelgrid" id="memberFormGrid">
<p:row>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayLastName" value="#{messages['NOM']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayLastName" required="true" value="#{membersTable.selectedMember.name}" style="width:98%;" maxLength="50">
<f:validateLength maximum="50"></f:validateLength>
</p:inputText>
<p:message for="displayLastName" display="tooltip" />
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayFirstName" value="#{messages['PRENOM']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayFirstName" required="true" value="#{membersTable.selectedMember.firstname}" style="width:98%;" maxLength="50">
<f:validateLength maximum="50"></f:validateLength>
</p:inputText>
<p:message for="displayFirstName" display="tooltip" />
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayBirthDate" value="#{messages['DATE.NAISSANCE']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:calendar id="displayBirthDate" navigator="true" required="true" value="#{membersTable.selectedMember.birthdate}" pattern="dd/MM/yyyy" />
<p:message for="displayBirthDate" display="tooltip" />
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayMemberNumber" value="#{messages['NUMERO.MEMBRE']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayMemberNumber" value="#{membersTable.selectedMember.memberNumber}" size="3" />
</p:column>
</p:row>
<p:row>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayAddress" value="#{messages['ADRESSE']}" />
</p:column>
<p:column colspan="3" style="float:left;border:none;">
<p:inputText id="displayAddress" value="#{membersTable.selectedMember.address}" style="width:98%;" maxLength="120">
<f:validateLength maximum="120"></f:validateLength>
</p:inputText>
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayPostalCode" value="#{messages['CODE.POSTAL']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayPostalCode" value="#{membersTable.selectedMember.postalCode}" size="4" maxLength="4">
<f:validateLength maximum="4"></f:validateLength>
</p:inputText>
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayCity" value="#{messages['VILLE']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayCity" value="#{membersTable.selectedMember.city}" style="width:98%;" maxLength="50">
<f:validateLength maximum="50"></f:validateLength>
</p:inputText>
</p:column>
</p:row>
<p:row>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayEmail" value="#{messages['EMAIL']}" />
</p:column>
<p:column colspan="3" style="float:left;border:none;">
<p:inputText id="displayEmail" value="#{membersTable.selectedMember.email}" style="width:98%;" maxLength="120">
<f:validateLength maximum="120"></f:validateLength>
</p:inputText>
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayPhoneNumber" value="#{messages['TELEPHONE']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayPhoneNumber" value="#{membersTable.selectedMember.phone}">
<f:validateLength maximum="12"></f:validateLength>
</p:inputText>
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayMobilePhone" value="#{messages['GSM']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayMobilePhone" value="#{membersTable.selectedMember.mobilePhone}">
<f:validateLength maximum="13"></f:validateLength>
</p:inputText>
</p:column>
</p:row>
<p:row>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayIdentityCard" value="#{messages['CARTE.IDENTITE']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:inputText id="displayIdentityCard" value="#{membersTable.selectedMember.identityCardNumber}" />
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayIdentityCardValidity" value="#{messages['IDENTITY.VALIDITY']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:calendar id="displayIdentityCardValidity" navigator="true" value="#{membersTable.selectedMember.passportValidity}" pattern="dd/MM/yyyy" />
</p:column>
<p:column style="text-align:right;border:none;">
<p:outputLabel for="displayStudent" value="#{messages['ETUDIANT']}" />
</p:column>
<p:column style="float:left;border:none;">
<p:selectOneRadio id="displayStudent" value="#{membersTable.selectedMember.student}">
<f:selectItem itemLabel="#{messages['OUI']}" itemValue="true" />
<f:selectItem itemLabel="#{messages['NON']}" itemValue="false" />
</p:selectOneRadio>
</p:column>
</p:row>
<f:facet name="footer">
<p:row>
<p:column colspan="8">
<p:commandButton type="button" value="#{messages['AJOUTER.MEMBRE']}" icon="ui-icon-disk" style="margin:5px;" onclick="PF('createMemberDlg').show()" > </p:commandButton>
<p:commandButton type="submit" value="#{messages['EFFACER.MEMBRE']}" icon="ui-icon-trash" style="margin:5px;" ><p:resetInput target="memberFormPanel" /></p:commandButton>
<p:commandButton type="submit" value="#{messages['MODIFY']}" icon="ui-icon-disk" style="margin:5px;" actionListener="#{membersTable.updateMember}" update="@([id$=membersTableId])"></p:commandButton>
</p:column>
</p:row>
</f:facet>
</p:panelGrid>
</h:form>
</ui:composition> |
Et mon bean
Code:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140
| package standardNaast.beans;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Locale;
import javax.annotation.PostConstruct;
import javax.faces.event.ActionEvent;
import javax.faces.view.ViewScoped;
import javax.inject.Inject;
import javax.inject.Named;
import org.apache.commons.lang3.StringUtils;
import org.primefaces.event.SelectEvent;
import standardNaast.entities.Abonnement;
import standardNaast.entities.Benevolat;
import standardNaast.entities.Personne;
import standardNaast.entities.PersonneCotisation;
import standardNaast.service.PersonneService;
@Named(value = "membersTable")
@ViewScoped
public class MembersTableBean implements Serializable {
private static final long serialVersionUID = 9148227569155809725L;
private List<Personne> members = new ArrayList<>();
private List<Personne> filteredMembers = new ArrayList<>();
private Personne selectedMember;
@Inject
private MemberAbonnementBean memberAbonnementBean;
@Inject
private MemberCotisationsBean memberCotisationsBean;
@Inject
private MemberBenevolatBean memberBenevolatBean;
@Inject
private MemberFormBean memberForm;
@Inject
private PersonneService personneService;
@Inject
private MemberTravelsBean memberTravelsBean;
@PostConstruct
public void init() {
final List<Personne> findAllPerson = this.personneService
.findAllPerson(false);
Collections.sort(findAllPerson);
this.members = findAllPerson;
this.filteredMembers = findAllPerson;
}
public List<Personne> getMembers() {
return this.members;
}
public void setMembers(final List<Personne> members) {
this.members = members;
}
public List<Personne> getFilteredMembers() {
return this.filteredMembers;
}
public void setFilteredMembers(final List<Personne> filteredMembers) {
this.filteredMembers = filteredMembers;
}
public Personne getSelectedMember() {
return this.selectedMember;
}
public void setSelectedMember(final Personne selectedMember) {
this.selectedMember = selectedMember;
}
public void onRowSelect(final SelectEvent event) {
this.memberForm.setUpdate(true);
this.memberForm.setSelectedPerson(this.getSelectedMember());
final Personne person = this.personneService.getPerson(this
.getSelectedMember().getPersonneId());
final List<Abonnement> abonnementList = person.getAbonnementList();
final List<Benevolat> benevolatList = person.getBenevolatList();
final List<PersonneCotisation> personnesCotisations = person
.getPersonnesCotisations();
this.memberAbonnementBean.setAbonnements(abonnementList);
this.memberCotisationsBean.setCotisations(personnesCotisations);
this.memberBenevolatBean.setBenevolats(benevolatList);
this.memberTravelsBean.setSelectedMember(this.getSelectedMember());
this.memberTravelsBean.setSelectedSeason("");
this.memberTravelsBean.setSeasonTravels();
}
public boolean filterByName(final Object value, final Object filter,
final Locale locale) {
return this.filter(value, filter, locale);
}
public boolean filterByFirstName(final Object value, final Object filter,
final Locale locale) {
return this.filter(value, filter, locale);
}
public boolean filter(final Object value, final Object filter,
final Locale locale) {
final String filterText = (filter == null) ? null : filter.toString()
.trim();
if (StringUtils.isBlank(filterText)) {
return true;
}
if (value == null) {
return false;
}
final String name = value.toString();
if (StringUtils.containsIgnoreCase(name, filterText)) {
return true;
} else {
return false;
}
}
public void updateMember(final ActionEvent event) {
this.personneService.savePerson(this.selectedMember);
this.init();
}
} |
Le NPE survient dans la méthode onRowSelect(). La variable selectedMember est null. Pourtant lors de la sélection de la ligne dans ma table, je passe bien via le setSelectedMember mais le paramètre est null. :calim2:
Merci pour votre aide.