I am trying to perform a row edit in primefaces databable. My problem is when I key in new value in inputText in CellEditor
and click edit (primefaces icon) onCellEdit method is calledsuccessfully but does not pick the newly value in the inputText it pick value that was initially in the datatable. What Am I doing wrong? I am using primefaces 3.5
Here in jsf code
<h:form id="form1">
<p:growl id="messages" showDetail="true"/>
<p:panel header="Registered Devices" style="min-height: 400px;" id="paneldevices">
<p:dataTable emptyMessage="No Device Registered" editable="true" widgetVar="deviceTable" id="idGrid" value="#{deviceMgdBean.devices}" var="item" >
<p:ajax event="rowEdit" listener="#{deviceMgdBean.onCellEdit()}" update=":form1:messages"/>
<p:ajax event="rowEditCancel" listener="#{deviceMgdBean.onCancel}" update=":form1:messages" />
<p:column headerText="Options" style="width:50px">
<p:rowEditor />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Device_name"/>
</f:facet>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{item.device_name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{item.device_name}" style="width:80%" />
</f:facet>
</p:cellEditor>
</p:column>
</h:form>
Here is my managed Bean
#ManagedBean
#ViewScoped
public class DeviceMgdBean implements Serializable {
public List<Devices> getDevices()
{
List<Devices> l=getDevdao().getDevices();//devices fetched from database
return l;
}
public void onCellEdit(RowEditEvent event)
{
Devices devo=(Devices) event.getObject();
FacesMessage msg = new FacesMessage("Device Edit","Test:"+devo.getDeviceName());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public void onCancel(RowEditEvent event)
{
FacesMessage msg = new FacesMessage("Item Cancelled");
FacesContext.getCurrentInstance().addMessage(null, msg);
Devices devo=(Devices) event.getObject();
}
}
class Devices {
private int device_id;
private String device_name;
//getter and setters
}
private List<Devices> l;
public List<Devices> getDevices() {
if(l==null) l=getDevdao().getDevices();//devices fetched from database
return l;
}
Related
With a PrimeFaces dataTable I try to edit a row. But when I click on the 'Save Row' button, the old value is send to the bean.
I tried to copy the database object to a normal pojo, but still the old value is send to the bean.
I use PrimeFaces 12
XHTML:
<h:form id="form">
<p:growl id="msgs" showDetail="true"/>
<div class="container-fluid">
<h1><h:outputText value="#{txt['rider.title']}"/></h1>
<p:dataTable id="dt_riders" class="table table-striped" value="#{riderView.allRiders}"
var="rider" editable="true">
<p:ajax event="rowEdit" listener="#{riderView.onRowEdit}" update=":form:msgs"/>
<p:ajax event="rowEditCancel" listener="#{riderView.onRowCancel}" update=":form:msgs"/>
<p:column headerText="#{txt['rider.header.id']}">
<h:outputText value="#{rider.id}"/>
</p:column>
<p:column headerText="#{txt['rider.header.name']}">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{rider.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText id="nameInp" value="#{rider.name}"/>
</f:facet>
</p:cellEditor>
</p:column>
<!-- and a few more -->
<p:column>
<p:rowEditor editTitle="Edit Row" cancelTitle="Cancel Edit" saveTitle="Save Row"/>
</p:column>
</p:dataTable>
</div>
</h:form>
The bean:
#ViewScoped
#Named("riderView")
public class RiderView implements Serializable {
private final RiderEjb riderEjb;
private final SecurityOfficer securityOfficer;
public RiderView() {
this(null, null);
}
#Inject
public RiderView(RiderEjb riderEjb, SecurityOfficer securityOfficer) {
this.riderEjb = riderEjb;
this.securityOfficer = securityOfficer;
}
public List<Rider> getAllRiders() {
return riderEjb.findAll(securityOfficer.getTeam());
}
public void onRowEdit(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Rider Edited", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
riderEjb.addOrUpdate(event.getObject());
}
public void onRowCancel(RowEditEvent<Rider> event) {
FacesMessage msg = new FacesMessage("Edit Cancelled", String.valueOf(event.getObject().getName()));
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
The Java object (getters and setters are generated by Lombok):
#Entity
#Getter
#Setter
public class Rider extends AbstractEntity {
#Id
private Long id;
private String name;
private Double weight;
private String gpxNames;
}
The problem was the method getAllRiders(). That calls the bean to gather the riders from the database. I changed it to retrieve all those riders from the database in a new #PostConstruct init() method.
Thanks to Jasper de Vries, I used the primefaces-test to pinpoint the problem.
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 :-)
I'm working on a theme for an app I'm making with PrimeFaces 6.2 (community edition) and I'd like to get my simulated DAO objects working before I proceed with my css templating.
I've got an issue I came across in the past and I can't find the right answer for it again. Would someone point out an error I've made somewhere in my code?
Details:
I've made a somewhat complex DataTable using PrimeFaces LazyDataModel with little help from PrimeFaces Showcase pages. My main issue is, when I write something in the filter fields or click on any column headers to do data sorting or even click on pagination buttons I get an unexpexted data rendering issue.
Filtered, sorted and paginated results get displayed in a single concatenated row what I don't want. I've posted images and code further below for insight.
Also, I'd like to point out:
No exceptions in JS console.
No exceptions in Java console.
don't mind the missing pagination icons (text-indent: 0;)
XHTML:
<h:form id="input-form-dt2">
<H4>DATA TABLE - LAZY MODEL</H4>
<div class="flex-container">
<p:outputPanel id="dev-input-panel-13">
<p:dataTable var="DOTable" value="#{dtModelLazy.DOTList}" paginator="true" rows="10" rowKey="#{DOTable.userID}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15,25,50" selectionMode="single" selection="#{dtModelLazy.selectedObj}" id="DTModelB" lazy="true">
<p:ajax event="rowSelect" listener="#{dtModelLazy.onRowSelect}" update="input-form-dt2:dlgDTOObjDetail" oncomplete="PF('DTObjDialog').show()" />
<p:column headerText="User ID" sortBy="#{DOTable.userID}" filterBy="#{DOTable.userID}" filterMatchMode="contains">
<h:outputText value="#{DOTable.userID}" />
</p:column>
<p:column headerText="Name" sortBy="#{DOTable.name}" filterBy="#{DOTable.name}" filterMatchMode="contains">
<h:outputText value="#{DOTable.name}" />
</p:column>
<p:column headerText="Surname" sortBy="#{DOTable.surname}" filterBy="#{DOTable.surname}" filterMatchMode="contains">
<h:outputText value="#{DOTable.surname}" />
</p:column>
<p:column headerText="Age" sortBy="#{DOTable.age}" filterBy="#{DOTable.age}" filterMatchMode="contains">
<h:outputText value="#{DOTable.age}" />
</p:column>
<p:column headerText="Address" sortBy="#{DOTable.address}" filterBy="#{DOTable.address}" filterMatchMode="contains">
<h:outputText value="#{DOTable.address}" />
</p:column>
<p:column headerText="City" sortBy="#{DOTable.city}" filterBy="#{DOTable.city}" filterMatchMode="contains">
<h:outputText value="#{DOTable.city}" />
</p:column>
<p:column headerText="Post code" sortBy="#{DOTable.postCode}" filterBy="#{DOTable.postCode}" filterMatchMode="contains">
<h:outputText value="#{DOTable.postCode}" />
</p:column>
<p:column headerText="Country code" sortBy="#{DOTable.countryCode}" filterBy="#{DOTable.countryCode}" filterMatchMode="contains">
<h:outputText value="#{DOTable.countryCode}" />
</p:column>
<p:column headerText="Phone number" sortBy="#{DOTable.phoneNumber}" filterBy="#{DOTable.phoneNumber}" filterMatchMode="contains">
<h:outputText value="#{DOTable.phoneNumber}" />
</p:column>
<p:column headerText="Avatar hash" sortBy="#{DOTable.photoID}" filterBy="#{DOTable.photoID}" filterMatchMode="contains">
<h:outputText value="#{DOTable.photoID}" />
</p:column>
</p:dataTable>
<p:dialog id="dlgDTOObjDetail" header="DataTable Object Detail" widgetVar="DTObjDialog" modal="true" showEffect="fade" hideEffect="fade" resizable="false">
<p:outputPanel id="DTObjDetail">
<p:panelGrid columns="2" rendered="#{not empty dtModelLazy.selectedObj}" columnClasses="label,value">
<h:outputText value="User ID: " />
<h:outputText value="#{dtModelLazy.selectedObj.userID}" />
<h:outputText value="Name: " />
<h:outputText value="#{dtModelLazy.selectedObj.name}" />
<h:outputText value="Surname: " />
<h:outputText value="#{dtModelLazy.selectedObj.surname}" />
<h:outputText value="Age: " />
<h:outputText value="#{dtModelLazy.selectedObj.age}" />
<h:outputText value="Address: " />
<h:outputText value="#{dtModelLazy.selectedObj.address}" />
<h:outputText value="City: " />
<h:outputText value="#{dtModelLazy.selectedObj.city}" />
<h:outputText value="Post code: " />
<h:outputText value="#{dtModelLazy.selectedObj.postCode}" />
<h:outputText value="Country code: " />
<h:outputText value="#{dtModelLazy.selectedObj.countryCode}" />
<h:outputText value="Phone number: " />
<h:outputText value="#{dtModelLazy.selectedObj.phoneNumber}" />
<h:outputText value="Photo hash: " />
<h:outputText value="#{dtModelLazy.selectedObj.photoID}" />
</p:panelGrid>
</p:outputPanel>
</p:dialog>
</p:outputPanel>
</div>
<hr></hr>
</h:form>
LAZY MODEL:
public class DataTableModelLazy extends LazyDataModel<DODataTable> {
private static final long serialVersionUID = -2647349397077805782L;
private List<DODataTable> datasource;
public DataTableModelLazy(List<DODataTable> datasource) {
this.datasource = datasource;
}
#Override
public DODataTable getRowData(String rowKey) {
for(DODataTable dtObj : datasource) {
if(dtObj.getUserID().equals(rowKey))
return dtObj;
}
return null;
}
#Override
public Object getRowKey(DODataTable dtObj) {
return dtObj.getUserID();
}
#Override
public List<DODataTable> load(int first, int pageSize, String sortField, SortOrder sortOrder, Map<String,Object> filters) {
List<DODataTable> data = new ArrayList<DODataTable>();
//filter
for(DODataTable dtObj : datasource) {
boolean match = true;
if(filters != null) {
for (Iterator<String> it = filters.keySet().iterator(); it.hasNext();) {
try {
String filterProperty = it.next();
Object filterValue = filters.get(filterProperty);
Field field = dtObj.getClass().getDeclaredField(filterProperty);
field.setAccessible(true);
String fieldValue = String.valueOf(field.get(dtObj));
field.setAccessible(false);
if(filterValue == null || fieldValue.startsWith(filterValue.toString())) {
match = true;
} else {
match = false;
break;
}
} catch(Exception e) {
match = false;
}
}
}
if(match) {
data.add(dtObj);
}
}
//sort
if(sortField != null) {
Collections.sort(data, new DataTableModelLazySorter(sortField, sortOrder));
}
//rowCount
int dataSize = data.size();
this.setRowCount(dataSize);
//paginate
if(dataSize > pageSize) {
try {
return data.subList(first, first + pageSize);
} catch(IndexOutOfBoundsException e) {
return data.subList(first, first + (dataSize % pageSize));
}
} else {
return data;
}
}
}
VIEW BEAN:
#Named("dtModelLazy")
#ViewScoped
public class DataGeneratorBeanLazy implements Serializable {
private static final long serialVersionUID = -5918527333909822277L;
private LazyDataModel<DODataTable> DOTList;
private DODataTable selectedObj;
#Inject
private DataGeneratorBean dataGen;
#PostConstruct
public void init() {
DOTList = new DataTableModelLazy(dataGen.createDTObjects(1500));
}
public LazyDataModel<DODataTable> getDOTList() {
return DOTList;
}
public void setDOTList(LazyDataModel<DODataTable> dOTList) {
DOTList = dOTList;
}
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("DataTable object selected!", ((DODataTable) event.getObject()).getUserID());
FacesContext.getCurrentInstance().addMessage(null, msg);
}
public DODataTable getSelectedObj() {
return selectedObj;
}
public void setSelectedObj(DODataTable selectedObj) {
this.selectedObj = selectedObj;
}
}
Update 1
I have modified the update property as update="input-form-dt2:dlgDTOObjDetail"to meet the suggestion provided. Also, I added the id property for the dialog. The issue still remains.
Update 2
I've changed my approach and started with the basic DataTable first. Also, I've stripped the .xhtml to a bare minimum. It contains only a form with the DataTable inside like so:
<ui:composition xmlns="http://www.w3.org/1999/xhtml"
xmlns:ui="http://java.sun.com/jsf/facelets"
xmlns:f="http://xmlns.jcp.org/jsf/core"
xmlns:h="http://xmlns.jcp.org/jsf/html"
xmlns:p="http://primefaces.org/ui">
<div>
UI components design
</div>
<h:form id="input-form-dt1">
<h4>DATA TABLE - BASIC</h4>
<p:dataTable id="DTableA" var="dataObject" value="#{dataTableBean.objectList}" paginator="true" rows="10" rowKey="#{dataObject.id}"
paginatorTemplate="{RowsPerPageDropdown} {FirstPageLink} {PreviousPageLink} {CurrentPageReport} {NextPageLink} {LastPageLink}"
rowsPerPageTemplate="5,10,15,25,50">
<p:column headerText="User ID" sortBy="#{dataObject.userID}" filterBy="#{dataObject.userID}" filterMatchMode="contains">
<h:outputText value="#{dataObject.userID}" />
</p:column>
<p:column headerText="Name" sortBy="#{dataObject.name}" filterBy="#{dataObject.name}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.name}" />
</p:column>
<p:column headerText="Surname" sortBy="#{dataObject.surname}" filterBy="#{dataObject.surname}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.surname}" />
</p:column>
<p:column headerText="Age" sortBy="#{dataObject.age}" filterBy="#{dataObject.age}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.age}" />
</p:column>
<p:column headerText="Address" sortBy="#{dataObject.address}" filterBy="#{dataObject.address}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.address}" />
</p:column>
<p:column headerText="City" sortBy="#{dataObject.city}" filterBy="#{dataObject.city}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.city}" />
</p:column>
<p:column headerText="Post code" sortBy="#{dataObject.postCode}" filterBy="#{dataObject.postCode}" filterMatchMode="contains" >
<h:outputText value="#{DOTable.postCode}" />
</p:column>
<p:column headerText="Country code" sortBy="#{dataObject.countryCode}" filterBy="#{dataObject.countryCode}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.countryCode}" />
</p:column>
<p:column headerText="Phone number" sortBy="#{dataObject.phoneNumber}" filterBy="#{dataObject.phoneNumber}" filterMatchMode="contains" >
<h:outputText value="#{dataObject.phoneNumber}" />
</p:column>
<p:column headerText="Avatar hash" sortBy="#{dataObject.photoID}" filterBy="#{dataObject.photoID}" filterMatchMode="contains">
<h:outputText value="#{dataObject.photoID}" />
</p:column>
</p:dataTable>
</h:form>
</ui:composition>
As you can see I've also removed all event listeners. I've added a new field to my data object (id of type Integer) and bound DataTables rowKey to it (previously bound to userID of type String - not a good idea). My DataTable backing bean is now as basic as it can be:
#Named("dataTableBean")
#ViewScoped
public class DataTableBean implements Serializable {
private static final long serialVersionUID = -1662465661106141910L;
private List<DTObject> objectList;
#Inject
private DataGeneratorBean dataGen;
#PostConstruct
public void init() {
setObjectList(dataGen.createDTObjects(1500));
}
public List<DTObject> getObjectList() {
if (objectList == null) {
return new ArrayList<>();
} else {
return objectList;
}
}
public void setObjectList(List<DTObject> objectList) {
this.objectList = objectList;
}
}
Now, there are no custom filters, sorters or paginators of any type, not even a data model, just raw data objects in a simple list. The output result is exactly the same as before when paginator buttons are clicked or data gets filtered. All resulting data still gets displayed in a single concatenated line.
ANSWER:
As Kukeltje pointed out in the comments I've made a complete nonsense in my main container and added an autoupdate component to it. That component messed up my data table events, loading data without a table to hold it. Once I've removed the component from my main container, everything worked out. Here is the code for my main container (commented out the troublemaker).
<div id="content-window">
<p:outputPanel id="content-panel">
<ui:include src="#{contentLoaderBean.mainContent}" />
<!-- <p:autoUpdate /> -->
</p:outputPanel>
</div>
The only situations I've seen this happening is when the datatable is fully updated in addtion to a partial update of the datatable via an event (page or filter or sort or...) In the rowSelect you do seem to update the full form which contains the datatable as well. That is bad practice and can as mentioned result in what you seem so remove that.
But...in your question there are no filter ajax events that explicitly update the full datatable so that cannot cause it. Yet with 99% vertainty there is something fully updates the datatable. Three options
there is something in your live code you left out of the datatable in your question
There is something else outside the code you posted that plays havoc (an autoupdate e.g),
an update from the server side is being done in a method
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}"
i have this problem: if build a p:datatable from ArrayList it's impossible editing and sometimes rowSelectd not fire.
my xhtml code:
<h:form id="form">
<p:messages id="messageWiz" showDetail="true" closable="true" autoUpdate="true"/>
<h:panelGroup>
<p:commandButton id="addPattern" icon="ui-icon-add"
actionListener="#{testController.add}" process="#this"
update="patternsId" />
<p:commandButton id="deletePattern" icon="ui-icon-delete"
actionListener="#{testController.remove}"
process="#this" update="#this, patternsId"
disabled="#{empty testController.patternsSelected}" />
</h:panelGroup>
<p:dataTable id="patternsId" var="pattern" scrollable="true" scrollHeight="200"
value="#{testController.patterns}" editable="true"
editMode="cell" widgetVar="patterns" rowIndexVar="idx"
selection="#{testController.patternsSelected}"
rowKey="#{pattern}"
emptyMessage="#{label['msg.emptytable']}" styleClass="nofooter">
<p:ajax event="rowSelect" update=":form:deletePattern" />
<p:ajax event="rowUnselect" update=":form:deletePattern" />
<p:ajax event="rowSelectCheckbox" update=":form:deletePattern"/>
<p:ajax event="toggleSelect" update=":form:deletePattern" />
<p:ajax event="rowUnselectCheckbox" update=":form:deletePattern" />
<p:ajax event="cellEdit" update=":form:messageWiz" />
<p:column selectionMode="multiple" width="20" />
<p:column>
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{pattern}" />
</f:facet>
<f:facet name="input">
<p:inputText value="#{pattern}"
required="true" style="width:96%" autocomplete="off" />
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
</h:form>
controller code:
#ManagedBean
#ViewScoped
public class TestController implements Serializable {
private static final long serialVersionUID = 1L;
private ArrayList<String> patterns = new ArrayList<String>();
private ArrayList<String> patternsSelected;
public ArrayList<String> getPatterns() {
return patterns;
}
public void setPatterns(ArrayList<String> patterns) {
this.patterns = patterns;
}
public ArrayList<String> getPatternsSelected() {
return patternsSelected;
}
public void setPatternsSelected(ArrayList<String> patternsSelected) {
this.patternsSelected = patternsSelected;
}
public void add() {
patterns.add(new String());
}
public void remove() {
}
}
add row and edit, then close edit end inputed vaues disappear, rowSelected not fire.
You cannot achieve this with an arraylist of strings.
You must implement a list of Pattern objects (with at least id and value members)
Backing bean (testController) must implement SelectableDataModel (unique ids will help to be sure to identify and remove the right items).