the next datatable is a report of files transferred and not transferred by each period (month / year). I need to include multiple row counts in the currentPageReportTemplate attribute. The total count, the count of transferred files and the count of not transferred files.
<p:dataTable id="repFiles" var="rep" value="#{reportFilesBean.list}" filteredValue="#{reportFilesBean.listFiltered}"
paginator="true" rows="20" sortMode="multiple" emptyMessage="Empty result"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
currentPageReportTemplate="Total: {totalRecords} / Transferred: #{reportFilesBean.countTrans} / Not transferred: #{reportFilesBean.countNotTrans}"
rowsPerPageTemplate="10,20,30,40,50,100" scrollable="true" style="width: 100%;" >
<f:event type="org.primefaces.event.data.PostFilterEvent" listener="#{reportFilesBean.postFilter}" />
<f:facet name="header">
Files transfered
</f:facet>
<p:column sortBy="#{rep.period}" filterBy="#{rep.period}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Period" />
</f:facet>
<h:outputText value="#{rep.period}" />
</p:column>
<p:column sortBy="#{rep.filename}" filterBy="#{rep.filename}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Filename" />
</f:facet>
<h:outputText value="#{rep.filename}" />
</p:column>
<p:column sortBy="#{rep.date}" filterBy="#{rep.date}" filterMatchMode="contains">
<f:facet name="header">
<h:outputText value="Date" />
</f:facet>
<h:outputText value="#{rep.date}" />
</p:column>
</p:dataTable>
#ManagedBean
#ViewScoped
public class ReportFilesBean implements Serializable {
private List<ReportFile> list;
private List<ReportFile> listFiltered;
private Long countTrans;
private Long countNotTrans;
public ReportFilesBean() {
list = new ArrayList<ReportFile>();
countTrans = 0L;
countNotTrans = 0L;
}
public void generateReport(ActionEvent actionEvent) {
Long[] c = {0L, 0L};
list = dao.reportFile(c);
countTrans = c[0];
countNotTrans = c[1];
}
public void postFilter(ComponentSystemEvent e) {
countTrans = 0L;
countNotTrans = 0L;
for (ReportFile r : listFiltered) {
if (r.getFilename() != null){
cantTrans++;
} else {
cantNoTrans++;
}
}
}
/* Getters and Setters */
}
At generate the report the variables countTrans and countNotTrans are displayed correctly. However at the time of filtering they maintain the value initially loaded. I debug the postFilter method and the count is successful but the datatable is not updated.
Please your help, I have read and I find no example with a similar scenario.
Thanks in advance.
Related
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
This question already has answers here:
How to choose the right bean scope?
(2 answers)
Closed 7 years ago.
So, I am loading a list from H2 database to be shown, and it is updated with data from form on previous page. The datatable is update only once in session, after I submit form first time. If I reset tomcat server, all the data submitted in last session will be shown. I will upload all the code that I consider relevant,:
Managed bean, with the TaskList datatable:
#ManagedBean
#SessionScoped
public class TaskListController {
private List<Task> taskList;
private Task task;
#PostConstruct
private void init() {
taskList = TaskServiceDatabase.taskList();
}
public String loadFirstPage() {
return "createNewTask.xhtml";
}
public List<Task> getTaskList() {
return taskList;
}
//getters and setters
Tasklist method:
public static List<Task> taskList() {
List<Task> taskList = new ArrayList<Task>();
try {
taskList = DatabaseUtils.fetchTask();
} catch (Exception e) {
e.printStackTrace();
}
return taskList;
}
Fetch task method is communicating with database, I am fairly certain this works properly, if it is needed, I can add it.
And here is the.xhtml file:
<h:form id="form">
<p:dataTable id="taskTable" var="task" rowIndexVar="taskNumber"
value="#{taskListController.taskList}" paginator="true" rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15">
<p:column>
<f:facet name="header">
<h:outputText value="Surname" />
</f:facet>
<h:outputText value="#{task.user.surname}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Name" />
</f:facet>
<h:outputText value="#{task.user.name}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Username" />
</f:facet>
<h:outputText value="#{task.user.username}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Project name" />
</f:facet>
<h:outputText value="#{task.project.projectName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Company name" />
</f:facet>
<h:outputText value="#{task.project.companyName}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Task description" />
</f:facet>
<h:outputText value="#{task.description}" />
</p:column>
<p:column>
<f:facet name="header">
<h:outputText value="Time (h)" />
</f:facet>
<h:outputText value="#{task.time}" />
</p:column>
</p:dataTable>
<h:commandButton action="#{taskListController.loadFirstPage}"
value="Return" update="form" />
</h:form>
So, what did I do wrong?
Changing scope of bean to ViewScoped solved the issue
I have two primefaces datatable A and B, the goal is to add an item from A to B, so I have two ArrayList for each datatable.
Each datatable has <p:ajax event="rowEditCancel" listener="#{item.onCancel}" update=":datatableA :datatableB" />
the listener is fired and the object is deleted in the datatable A and added to the datatable B but the item that remains in the datatable A is duplicated, but when I clicked in that item it throws a NoRowAvailableException
Here is the form
<h:form id="formulario">
<p:accordionPanel id="ap1">
<p:tab title="Examen">
<h:panelGrid columns="2" cellpadding="10">
</h:panelGrid>
</p:tab>
<p:tab title="Preguntas disponibles" id="tb2">
<h:panelGroup id="pg2">
<p:dataTable id="dtDisponibles" value="#{examenPregunta.itemsDisponibles}" var="pregunta"
rows="10" paginator="true"
editable="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" lazy="true" >
<f:facet name="header">
<h:outputText value="Preguntas disponibles"/>
</f:facet>
<!--" <p:ajax event="rowEditCancel" listener="#{examenPregunta.agregarItem}" update="#form" />-->
<p:ajax event="rowEditCancel" listener="#{examenPregunta.agregarItem}" update=":formulario:ap1:dtSeleccionados :formulario:ap1:dtDisponibles />
<p:column headerText="Clave" >
<h:outputText value="#{pregunta.identificador}"/>
</p:column>
<p:column headerText="Enunciado">
<h:outputText escape="false" value="#{pregunta.enunciado}"/>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:panelGroup>
</p:tab>
<p:tab title="Preguntas seleccionadas" id="tab3">
<h:panelGroup id="pg3">
<p:dataTable id="dtSeleccionados" value="#{examenPregunta.itemsSeleccionados}"
editable="true"
var="pregunta" rows="10" paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15" lazy="true" >
<f:facet name="header">
<h:outputText value="Preguntas seleccionadas"/>
</f:facet>
<!--<p:ajax event="rowEditCancel" listener="#{examenPregunta.quitarItem}" update="#form" /> -->
<p:ajax event="rowEditCancel" listener="#{examenPregunta.quitarItem}" update=":formulario:ap1:dtDisponibles :formulario:ap1:dtSeleccionados" />
<p:column headerText="Clave" >
<h:outputText value="#{pregunta.identificador}"/>
</p:column>
<p:column headerText="Enunciado">
<h:outputText escape="false" value="#{pregunta.enunciado}"/>
</p:column>
<p:column>
<p:rowEditor />
</p:column>
</p:dataTable>
</h:panelGroup>
</p:tab>
</p:accordionPanel>
</h:form>
and here is the managed bean
#ManagedBean
#SessionScoped
public class ExamenPregunta implements Serializable {
private static final long serialVersionUID = 1L;
private Date currentDate = new Date();
private String idExamen = "";
private ITOAssessmentTest examen = null;
ITOAssessmentItem pregunta = new ITOAssessmentItem();
ITOAssessmentItem[] arrPregunta = null;
private ArrayList<ITOAssessmentItem> itemsDisponibles = new ArrayList<ITOAssessmentItem>();
private ArrayList<ITOAssessmentItem> itemsSeleccionados = new ArrayList<ITOAssessmentItem>();
public void agregarItem(RowEditEvent event){
System.out.println("agregarItem");
itemsDisponibles.remove((ITOAssessmentItem) event.getObject());
itemsSeleccionados.add((ITOAssessmentItem) event.getObject());
}
public void quitarItem(RowEditEvent event){
System.out.println("quitarItem");
itemsDisponibles.add((ITOAssessmentItem) event.getObject());
itemsSeleccionados.remove((ITOAssessmentItem) event.getObject());
}
/**
* #return the itemsDisponibles
*/
public ArrayList<ITOAssessmentItem> getItemsDisponibles() {
return itemsDisponibles;
}
/**
* #return the itemsSeleccionados
*/
public ArrayList<ITOAssessmentItem> getItemsSeleccionados() {
return itemsSeleccionados;
}
}
Thanks in advance!!!
you code looks ok.
maybe its an bug for this combination accordionPanel->datatable->ajax->rowEdit.
with
<p:column>
<p:commandButton value="foo" action="#{examenPregunta.doAction(pregunta)}"
process="#this"
update=":formulario:dtDisponibles :formulario:dtSeleccionados"></p:commandButton>
</p:column>
its work for me.
why did u have a lazy="true"?
I have an init() function that returns a list of emails that will be displayed in a Primefaces datatable. And I have a commandButton that extract emails and persist them in the dataTable. These new records show up in the dataTable only if I log out and log in.
This is my init() function ( my managed Bean is annotated with #ManagedBean(name = "mailMB") and #SessionScoped) :
#PostConstruct
public void init() {
emails = new ArrayList();
idCustomer = (String) session.getAttribute("idCustomer");
System.out.println(idCustomer + " this is it");
cust = customerBusinessLocal.findById(idCustomer);
System.out.println(cust.getName());
datas = dataBusinessLocal.findByCustomer(cust);
System.out.println(datas.size());
for (Data d : datas) {
for (Email e : mailBusinessLocal.mailsByData(d)) {
emails.add(e);
}
}
public List<Email> getEmails() {
return emails;
}
In my page xhtml i've implemented the code below:
<h:form id="form">
<p:commandButton value="Extract" update="tableemails" id="ajax" widgetVar="extractButton"
action="#{mailMB.searchEmails()}"
icon="ui-icon-disk" styleClass="ui-priority-primary"
onstart="blockUIWidget1.block()"
oncomplete="blockUIWidget1.unblock()"/>
<pe:blockUI target="formulaire" widgetVar="blockUIWidget1">
<h:panelGrid columns="2">
<img src="../../pictures/animated-loading-bar.gif" width="264" height="34" alt="animated-loading-bar"/>
<h:outputText value="Please wait..." style="white-space: nowrap;"/>
</h:panelGrid>
</pe:blockUI>
<p:panel id="display" header="Emails" >
<p:dataTable id="tableemails" value="#{mailMB.emails}" var="item" rowsPerPageTemplate="5,10,15" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
paginator="true" rows="10" styleClass="case-table" emptyMessage="No records found with given criteria" paginatorPosition="bottom"
filteredValue="#{mailMB.filteredMails}" rowKey="#{item.id}"
selection="#{mailMB.selectedMail}" selectionMode="single" >
<p:ajax event="rowSelect" update=":form:display"/>
<p:column styleClass="blockable" filterStyle="width: 250px" filterBy="#{item.email} " sortBy="#{item.email}">
<f:facet name="header">
<h:outputText value="Email"/>
</f:facet>
<h:outputText value="#{item.email}"/>
</p:column>
</p:dataTable>
</p:panel>
</h:form>
it looks like you do not reload your List<Email> emails after persisting some new data. #PostConstract is executed once after your bean is created (sincce it's #SessionScoped it's created once per session), thats why you see changes only after another login. Add a method repopulateEmails() that would load data from database and run it after you add/remove something, just add it to your persist() method.
public void persist()
{
....
getEntityManager().persist(getInstance());
getEntityManager().flush();
emails = null;
......
}
public List<Email> getEmails(){
if(emails == null){
emails = repopulateEmails();
}
return emails;
}
i am trying to implement a primefaces data table with cell editing. Something similar to the one implemented here:
http://www.primefaces.org/showcase/ui/datatableCellEditing.jsf
So here is my jsf datatable code:
<h:form>
<p:growl id="messages" showDetail="true"/>
<p:panel id="dataPanel">
<p:dataTable
id="imagesDataTable"
var="cRImageData"
value="#{syncCenterBean.cRImageDataList}"
widgetVar="imagesTable"
paginator="true"
sortMode="multiple"
rows="10"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="10,15,20,30"
paginatorAlwaysVisible="false"
editable="true"
editMode="cell">
<p:ajax event="cellEdit" listener="#{syncCenterBean.onCellEdit}" update=":form:messages" />
<p:column sortBy="#{cRImageData.imId}" headerText="ID" style="width:100px;text-align:center;">
<h:outputText value="#{cRImageData.imId}" />
</p:column>
<p:column headerText="Image Name" style="width:180px;text-align:center;">
<h:outputText value="#{cRImageData.imName}" />
</p:column>
<p:column headerText="Image Type" style="width:170px;text-align:center;">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{cRImageData.imType}" />
</f:facet>
<f:facet name="input">
<h:selectOneMenu value="#{syncCenterBean.cRImageTypeList}" style="width:100%">
<f:selectItems value="#{syncCenterBean.cRImageTypeList}" var="imTypeId" itemLabel="#{imTypeId}" itemValue="#{imTypeId}" />
</h:selectOneMenu>
</f:facet>
</p:cellEditor>
</p:column>
...
And here is the code for my back bean:
#ManagedBean(name = "syncCenterBean")
#RequestScoped
public class SyncCenterBean implements Serializable {
....
List<CRImageData> cRImageDataList;
List<CRImageType> cRImageTypeList;
#SuppressWarnings("unchecked")
public SyncCenterBean(){
cRImageTypeList = getImageTypesDB(); //returns a populated list of objects
cRImageDataList = getImageDataDB(); //returns a populated list of objects
}
...
public void onCellEdit(CellEditEvent event) {
Object oldValue = event.getOldValue();
Object newValue = event.getNewValue();
if(newValue != null && !newValue.equals(oldValue)) {
FacesMessage msg = new FacesMessage(FacesMessage.SEVERITY_INFO, "Cell Changed", "Old: " + oldValue + ", New:" + newValue);
FacesContext.getCurrentInstance().addMessage(null, msg);
}
}
But when i try to load the view i get:
Caused by: javax.faces.view.facelets.TagException: .... Event:cellEdit is not supported.
on line:
<p:ajax event="cellEdit" listener="#{syncCenterBean.onCellEdit}" update=":form:messages" />
You should make your datatable editable for this event
<p:datatable editable="true" editMode="cell" />