I didn't found a good answer so this problem. Maybe I just need to understand how to handle it. I implemented via contextMenu a menuItem to delete selected rows. That doesn't work anymore. Furthermore the editing does not working anymore. I have implemented a row editor. When I click on it, it gets activated and i can start editing but when I press okay or abort nothing happens.
No method is getting called. Not for deleting, not for editing, not even for selecting. It has obviously something to do with the lazyDataModel but how can I change it.
My Controller:
#Scope(value = "session")
#Component(value = "telefonbuchList")
#ELBeanName(value = "telefonbuchList")
#Join(path = "/", to = "/eintraege-liste.jsf")
public class TelefonbuchListController extends LazyDataModel<Telefonbuch> {
private static final long serialVersionUID = 1L;
#Autowired
private TelefonbuchRepository telefonbuchRepository;
private List<Telefonbuch> selectedEntries;
private LazyDataModel<Telefonbuch> lazyModel;
private int pageSize = 5;
public void deleteEntry() {
telefonbuchRepository.deleteAll(selectedEntries);
lazyModel.getWrappedData().removeAll(selectedEntries);
selectedEntries.clear();
}
public LazyDataModel<Telefonbuch> getLazyModel() {
return lazyModel;
}
#Override
public int getPageSize() {
return pageSize;
}
#Override
public Telefonbuch getRowData(String rowKey) {
List<Telefonbuch> list = getWrappedData();
for (Telefonbuch telefonbuch : list) {
if (telefonbuch.getId().toString().equals(rowKey)) {
return telefonbuch;
}
}
return null;
}
#Override
public Object getRowKey(Telefonbuch telefonbuch) {
return telefonbuch != null ? telefonbuch.getId() : null;
}
public List<Telefonbuch> getSelectedEntries() {
return selectedEntries;
}
#Deferred
#RequestAction
#IgnorePostback
public void loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
private static final long serialVersionUID = 1L;
#Override
public List<Telefonbuch> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
List<Telefonbuch> result = new ArrayList<Telefonbuch>();
if (first == 0) {
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
} else {
first = first / pageSize;
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
}
return result;
}
};
lazyModel.setRowCount((int) telefonbuchRepository.count());
lazyModel.setPageSize(pageSize);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
telefonbuchRepository.save((Telefonbuch) newValue);
}
public void onRowCancel(RowEditEvent event) {
}
public void onRowEdit(RowEditEvent event) {
Object oldValue = event.getObject();
telefonbuchRepository.save((Telefonbuch) oldValue);
FacesMessage msg = new FacesMessage("Eintrag geändert",
((Telefonbuch) event.getObject()).getVorname() + " " + ((Telefonbuch) event.getObject()).getNachname());
FacesContext.getCurrentInstance().addMessage("eintraege-list", msg);
}
#Override
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setSelectedEntries(List<Telefonbuch> selectedEntries) {
this.selectedEntries = selectedEntries;
}
The .xhtml:
<h:form id="eintraegeList">
<p:panel header="Liste aller Einträge">
<p:dataTable id="table" var="telefonbuch" lazy="true" widgetVar="tableWv" value="#{telefonbuchList.lazyModel}" stickyHeader="true" editable="true" resizableColumns="true" liveResize="true" style="margin-bottom:20px" paginator="true" rows="#{telefonbuchList.pageSize}" dynamic="true" emptyMessage="Keine Telefonbucheinträge vorhanden" selection="#{telefonbuchList.selectedEntries}" selectionMode="multiple" rowKey="#{telefonbuch.id}"
currentPageReportTemplate="{startRecord}-{endRecord} von {totalRecords}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink} {Exporters}"
rowsPerPageTemplate="5,8,10">
<f:facet name="header">
<p:commandButton id="toggler" type="button" value="Anzeige" style="float:right" icon="pi pi-align-justify" />
<p:columnToggler datasource="table" trigger="toggler" />
</f:facet>
<p:ajax event="rowEdit" listener="#{telefonbuchList.onRowEdit}" update="table" />
<p:ajax event="rowEditCancel" listener="#{telefonbuchList.onRowCancel}" update="table" />
<p:ajax event="cellEdit" listener="#{telefonbuchList.onCellEdit}" update="table" />
<p:separator />
<p:column headerText="ID" sortBy="#{telefonbuch.id}">
<h:outputText value="#{telefonbuch.id}" />
</p:column>
<p:column headerText="Vorname" sortBy="#{telefonbuch.vorname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.vorname}" /></f:facet>
<f:facet name="input"><p:inputText id="vornameInput" value="#{telefonbuch.vorname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Nachname" sortBy="#{telefonbuch.nachname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.nachname}" /></f:facet>
<f:facet name="input"><p:inputText id="nachnameInput" value="#{telefonbuch.nachname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Telefonnummer" sortBy="#{telefonbuch.telefonnummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.telefonnummer}" /></f:facet>
<f:facet name="input"><p:inputText id="telefonnummerInput" value="#{telefonbuch.telefonnummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Handynummer" sortBy="#{telefonbuch.handynummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.handynummer}" /></f:facet>
<f:facet name="input"><p:inputText id="handynummerInput" value="#{telefonbuch.handynummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschäftsstelle" sortBy="#{telefonbuch.geschaeftsstelle}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.geschaeftsstelle}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{telefonbuch.geschaeftsstelle}" style="width:100%">
<f:selectItems value="#{telefonbuchController.geschaeftsstellen}" var="c" itemLabel="#{geschaeftsstelle}" itemValue="#{geschaeftsstelle}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschlecht" sortBy="#{telefonbuch.gender.shortGender}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.gender.shortGender}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu id="gender" value="#{telefonbuch.gender}" style="width:100%">
<f:selectItem itemLabel="Keine Angabe" itemValue="" />
<f:selectItems value="#{telefonbuch.genders}" var="gender" itemLabel="#{gender.shortGender}" itemValue="#{gender}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:20px;text-align:center;">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:growl id="growl" showDetail="true" for="eintraege-list">
<p:autoUpdate />
</p:growl>
<p:separator />
<p:contextMenu for="table">
<h:outputStylesheet library="webjars" name="font-awesome/5.7.1/css/fontawesome.min-jsf.css" />
<p:menuitem value="Löschen" update="table" icon="fas fa-eraser" action="#{telefonbuchList.deleteEntry}"/>
<p:menuitem value="Edit Cell" icon="pi pi-search" onclick="PF('tableWv').showCellEditor();return false;"/>
</p:contextMenu>
<h3>Exportieren der Daten</h3>
<h:commandLink>
<p:graphicImage value="/img/icon-pdf.png" />
<p:dataExporter type="pdf" target="table" fileName="Telefonbuch" />
</h:commandLink>
</p:panel>
</h:form>
Model (Telefonbuch):
public enum Gender {
MALE("Männlich"), FEMALE("Weiblich");
private String shortGender;
private Gender(String shortGender) {
this.shortGender = shortGender;
}
public String getShortGender() {
return shortGender;
}
}
#Column
#Enumerated(EnumType.STRING)
private Gender gender;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String vorname;
#Column
private String nachname;
#Column
private String telefonnummer;
#Column
private String handynummer;
#Column
private String geschaeftsstelle;
PrimeFaces Version 6.2
JSF MyFaces Version 2.2.12
Java 1.8
Spring Boot 2.1.2
Related
I tried many things know. This thread is related to another thread but now the problem is more specific. I found out that the methods getRowData() and also if I implement it getRowKey() don't get called.
What I've tried:
In my .xhtml I set the rowKey and it's fine. No Compiler Error. In the Controller I write down the getRowData(). I try to select something and this breaks the whole page. The setter doesn't get called. If I don't overwrite getRowData() the compiler still works.
When I try to implement getRowKey() and getRowData() in my Controller it tells me ... exception [getRowKey(T object) must be implemented by ...
Then I tried to implement SelectableDataModel to look if there is any difference but there's not.
When I delete the selectionMode so the whole selection everything is fine. Pagination works great. Also editing columns works. But my contextMenu which is needed to delete an entry does not work.
xhtml:
<h:form id="eintraegeList">
<p:panel header="Liste aller Einträge">
<p:dataTable id="table"
var="telefonbuch"
lazy="true"
widgetVar="tableWv"
value="#{telefonbuchList.lazyModel}"
editable="true"
resizableColumns="true"
liveResize="true"
style="margin-bottom:20px"
paginator="true"
rows="#{telefonbuchList.pageSize}"
emptyMessage="Keine Telefonbucheinträge vorhanden"
selectionMode="single"
selection="#{telefonbuchList.selectedEntry}"
rowKey="#{telefonbuch.id}"
currentPageReportTemplate="{startRecord}-{endRecord} von {totalRecords}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,8,10">
<f:facet name="header">
<p:commandButton id="toggler" type="button" value="Anzeige" style="float:right" icon="pi pi-align-justify" />
<p:columnToggler datasource="table" trigger="toggler" />
</f:facet>
<p:ajax event="rowEdit" listener="#{telefonbuchList.onRowEdit}" update="table" />
<p:ajax event="rowEditCancel" listener="#{telefonbuchList.onRowCancel}" update="table" />
<p:ajax event="cellEdit" listener="#{telefonbuchList.onCellEdit}" update="table" />
<p:ajax event="rowSelect" listener="#{telefonbuchList.onRowSelect}" update="table" />
<p:separator />
<p:column headerText="ID" sortBy="#{telefonbuch.id}">
<h:outputText value="#{telefonbuch.id}" />
</p:column>
<p:column headerText="Vorname" sortBy="#{telefonbuch.vorname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.vorname}" /></f:facet>
<f:facet name="input"><p:inputText id="vornameInput" value="#{telefonbuch.vorname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Nachname" sortBy="#{telefonbuch.nachname}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.nachname}" /></f:facet>
<f:facet name="input"><p:inputText id="nachnameInput" value="#{telefonbuch.nachname}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Telefonnummer" sortBy="#{telefonbuch.telefonnummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.telefonnummer}" /></f:facet>
<f:facet name="input"><p:inputText id="telefonnummerInput" value="#{telefonbuch.telefonnummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Handynummer" sortBy="#{telefonbuch.handynummer}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.handynummer}" /></f:facet>
<f:facet name="input"><p:inputText id="handynummerInput" value="#{telefonbuch.handynummer}" style="width:100%"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschäftsstelle" sortBy="#{telefonbuch.geschaeftsstelle}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.geschaeftsstelle}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu value="#{telefonbuch.geschaeftsstelle}" style="width:100%">
<f:selectItems value="#{telefonbuchController.geschaeftsstellen}" var="c" itemLabel="#{geschaeftsstelle}" itemValue="#{geschaeftsstelle}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Geschlecht" sortBy="#{telefonbuch.gender.shortGender}">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{telefonbuch.gender.shortGender}" /></f:facet>
<f:facet name="input">
<p:selectOneMenu id="gender" value="#{telefonbuch.gender}" style="width:100%">
<f:selectItem itemLabel="Keine Angabe" itemValue="" />
<f:selectItems value="#{telefonbuch.genders}" var="gender" itemLabel="#{gender.shortGender}" itemValue="#{gender}"/>
</p:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column exportable="false" style="width:20px;text-align:center;">
<p:rowEditor />
</p:column>
</p:dataTable>
<p:growl id="growl" showDetail="true" for="eintraege-list">
<p:autoUpdate />
</p:growl>
<p:separator />
<p:contextMenu for="table">
<p:menuitem value="Löschen" update="table" icon="fas fa-eraser" action="#{telefonbuchList.deleteEntry}"/>
<p:menuitem value="Edit Cell" icon="pi pi-search" onclick="PF('tableWv').showCellEditor();return false;"/>
</p:contextMenu>
</p:panel>
</h:form>
Controller:
#Scope(value = "session")
#Component(value = "telefonbuchList")
#ELBeanName(value = "telefonbuchList")
#Join(path = "/", to = "/eintraege-liste.jsf")
public class TelefonbuchListController extends LazyDataModel<Telefonbuch> {
private static final long serialVersionUID = 1L;
#Autowired
private TelefonbuchRepository telefonbuchRepository;
private List<Telefonbuch> selectedEntries;
private Telefonbuch selectedEntry;
private LazyDataModel<Telefonbuch> lazyModel;
private int pageSize = 5;
public void deleteEntry() {
telefonbuchRepository.deleteAll(selectedEntries);
lazyModel.getWrappedData().removeAll(selectedEntries);
selectedEntries.clear();
}
public LazyDataModel<Telefonbuch> getLazyModel() {
return lazyModel;
}
#Override
public int getPageSize() {
return pageSize;
}
#Override
public Telefonbuch getRowData(String rowKey) {
System.out.println("rowKey: " + rowKey);
List<Telefonbuch> list = getWrappedData();
for (Telefonbuch telefonbuch : list) {
if (telefonbuch.getId().toString().equals(rowKey)) {
return telefonbuch;
}
}
return null;
}
#Override
public Object getRowKey(Telefonbuch telefonbuch) {
return telefonbuch != null ? telefonbuch.getId() : null;
}
public List<Telefonbuch> getSelectedEntries() {
return selectedEntries;
}
public Telefonbuch getSelectedEntry() {
return selectedEntry;
}
#Deferred
#RequestAction
#IgnorePostback
public void loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
private static final long serialVersionUID = 1L;
#Override
public List<Telefonbuch> load(int first, int pageSize, String sortField, SortOrder sortOrder,
Map<String, Object> filters) {
List<Telefonbuch> result = new ArrayList<Telefonbuch>();
if (first == 0) {
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
} else {
first = first / pageSize;
if (sortField != null && !sortField.isEmpty()) {
if (sortOrder.name().equalsIgnoreCase("ascending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).ascending()))
.getContent();
} else if (sortOrder.name().equalsIgnoreCase("descending")) {
result = telefonbuchRepository
.findAll(PageRequest.of(first, pageSize, Sort.by(sortField).descending()))
.getContent();
}
} else {
result = telefonbuchRepository.findAll(PageRequest.of(first, pageSize)).getContent();
}
}
return result;
}
};
lazyModel.setRowCount((int) telefonbuchRepository.count()); // Aufruf auslagern, aber bei gemeinsamen Arbeiten kann neue Row hinzukommen
lazyModel.setPageSize(pageSize);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
telefonbuchRepository.save((Telefonbuch) newValue);
}
public void onRowEdit(RowEditEvent event) {
Object oldValue = event.getObject();
telefonbuchRepository.save((Telefonbuch) oldValue);
FacesMessage msg = new FacesMessage("Eintrag geändert",
((Telefonbuch) event.getObject()).getVorname() + " " + ((Telefonbuch) event.getObject()).getNachname());
FacesContext.getCurrentInstance().addMessage("eintraege-list", msg);
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("Eintrag ausgewählt",
((Telefonbuch) event.getObject()).getVorname() + " " + ((Telefonbuch) event.getObject()).getNachname());
FacesContext.getCurrentInstance().addMessage("eintraege-list", msg);
}
#Override
public void setPageSize(int pageSize) {
this.pageSize = pageSize;
}
public void setSelectedEntries(List<Telefonbuch> selectedEntries) {
this.selectedEntries = selectedEntries;
}
public void setSelectedEntry(Telefonbuch selectedEntry) {
this.selectedEntry = selectedEntry;
}
Model:
#Data
#Entity
public class Telefonbuch {
public enum Gender {
MALE("Männlich"), FEMALE("Weiblich");
private String shortGender;
private Gender(String shortGender) {
this.shortGender = shortGender;
}
public String getShortGender() {
return shortGender;
}
}
#Column
#Enumerated(EnumType.STRING)
private Gender gender;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column
private String vorname;
#Column
private String nachname;
#Column
private String telefonnummer;
#Column
private String handynummer;
#Column
private String geschaeftsstelle;
protected Telefonbuch() {
}
public Telefonbuch(String vorname, String nachname, String telefonnummer, String handynummer) {
this.vorname = vorname;
this.nachname = nachname;
this.telefonnummer = telefonnummer;
this.handynummer = handynummer;
}
PrimeFaces Version 6.2
JSF MyFaces Version 2.2.12
Java 1.8
Spring Boot 2.1.3
In your method
TelefonbuchListController.loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
//...
}
you create a new anonymous instance of the abstract class LazyDataModel. This is then assigned to the lazyModel field which is later returned to your p:dataTable value attribute.
Obviously it does not override the non operative getRowKey nor getRowData methods from the abstract class LazyDataModel.
You will have to override them like this:
public void loadData() {
lazyModel = new LazyDataModel<Telefonbuch>() {
// ...
#Override
public Telefonbuch getRowData(String rowKey) {
// your implementation here
}
#Override
public Object getRowKey(Telefonbuch telefonbuch) {
// your implementation here
}
// ...
}
Both methods getRowKey and getRowData you presented in your questions belong to a LazyDataModel implementaion that is not assigned to the p:dataTable value attribute. Hence both never get invoked. If it was the LazyDataModel assigned to the p:dataTable value attribute, your p:dataTable would probably look somehow like this:
<p:dataTable id="table"
var="telefonbuch"
lazy="true"
widgetVar="tableWv"
value="#{telefonbuchList}"
...
I'm putting the currently iterated dataTable as a property of a managed bean using .Here I want to take one localproduct and send it to the dialog to change the values. But I did not add the code for that due to my setListener does not work and it does not set or it sets to null. However, it is always set it as null. Can selection mode kill the setPropertyActionListener?
The view, local-product.xhtml:
<ui:define name="content">
<h:form prependId="false" style="margin-top: 25px" id="form">
<p:dataTable id="tableData" value="#{localProductUI.localProductLazyModel}" var="localProduct" style="max-width: 1200px; margin-top: 20px;" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="20,100,200,500" rows="20" lazy="true" rowIndexVar="row" editable="true" editMode="cell"
widgetVar="productTable" reflow="true" selection="#{localProductUI.selectedNewLocalProduct}" rowKey="#{localProduct.id}" rowSelectMode="checkbox">
<f:facet name="header">
<h:outputText value="Number of products: #{localProductUI.countProduct}" id="card-count"/>
</f:facet>
<p:column selectionMode="multiple" filterValue="" style="width: 20px"/>
<p:column headerText="Id" sortBy="#{localProduct.id}">
#{localProduct.id}
</p:column>
<p:column headerText="Name" filterBy="#{localProduct.name}" style="white-space: normal;">
#{localProduct.name}
</p:column>
<p:column headerText="Code" sortBy="#{localProduct.code}" filterBy="#{localProduct.code}">
#{localProduct.code}
</p:column>
<p:column headerText="Category" filterBy="#{localProduct.categoryId}" style="white-space: normal;">
#{localProduct.categoryId}
</p:column>
<p:column headerText="APrice" sortBy="#{localProduct.arrivalCost}">
#{util.fDouble(localProduct.arrivalCost)}
</p:column>
<p:column headerText="SPrice" sortBy="#{localProduct.sellingPrice}">
#{util.fDouble(localProduct.sellingPrice)}
</p:column>
<p:column headerText="Change">
<p:commandButton value="Change" update=":productDetail" onclick="PF('productDialog').show();"
action="#{localProductUI.editNewLocalProduct}" >
<f:setPropertyActionListener target="#{localProductUI.newLocalProduct}" value="#{localProduct}" />
</p:commandButton>
</p:column>
</p:dataTable>
<p:dialog header = "Change product" widgetVar="productDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false">
<p:outputPanel id="productDetail" style="text-align: center">
<p:panelGrid columns="2" rendered="#{not empty localProductUI.newLocalProduct}" columnClasses="label,value">
<h:outputText value="Name:"/>
<h:outputText value="#{localProductUI.newLocalProduct.name}"/>
<h:outputText value="Code:"/>
<h:outputText value="#{localProductUI.newLocalProduct.code}"/>
<h:outputText value="Category:"/>
<h:outputText value="#{localProductUI.newLocalProduct.categoryId}"/>
<h:outputText value="APrice:"/>
<h:outputText value="#{localProductUI.newLocalProduct.arrivalCost}"/>
<h:outputText value="SPrice:"/>
<h:outputText value="#{localProductUI.newLocalProduct.sellingPrice}"/>
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</h:form>
</ui:define>
</ui:composition>
The managed bean, LocalProductUI:
public class LocalProductUI implements Serializable {
/*
* Consts
*/
private static final Logger log = Logger.getLogger(LocalProductUI.class.getName());
/*
* EJB
*/
#EJB private NewLocalProductEJB newLocalProductEJB;
/*
* Fields
*/
private LazyDataModel<NewLocalProduct> localProductLazyModel;
private Integer countProduct;
private List<NewLocalProduct> selectedNewLocalProduct;
private NewLocalProduct newLocalProduct;
/*
* Init
*/
public void init() {
this.localProductLazyModel = new LazyDataModel<NewLocalProduct>() {
#Override
public List<NewLocalProduct> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String, Object> filters) {
localProductLazyModel.setRowCount(newLocalProductEJB.countNewLocalProducts(filters));
countProduct = newLocalProductEJB.countNewLocalProducts(filters);
Boolean sortAsc = sortOrder == null ? null : sortOrder == SortOrder.ASCENDING;
return newLocalProductEJB.getNewLocalProductList(first, pageSize, sortField, sortAsc, filters);
}
#Override
public NewLocalProduct getRowData(String rowKey) {
int id;
try {
id = new Integer(rowKey);
} catch (NumberFormatException e) {
throw new Error(e);
}
return newLocalProductEJB.findById(id);
}
#Override
public Object getRowKey(NewLocalProduct product) {
return product.getId();
}
#Override
public void setRowIndex(int rowIndex) {
if (rowIndex == -1 || getPageSize() == 0) {
super.setRowIndex(-1);
} else {
super.setRowIndex(rowIndex % getPageSize());
}
}
};
localProductLazyModel.setRowCount(newLocalProductEJB.countNewLocalProducts(new HashMap<String, Object>()));
}
/*
* Actions
*/
public void saveToGlobalProduct() throws InputValidationException {
newLocalProductEJB.doSave(selectedNewLocalProduct);
FacesMessage msg = new FacesMessage("Number of local products added: "+ selectedNewLocalProduct.size());
FacesContext.getCurrentInstance().addMessage(null,msg);
}
public void editNewLocalProduct(){
System.err.println("Change here!");
}
public void removeProduct() throws InputValidationException {
newLocalProductEJB.doRemove(selectedNewLocalProduct);
FacesMessage msg = new FacesMessage("Number of local products deleted: "+ selectedNewLocalProduct.size());
FacesContext.getCurrentInstance().addMessage(null,msg);
}
/*
* Getters/setters
*/
public Integer getCountProduct() { return countProduct; }
public void setCountProduct(Integer countProduct){
this.countProduct = countProduct;
}
public LazyDataModel<NewLocalProduct> getLocalProductLazyModel() { return localProductLazyModel; }
public void setLocalProductLazyModel(LazyDataModel<NewLocalProduct> localProductLazyModel){ this.localProductLazyModel = localProductLazyModel; }
public List<NewLocalProduct> getSelectedNewLocalProduct(){ return selectedNewLocalProduct; }
public void setSelectedNewLocalProduct(List<NewLocalProduct> selectedNewLocalProduct){ this.selectedNewLocalProduct = selectedNewLocalProduct; }
public NewLocalProduct getNewLocalProduct() { return newLocalProduct; }
public void setNewLocalProduct(NewLocalProduct newLocalProduct){ this.newLocalProduct = newLocalProduct;}
}
I want to update cellValue in same row.
I followed the sugestions of BalusC
Updating entire <p:dataTable> on complete of <p:ajax event="cellEdit">
After all my code perform 2 Requests. The secound one makes a full page Reload and all data will reseted.
I also tried <p:remoteCommand name="updateTable" process="#this" update="kAbnrTbl" /> following this suggestion.
Using a p:remoteCommand to update a p:dataTable
Here is JSF Page:
<h:form id="kalkEditForm">
<p:outputPanel id="dropArea">
<p:remoteCommand name="updateTable" update="kAbnrTbl" />
<p:dataTable id="kAbnrTbl" value="#{tableBean.data}" var="data" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="updateTable()"/>
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{data.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{data.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<h:outputText value="#{data.col2}" />
</p:column>
</p:dataTable>
</p:outputPanel>
</h:form>
And here Bean:
#ManagedBean(name="tableBean")
#ViewScoped
public class TableBean {
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private final ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void onCellEdit(CellEditEvent event) {
final DataTable dataTable = (DataTable)event.getComponent();
RowData data = (RowData) dataTable.getRowData();
data.setCol2("changed");
}
}
I have no idea what is wrong with the code. Why perform <p:remoteCommand ... the second Request.
Using:Primface 5.3
Back to the beginning point. If I don't use <p:remoteCommand name="updateTable" update="kAbnrTbl" /> hack, it works ok but I have to press the refreshButton.
If I use the hack I have 2 Requests and a full page reload. There must be a tiny typo or something that I overlook.
Here the code without the hack.
<h:form id="kalkEditForm">
<p:outputPanel id="dropArea">
<!-- <p:remoteCommand name="updateTable" update="kAbnrTbl" /> -->
<p:dataTable id="kAbnrTbl" value="#{tableBean.data}" var="data" editable="true" editMode="cell">
<p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" update="kAbnrTbl"/>
<!-- <p:ajax event="cellEdit" listener="#{tableBean.onCellEdit}" oncomplete="updateTable()"/> -->
<p:column headerText="Col1">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{data.col1}" /></f:facet>
<f:facet name="input"><p:inputText value="#{data.col1}" /></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Col2">
<h:outputText value="#{data.col2}" />
</p:column>
</p:dataTable>
</p:outputPanel>
<p:commandButton id="refreshButton" value="Redisplay" update="kAbnrTbl" />
</h:form>
I used event="rowEdit", this worked for me.
<p:ajax event="rowEdit" listener="#{tableBean.onCellEdit}" oncomplete="updateTable()" />
Following the note from user3821232, the workaround is to be used instead of "celleditor" "inplace" in conjunction with a standard <p:ajax.. call.
Here you can see the workaround.
xthml:
<h:form id="kalkEditForm">
<p:outputPanel id="dropArea">
<p:dataTable id="kAbnrTbl" value="#{tableBean.data}" var="data" editable="true" editMode="cell" rowIndexVar="row">
<p:column headerText="Col1" id="col1" sortBy="#{data.col1}" sortable="true">
<p:inplace>
<f:facet name="output"><h:outputText value="#{data.col1}" /></f:facet>
<f:facet name="input">
<p:inputText value="#{data.col1}" >
<p:ajax event="blur" process="#this" listener="#{tableBean.updateData(row, 'col1')}" update="kAbnrTbl"/>
</p:inputText>
</f:facet>
</p:inplace>
</p:column>
<p:column headerText="Col2">
<h:outputText id="col2" value="#{data.col2}" />
</p:column>
</p:dataTable>
</p:outputPanel>
</h:form>
Bean:
#ManagedBean(name="tableBean")
#ViewScoped
public class TableBean {
private static final Logger logger = Logger.getLogger(TableBean.class);
public TableBean() {
RowData entry = new RowData("a1", "b1");
entries.add(entry);
entry = new RowData("a2", "b2");
entries.add(entry);
entry = new RowData("a3", "b3");
entries.add(entry);
}
public class RowData {
private String col1;
private String col2;
public RowData(String col1, String col2) {
this.col1 = col1;
this.col2 = col2;
}
public String getCol1() {
return col1;
}
public void setCol1(String col1) {
this.col1 = col1;
}
public String getCol2() {
return col2;
}
public void setCol2(String col2) {
this.col2 = col2;
}
}
private final ArrayList<RowData> entries = new ArrayList<RowData>();
public List<RowData> getData() {
return entries;
}
public void updateData(Integer row, String colName){
logger.debug(String.format("updateData called row:%d colName %s", row, colName));
RowData data = getData().get(row);
data.setCol2("changed");
}
}
I'm using PF 4.0 and I have a datatable that is lazily loaded and i'm trying to add a filter textbox to the "name" column, but the textbox is not appearing. What am I missing?
...
<p:dataTable var="user" value="#{userGroupBacking.users}" editable="true" id="userTable" paginator="true" rows="20"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink}" lazy="true"
filteredValue="#{userGroupBacking.filteredUsers}" >
<p:ajax event="rowEdit" listener="#{userGroupBacking.onEdit}" />
<p:column headerText="User" filterBy="#{user.name}" filterMatchMode="contains">
<h:outputText value="#{user.name}" />
</p:column>
...
backing bean:
#ManagedBean(name="userGroupBacking")
#ViewScoped
public class UserGroupBacking {
#ManagedProperty(value="#{accessBacking}")
private AccessBacking accessBacking;
public void setAccessBacking(AccessBacking accessBacking) {
this.accessBacking = accessBacking;
}
#PostConstruct
public void init() {
this.ds = databaseBacking.getDs();
if(isLoggedIn()) {
loadData();
}
}
/**
* Checks that the user is logged in
* #return
*/
public boolean isLoggedIn() {
return accessBacking.isHasAccess();
}
public LazyDataModel<User> getUsers() {
return users;
}
public List<Group> getGroups() {
return groups;
}
public List<Group> getSelectedGroups() {
return selectedGroups;
}
public List<SelectItem> getGroupsAsSelectItems() {
return groupsAsSelectItems;
}
public List<SelectItem> getUsersAsSelectItems() {
return usersAsSelectItems;
}
public String getNewGroup() {
return newGroup;
}
public void setNewGroup(String newGroup) {
this.newGroup = newGroup;
}
public List<User> getFilteredUsers() {
return filteredUsers;
}
public void setFilteredUsers(List<User> filteredUsers) {
this.filteredUsers = filteredUsers;
}
}
I figured it out. It seems that in PF 4.0, you need the filterBy code to change from:
<p:column headerText="User" filterBy="#{user.name}" filterMatchMode="contains">
<h:outputText value="#{user.name}" />
</p:column>
to:
<p:column headerText="User" filterBy="name" filterMatchMode="contains">
<h:outputText value="#{user.name}" />
</p:column>
I am just curious, is this the actual code you have in your page. Cause it should wrapped up inside <p:cellEditor> as shown in primefaces showcase
http://www.primefaces.org/showcase-labs/ui/datatableRowEditing.jsf
some thing like
<p:column headerText="Model" style="width:30%">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{car.model}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{car.model}" style="width:100%"/>
</f:facet>
</p:cellEditor>
</p:column>
I'm using prime faces 3.4.2 and I'm trying to update an entity that contains a list of another object, using a row editing datatable. My problem is that when I validate the change , the simple attributes of the entity are updated in the database , but the list is not. I don't know how to save the whole object in the data base.
here you find the editing page :
`
<p:panel style="width:1000px; ;font: lighter 70.5% Arial, Helvetica, sans-serif ; " header="Informations Générales">
<p:growl id="growl" showDetail="true" sticky="true" style="font-size: small;" />
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel value="Société" />
<p:inputText id="custSoc" value="#{CustomerCtrl.selectedCust.company}"/>
<h:outputLabel value="Secteur d'activité" />
<p:inputText id="custActivite" value="#{CustomerCtrl.selectedCust.secteurActivite}" />
<h:outputLabel value="Nom du propriétaire" />
<p:inputText id="custprop" value="#{CustomerCtrl.selectedCust.proprietaire}" />
</h:panelGrid>
<p:tabView id="tabView">
<p:tab title="Coordonnées">
<p:growl id="messages" showDetail="true"/>
<p:dataTable var="cu" value="#{CustomerCtrl.selectedCust.coordonnee}" id="carList" editable="true">
<f:facet name="header">
Coordonnées
</f:facet>
<p:columnGroup type="header">
<p:row>
<p:column colspan="5" headerText="Adresses" />
<p:column colspan="5" headerText="Contacts" />
</p:row>
<p:row>
<p:column headerText="Num" style="width:2cm"/>
<p:column headerText="Rue/Avenue" style="width:3cm"/>
<p:column headerText="Code postal" style="width:2cm" />
<p:column headerText="Ville" style="width:2.5cm" />
<p:column headerText="Pays" style="width:2.5cm" />
<p:column headerText="Fixe" style="width:2cm"/>
<p:column headerText="Mobile" style="width:2cm"/>
<p:column headerText="Fax" style="width:2cm"/>
<p:column headerText="E-mail" style="width:3.7cm"/>
<p:column headerText=" " />
</p:row>
</p:columnGroup>
<p:ajax event="rowEdit" listener="#{CustomerCtrl.onEdit}" update=":form:messages" />
<p:ajax event="rowEditCancel" listener="#{CustomerCtrl.onCancel}" update=":form:messages" />
<p:column headerText="Num">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.number}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.number}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Rue/Avenue">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.street}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.street}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Code postal">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.zipcode}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.zipcode}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Ville">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.city.text}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{cu.city.text}" style="width:100%">
<f:selectItems value="#{CustomerCtrl.cityList}" style="width:100%"
var="city"
itemLabel="#{city}"
itemValue="#{city}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Pays" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.country.text}" style="width:100%" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{cu.country.text}" style="width:100%">
<f:selectItems value="#{CustomerCtrl.countryList}" style="width:100%"
var="color"
itemLabel="#{color}"
itemValue="#{color}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Fixe">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.phone}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.phone}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Mobile" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.mobile}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.mobile}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Fax" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.fax}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.fax}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="E-mail" >
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cu.email}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{cu.email}" style="width:90%"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:6%">
<p:rowEditor />
</p:column>
</p:dataTable>
</p:tab>
<p:tab title="Compte">
<h:panelGrid columns="2" cellpadding="5">
<h:outputLabel value="Login" />
<p:inputText id="userLogin" value="#{CustomerCtrl.selectedCust.login}" />
<h:outputLabel value="Mot de passe" />
<p:password id="userpass" value="#{CustomerCtrl.selectedCust.password}" />
</h:panelGrid>
</p:tab>
<p:tab title="Applications">
<h:panelGrid columns="2" cellpadding="5">
</h:panelGrid>
</p:tab>
<p:tab title="Interventions">
<h:panelGrid columns="2" cellpadding="5">
</h:panelGrid>
</p:tab>
</p:tabView>
</p:panel>
<br/>
`
and here is my managedbean :`#ManagedBean(name = "CustomerCtrl")
#ViewScoped
public class CustomerController implements Serializable {
/**
*
*/
private static final long serialVersionUID = 1L;
private int idSelected;
private Customer selectedCust ;
private Coordonnee selectedCoord = new Coordonnee();
private Coordonnee filteredCoord = new Coordonnee();
private List<Customer> filteredCusts;
private int cityId;
private int countryId;
private List<SelectItem> cityList = new ArrayList<SelectItem>();
private List<SelectItem> countryList = new ArrayList<SelectItem>();
private List<Customer> custmrs = new ArrayList<Customer>();
private List<Coordonnee> coordonnees = new ArrayList<Coordonnee>();
private Coordonnee selectedCustomerCoordonne;
#EJB
private SettingsBean settingBean;
public CustomerController() {
if (selectedCust != null) {
coordonnees = (List<Coordonnee>) settingBean.FindCoordonneeByCustomer(selectedCust.getId());
}
}
public void createCustomer() {
System.out.println("hello createCustomer");
System.out.println("selectedcust :"+selectedCust.getCompany());
System.out.println("selectedcustCoordonnee 1 :"+selectedCustomerCoordonne);
if(selectedCust==null){
System.out.println("entré");
selectedCust= new Customer();
System.out.println("nouvelle instance créé");
settingBean.createCustomer(selectedCust);
settingBean.createCoordonnee(selectedCustomerCoordonne);
System.out.println("Nouveau client " + selectedCust.getCompany() + " ajoutée");
}
else{
System.out.println("editer");
selectedCust.setCoordonnee(coordonnees);
settingBean.editCustomer(selectedCust);
System.out.println("client " + selectedCust.getCompany() + " édité");
}
}
public List<Customer> getCustmrs() {
custmrs = settingBean.findAllCustomers();
return custmrs;
}
public void setCustmrs(List<Customer> custmrs) {
this.custmrs = custmrs;
}
public void preRenderView() {
HttpSession session = (HttpSession) FacesContext.getCurrentInstance()
.getExternalContext().getSession(true);
}
public Customer getSelectedCust() {
if (selectedCust == null) {
selectedCust = (Customer) FacesContext.getCurrentInstance()
.getExternalContext().getSessionMap().get("selectedCust");
System.out.println("Par session");
if (selectedCust == null) {
selectedCust = new Customer();
selectedCust.setCoordonnee(new ArrayList<Coordonnee>());
} else
selectedCust.setCoordonnee(settingBean
.FindCoordonneeByCustomer(selectedCust.getId()));
}
return selectedCust;
}
public void setSelectedCust(Customer selectedCust) {
this.selectedCust = selectedCust;
}
public List<Customer> getFilteredCusts() {
return filteredCusts;
}
public void setFilteredCusts(List<Customer> filteredCusts) {
this.filteredCusts = filteredCusts;
}
public List<Coordonnee> getCoordonnees() {
if (selectedCust != null) {
coordonnees = (List<Coordonnee>) settingBean.FindCoordonneeByCustomer(selectedCust.getId());
}
return coordonnees;
}
public void setCoordonnees(List<Coordonnee> coordonnees) {
this.coordonnees = coordonnees;
}
public void setCustomerToEdit(Customer customerToEdit) {
}
public String removeCustomer() {
if (selectedCust != null) {
System.out.println("in delete");
String selected = selectedCust.getCompany();
System.out.println("supprimer " + selected + "");
custmrs.remove(selectedCust);
settingBean.removeCustomer(selectedCust);
System.out.println("client supprimé");
}
return "";
}
public String removeCustomercoordonnee() {
if (selectedCustomerCoordonne != null) {
System.out.println("coordonne in delete");
String selected = selectedCustomerCoordonne.getEmail();
System.out.println("supprimer " + selected + "");
settingBean.removeCustomerCoordonnee(selectedCustomerCoordonne);
System.out.println("coordonne supprimé");
}
return "";
}
public String editCustomer() {
if (selectedCust != null) {
FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().put("selectedCust", selectedCust);
System.out.println("selected "
+ FacesContext.getCurrentInstance().getExternalContext()
.getSessionMap().get("selectedCust"));
}
return "customeradd.xhtml?faces-redirect=true";
}
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public int getCountryId() {
return countryId;
}
public void setCountryId(int countryId) {
this.countryId = countryId;
}
public List<SelectItem> getCityList() {
cityList = new ArrayList<SelectItem>();
List<City> Listcity = settingBean.findAllCity();
for (City c : Listcity) {
cityList.add(new SelectItem(c.getId(), c.getText()));
}
return cityList;
}
public void setCityList(List<SelectItem> cityList) {
this.cityList = cityList;
}
public List<SelectItem> getCountryList() {
cityList = new ArrayList<SelectItem>();
List<Country> Listcountry = settingBean.findAllCountry();
for (Country c : Listcountry) {
countryList.add(new SelectItem(c.getId(), c.getText()));
}
return countryList;
}
public void setCountryList(List<SelectItem> countryList) {
this.countryList = countryList;
}
public int getIdSelected() {
return idSelected;
}
public void setIdSelected(int idSelected) {
this.idSelected = idSelected;
}
public Coordonnee getSelectedCustomerCoordonne() {
return selectedCustomerCoordonne;
}
public void setSelectedCustomerCoordonne(
Coordonnee selectedCustomerCoordonne) {
this.selectedCustomerCoordonne = selectedCustomerCoordonne;
}
public Coordonnee getSelectedCoord() {
return selectedCoord;
}
public void setSelectedCoord(Coordonnee selectedCoord) {
this.selectedCoord = selectedCoord;
}
public Coordonnee getFilteredCoord() {
return filteredCoord;
}
public void setFilteredCoord(Coordonnee filteredCoord) {
this.filteredCoord = filteredCoord;
}
public void onEdit(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Cliquer sur enregistrer pour valider la modification", ((Coordonnee) event.getObject()).getCustomer().getCompany());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Modification annulée", ((Coordonnee) event.getObject()).getCustomer().getCompany());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}`
Pleaaase help me to save the both objects.