Problems after using Primefaces filter - jsf

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 :-)

Related

onRowSelect update second lazy p:datatable with new data

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;
}

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.

Removing row from p:datatable

I'm a beginner with JSF 2, PrimeFaces and EJB and I'm making a back-end application I successfully listed the database record on a datatable and I made a command button in the front of each record on the datatable, so I can delete a row when I click on that button , but i made all the code but when I click on the button nothing happened. Here is the code . and thank you.
The method in the EJB:
#Override
public void DeleteCitizen(Citizen citizen) {
Citizen detachCit = entityManager.merge(citizen);
entityManager.remove(detachCit);
//entityManager.remove(entityManager.merge(citizen));
}
The backing bean :
#ManagedBean
#SessionScoped
public class CitizenCtr {
private List<Citizen> citizens = new ArrayList<Citizen>();
private DataModel<Citizen> datamodel = new ListDataModel<Citizen>();
//the Model
Citizen cit = new Citizen();
//injection of the proxy
#EJB
CitizenServicesLocal citizenServiceLocal;
public List<Citizen> getCitizenss() {
citizens = citizenServiceLocal.ListAllCitizen();
return citizens;
}
public DataModel<Citizen> getDatamodel() {
datamodel.setWrappedData(citizenServiceLocal.ListAllCitizen());
return datamodel;
}
public void setDatamodel(DataModel<Citizen> datamodel) {
this.datamodel = datamodel;
}
public Citizen getCit() {
return cit;
}
public void setCit(Citizen cit) {
this.cit = cit;
}
// Login operation
public String TryLogin() {
String goTo = null;
Citizen citizenFound = citizenServiceLocal.Login(cit.getEmail(), cit.getPassword());
if (citizenFound != null) {
cit = citizenFound;
goTo = "/CitizenProfile/Profile?send-redirect=true";
System.out.println("Welcome you are logged In ");
} else {
System.out.println("please enter valid data ! ");
goTo = "/welcome?send-redirect=true";
}
return goTo;
}
//Subscribe operation
public String DoSubscribe() {
String Goto = null;
citizenServiceLocal.Subscribe(cit);
Goto = "/welcome?sendredirect=true";
return Goto;
}
//Update profile operation
public String DoUpdateProfile() {
String Goto = null;
citizenServiceLocal.updateProfile(cit);
Goto = "/CitizenProfile/Profile?sendredirect=true";
return Goto;
}
//Logout operation
public String DoLogout() {
String Goto = "/welcome?sendredirect=true";
FacesContext.getCurrentInstance().getExternalContext().invalidateSession();
return Goto;
}
public Citizen GetAllCitizen() {
List<Citizen> list;
list = citizenServiceLocal.ListAllCitizen();
return (Citizen) list;
}
// Ban Operation
public void BanCitizen() {
citizenServiceLocal.DeleteCitizen(cit);
}
}
And this is the XHTML file:
<h2>Citizen Management</h2>
<p:link action="#{citizenCtr.BanCitizen()}" value="erase" >
<p:ajax update="mytable"></p:ajax>
</p:link>
<p:dataTable id="mytable"
value="#{citizenCtr.datamodel}"
var="citizen">
<f:facet name="header"> List of Citizens </f:facet>
<p:column>
<f:facet name="header">
<h:outputText value="CIN"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.CIN}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Name"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.firstName}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="LastName"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.scondName}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Addess"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.email}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Email"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.password}"></h:outputText>
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Password"></h:outputText>
</f:facet>
<h:outputText value="#{citizen.adresse}"></h:outputText>
</p:column>
<p:column>
<p:commandButton action="#{citizenCtr.BanCitizen()}"
value="Ban"
ajax="true"
update="mytable"
process="#this">
</p:commandButton>
</p:column>
</p:dataTable>
It is hard to follow your logic, but you are calling DeleteCitizen(Citizen) using a this.cit value which is not clear where it has been set.
If you are using EL 2.2 (Servlet 3.0), you could do this:
In JSF:
<p:commandButton action="#{citizenCtr.banCitizen(citizen)}" value="Ban" ajax="true" update="mytable" process="#this">
In controller
public void banCitizen(Citizen citizenToDelete) {
citizenServiceLocal.deleteCitizen(citizenToDelete);
}
Notes to improve:
Follow naming conventions. Method names begin with lowercase.
Getters may be called several times for each request. Having to query the DB several times for all the citizens for each request will be time consuming. For example, store the citizen's list as a property of the controller; the getter should just return that value. When an action that modifies the contents of the list is performed (v.g. banCitizen(Citizen)), then that action should take care of updating the values of the attribute.
Check the logs to see if there are error messages.
Why action on commandButton? Try actionListener...
<p:commandButton actionListener="#{citizenCtr.banCitizen(citizen)}" value="Ban" ajax="true" update="mytable" process="#this">

Update a row in p:dataTable

I'm working with JSF and primefaces. I want to update a row when I click on the button (pencil). I used the first code from this tutorial (Primefaces docs), but dosent work in my case.
the problem is : when i click the button (pencil) to update a row, nothing change. i have always the old values
This is my JSF code :
<f:view>
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<p:dataTable id="tservice" var="item" value="#{serviceMBean.services}" editable="true" style="margin-bottom:20px">
<f:facet name="header"> edit </f:facet>
<p:ajax event="rowEdit" listener="#{serviceMBean.onRowEdit}" update=":form:msgs" />
<p:ajax event="rowEditCancel" listener="#{serviceMBean.onRowCancel}" update=":form:msgs" />
<p:column headerText="Libelle du service">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{item.libelleservice}" /></f:facet>
<f:facet name="input">
<p:inputText value="#{item.libelleservice}" style="width:100%" label="Libelle"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="Utilisateurs/Service">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{item.nbruserservice}" /></f:facet>
<f:facet name="input">
<p:inputText value="#{item.nbruserservice}" style="width:100%" label="Nbre Users"/>
</f:facet>
</p:cellEditor>
</p:column>
<p:column style="width:32px">
<p:rowEditor />
</p:column>
And this is my managed bean code:
#Named(value = "serviceMBean")
#ViewScoped
public class ServiceMBean implements Serializable {
private List<Service> serviceList;
private Service s;
#EJB
private ServiceManager serviceManager;
public ServiceMBean() {}
public void modifierService(Service s1) {
this.serviceManager.updateService(s1);
}
public void onRowEdit(RowEditEvent event) {
Service s2 = (Service) event.getObject();
System.out.println("--->" + s2.getNbruserservice());
FacesMessage msg = new FacesMessage("Service Modifié", ((Service) event.getObject()).getLibelleservice());
this.modifierService(s2);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onRowCancel(RowEditEvent event) {
FacesMessage msg = new FacesMessage("Modification annulée", ((Service) event.getObject()).getLibelleservice());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
And this is my code for ServiceManager:
public void updateService(Object service) {
em.merge(service);
}
I think the setter in my JSF page doesn't work. Any solutions or suggestions?
Solution : Add a void method with #PostConstruct.
Example : #PostConstruct
#PostConstruct
public void initialiser() {
serviceList = this.getServices();
}
Don't forget the getter and setter of serviceList
In the JSF page, the value of datatable will be : value="#{ServiceMBean.serviceList}"

sorting not working in p:datatable

I am using primeface datatable but its sorting not working, can anyone help me!! I have tried to add #{v.elementID} in sortBy but it still not workin
<p:dataTable value="#{dashboardBean.topTenMenuItem}"
var="v" paginator="true"
rows="#{msg['dashboard.product.mapping.datatable.rows']}">
<p:column sortBy="#{v.elementId}" headerText="ID">
<h:outputText value="#{v.elementId}" />
</p:column>
<p:column sortBy="#{v.name}" headerText="Name">
<h:link value="#{v.name}" />
</p:column>
<p:column sortBy="#{v.updateBy}" headerText="Update By">
<h:outputText value="#{v.updateBy}" />
</p:column>
<p:column sortBy="#{v.statusName}" headerText="Status">
<h:outputText value="#{v.statusName}" />
</p:column>
<p:column sortBy="#{v.updateDate}" headerText="Updated On">
<h:outputText value="#{v.updateDate}" />
</p:column>
</p:dataTable>
and bean is
public List<RecentItemDashDTO> getTopTenMenuItem() {
Map<String, Object> sessMap = CommonUtil.getSessionMap();
SessionDTO sessionDTO = (SessionDTO) sessMap.get(WebConstants.SESSION_DTO);
countryCode = sessionDTO.getLoggedinCountryCode();
String languageCode = sessionDTO.getDefaultLanguageCode();
topTenMenuItem = dashboardService.getTopTenRecentMenuDashData(countryCode,languageCode);
return topTenMenuItem;
}
public void setTopTenMenuItem(List<RecentItemDashDTO> topTenMenuItem) {
this.topTenMenuItem = topTenMenuItem;
}
My own experience says that to use this feature you'll need a List object in your BackingBean, with getters and setters. Not a reference. Try that with any init method and let us know if it worked.
public class DashboardBean {
private List<RecentItemDashDTO> myList;
public List<RecentItemDashDTO> getMyList()
{
return myList;
}
public void setMyList(List<RecentItemDashDTO> myList)
{
this.myList = myList;
}
public List<RecentItemDashDTO> getTopTenMenuItem()
{
Map<String, Object> sessMap = CommonUtil.getSessionMap();
SessionDTO sessionDTO = (SessionDTO)sessMap.get(WebConstants.SESSION_DTO);
countryCode = sessionDTO.getLoggedinCountryCode();
String languageCode = sessionDTO.getDefaultLanguageCode();
topTenMenuItem = dashboardService.getTopTenRecentMenuDashData(countryCode, languageCode);
return topTenMenuItem;
}
#PostConstruct
public void init()
{
myList = getTopTenMenuItem();
}
}
XHTML:
<p:dataTable value="#{dashboardBean.myList}" ... >
I got another solution for sorting.
private String initList;
public String getInitList() {
myTopTenMenuItem=getTopTenMenuItem();
return null;
}
and in xhtml
<h:form name="form" prependId="false">
<h:inputHidden value="#{dashboardBean.initList}" />

Resources