onRowSelect update second lazy p:datatable with new data - jsf

I hope someone will give me some hint about my problem. I have two <p:dataTable> that have lazy load. On first <p:dataTable> user can select row. According to selected row second <p:dataTable> must be updated with new lazy data (lazyModel2).
I don't know how to get new lazyModel2 and update second <p:dataTable> with new data on row select. onRowSelect event is working and I can get selectedRow data.
I just don't have any idea how to get new lazyModel2 from onRowSelect() method.
XHTML
<p:dataTable id="dt1"
var="dtVar1"
value="#{controller.lazyModel1}"
lazy="true"
rowKey="#{dtVar1.recordId}"
filterEvent="enter"
sortMode="multiple"
selectionMode="single"
selection="#{controller.selected1item}">
<p:ajax event="rowSelect"listener="#{controller.onRowSelect}"update="MasterForm:dt2"/>
<p:column headerText="Text" sortBy="#{dtVar1.text}" filterBy="#{dtVar1.text}" style="width: 100px">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{dtVar1.text}"/></f:facet>
<f:facet name="input"><p:inputText value="#{dtVar1.text}"style="width: 100%"/></f:facet>
</p:cellEditor>
</p:column>
...
</p:dataTable>
<p:dataTable id="dt2"
var="dtVar2"
value="#{controller.lazyModel2}"
lazy="true"
rowKey="#{dtVar2.recordId}"
filterEvent="enter"
sortMode="multiple"
editable="true"
editMode="row">
<p:ajax event="rowEdit" listener="#{controller.onRowEdit}" update="dt2"/>
<p:column style="width: 32px">
<f:facet name="header"><h:outputText value=""/></f:facet>
<p:rowEditor/>
</p:column>
<p:column headerText="Text 2" sortBy="#{dtVar2.konto}" filterBy="#{dtVar2.konto}" style="width: 100px">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{dtVar2.konto}"/></f:facet>
<f:facet name="input"><p:inputText value="#{dtVar2.konto}" style="width: 100%"/></f:facet>
</p:cellEditor>
</p:column>
...
</p:dataTable>
CONTROLLER
#Named
#ViewScoped
public class Controller extends GenericWebController {
#Inject
private Lazy1DataModel lazyModel1;
#Inject
private Lazy2DataModel lazyModel2;
public void onRowSelect(SelectEvent event) throws SQLException {
...
filters.put("recordId", arraylistafiltera);
...
List<FPromInDto> newlazy = getLazyModel2().load(0,15,null, filters);
lazyModel2.setWrappedData(newlazy);
}
public Lazy1DataModel getLazyModel1() { return lazyModel1; }
public void setLazyModel1(Lazy1DataModel lazyModel1) { this.lazyModel1 = lazyModel1; }
public Lazy2DataModel getLazyModel2() { return lazyModel2; }
public void setLazyModel2(Lazy2DataModel lazyModel2) { this.lazyModel2 = lazyModel2; }
}
Lazy2DataModel
public class Lazy2DataModel extends LazyDataModel<SomeDto> {
#Inject
private SomeDao someDao;
#Override
public List<SomeDto> load(int first, int pageSize, List<SortMeta> multiSortMeta, Map<String, Object> filters) {
List<SomeDto> data = new ArrayList<>();
try {
data = someDao.lazyLoad(first, pageSize, BiLazyUtils.getSortString(multiSortMeta, SomeDto.class), BiLazyUtils.getFilterString(filters, SomeDto.class));
this.setRowCount(someDao.count(BiLazyUtils.getFilterString(filters, SomeDto.class)));
} catch (SQLException e) {
e.printStackTrace();
}
return data;
}

Related

Problems after using Primefaces filter

I have a datatable where one of the columns is editable.
As long as i dont use my filter i can navigate through my list and can edit the entry in any row i want. I dont get any errors and my changes are persisted in the DB correctly.
But after i once used any of the filter everything goes sideways. The filter itself works properly.
But when i now try to edit any entry the event.oldValue() from my CellEditEvent is always null and i cant persist my entries.
And only the first page of my paginator is filled with data. Every other page is empty.
Here is the view:
<div class="Container100">
<p:dataTable paginator="true" rows="15" var="listReportingParticipantOverview" value="#{reportingBean.listReportingParticipantOverview}"
id="participantOverviewId" widgetVar="participantOverviewId"
editable="true" editMode="cell" editInitEvent="dblclick"
emptyMessage="#{msg['system.no_result']}"
filteredValue="#{reportingBean.filteredListReportingParticipantOverview}">
<p:ajax event="cellEdit" listener="#{reportingBean.onCellEdit}" update=":reportingForm:msgs"/>
<p:column headerText="#{msg['model.reporting.participant_overview.name']}" filterBy="#{listReportingParticipantOverview.name}" filterMatchMode="contains">
<h:outputText value="#{listReportingParticipantOverview.name}" />
</p:column>
<p:column headerText="#{msg['model.reporting.participant_overview.dateOfBirth']}" filterBy="#{listReportingParticipantOverview.dateOfBirth}" filterMatchMode="contains">
<h:outputText value="#{listReportingParticipantOverview.dateOfBirth}" />
</p:column>
<p:column headerText="#{msg['model.reporting.participant_overview.email']}" filterBy="#{listReportingParticipantOverview.email}" filterMatchMode="contains">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{listReportingParticipantOverview.email}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{listReportingParticipantOverview.email}" style="width:100%" label="name"/>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</div>
Here is the bean:
#SessionScoped
#ManagedBean(name = "reportingBean2")
public class ReportingBean2 extends BeanController implements Serializable {
List<ReportingParticipantOverview> listReportingParticipantOverview = new ArrayList<ReportingParticipantOverview>();
List<ReportingParticipantOverview> filteredListReportingParticipantOverview;
ContactRepository contactRepository;
ContactRepository contactRepositoryOtherDBContext;
CommunicationRepository communicationRepositoryOtherDBContext;
private AbstractApplicationContext otherDBContext;
public void initData() {
this.listReportingParticipantOverview = this.contactRepositoryOtherDBContext
.selectParticipantOverviewReporting();
}
#PostConstruct
public void init() {
otherDBContext = new ClassPathXmlApplicationContext("applicationContext_otherDB.xml");
this.contactRepository = this.getApplicationContext().getBean(ContactRepository.class);
this.contactRepositoryOtherDBContext = otherDBContext.getBean(ContactRepository.class);
this.communicationRepositoryOtherDBContext = otherDBContext.getBean(CommunicationRepository.class);
}
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
// ...
}
public List<ReportingParticipantOverview> getListReportingParticipantOverview() {
return listReportingParticipantOverview;
}
public void setListReportingParticipantOverview(
List<ReportingParticipantOverview> listReportingParticipantOverview) {
this.listReportingParticipantOverview = listReportingParticipantOverview;
}
public List<ReportingParticipantOverview> getFilteredListReportingParticipantOverview() {
return filteredListReportingParticipantOverview;
}
public void setFilteredListReportingParticipantOverview(
List<ReportingParticipantOverview> filteredListReportingParticipantOverview) {
this.filteredListReportingParticipantOverview = filteredListReportingParticipantOverview;
}
}
}
I am using Java 8, Eclipse 2021-03 and Primefaces 10.0.0.
Any help appreciated :-)

getRowData and getRowKey never executed LazyDataModel

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}"
...

After adding LazyDataModel Editing and Delete not working

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

How to make one column editable in a readonly ace:datatable?

I have a readonly ace:datatable composed of 4 columns
I wish to make the fourth column "Process Limit" editable in this datatable
Can i do this ?
This is the xhtml code :
<ace:dataTable value="#{bankProcessLimitManagement.bankProcessLimitBean}"
var="name" style="width: 50% !important;" id="namesTable"
rowSelectListener="#{bankProcessLimitManagement.rowSelectListener}"
rowUnselectListener="#{bankProcessLimitManagement.rowDeSelectListener}"
selectionMode="single" paginator="true" rows="10">
<ace:column headerText="LatinName">
<h:outputText value="#{name.latinName}"></h:outputText>
</ace:column>
<ace:column headerText="Arabic Name">
<h:outputText value="#{name.arabicName}"></h:outputText>
</ace:column>
<ace:column headerText="Process Type">
<h:outputText value="#{name.processType}"></h:outputText>
</ace:column>
<ace:column headerText="Process Limit">
<h:outputText value="#{name.limit}"></h:outputText>
</ace:column>
</ace:dataTable>
This is the correspondent bean:
#ManagedBean(name="bankProcessLimitManagement")
#ViewScoped
public class BankProcessLimitManagement {
// Render for the datatable
private boolean renderTable = false;
// List linked to the datatable
private List<BankProcessLimitBean> bankProcessLimitBean;
// Selected Row
private BankProcessLimitBean selectedBankProcessLimit;
public void rowSelectListener(SelectEvent event) {
selectedBankProcessLimit = (BankProcessLimitBean) event.getObject();
}
public void rowDeSelectListener(UnselectEvent event) {
selectedBankProcessLimit = null;
}
// Getters
public List<BankProcessLimitBean> getBankProcessLimitBean() { return bankProcessLimitBean; }
public boolean isRenderTable() { return renderTable; }
public BankProcessLimitBean getSelectedBankProcessLimit() { return selectedBankProcessLimit; }
// Setters
public void setRenderTable(boolean renderTable) { this.renderTable = renderTable; }
public void setBankProcessLimitBean(List<BankProcessLimitBean> bankProcessLimitBean) { this.bankProcessLimitBean = bankProcessLimitBean; }
public void setSelectedBankProcessLimit(BankProcessLimitBean selectedBankProcessLimit) { this.selectedBankProcessLimit = selectedBankProcessLimit; }
}
Thanks in advance
As said in the documentation you should do:
<ace:column headerText="Process Limit">
<ace:cellEditor>
<f:facet name="output">
<h:outputText value="#{name.limit}"/>
</f:facet>
<f:facet name="input">
<h:inputText value="#{name.limit}"/>
</f:facet>
</ace:cellEditor>
</ace:column>
You need of course to add a form wrapping your table, and to include a button or a link in order to submit the data.

Primefaces - datatable column filter textbox not appearing

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>

Resources