Primefaces JSF RowEditCancel event duplicates a row deleted from a datatabale - jsf

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"?

Related

Disappearing p:DataTable on cellEdit p:ajax event

I use NetBeans 8.2, GlassFish 5.0, PrimeFaces 5.0.
I created a page with a cell editable data table. When I do the modification on one cell after the ajax event the whole data table replaced by the modified value. Just like the ajax respond does not send back the whole table contents. How can I correct it?
The facelet:
<h:form id="frmDemands">
<p:growl id="msgs" showDetail="true"/>
<div>
<p:dataTable
id="dtblDemands"
value="#{demandUtility.demands}"
var="demand"
editable="true"
editMode="cell"
paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15">
<p:ajax event="cellEdit" listener="#{applicantBean.onCellEdit}" update=":frmDemands :frmDemands:msgs"/>
<f:facet name="header">Demands</f:facet>
<p:column headerText="ID">
<h:outputText value="#{demand.id}"/>
</p:column>
<p:column headerText="Amount">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{demand.amount}"/></f:facet>
<f:facet name="input"><p:inputText value="#{demand.amount}"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="State">
<h:outputText value="#{demand.state}"/>
</p:column>
<p:column>
<p:commandButton value="Delete" rendered="#{applicantBean.isDemandDeleteable( demand )}" actionListener="#{applicantBean.onDeleteDemand( demand.id )}" update="#form"/>
</p:column>
</p:dataTable>
</div>
</h:form>
The backing bean handle the cellEdit event:
#Named
#RequestScoped
#Data
public class ApplicantBean
{
#Inject
private DemandUtility demandUtility;
...
public void onCellEdit( CellEditEvent event_ )
{
int rowIndex = event_.getRowIndex();
double newValue = (Double) event_.getNewValue();
Demand demand = demandUtility.getDemands().get( rowIndex );
demand.setAmount( newValue );
Event event = new Event( demandUtility.getNextEventId(), new Date(), "Demand (" + demand.getId() + ") modified! New amount: " + newValue );
demandUtility.getEvents().add( event );
}
...
}
When I try to set the #parent value to the update attribute of the ajax event the dataTable disappears as well.
Can somebody help me, please?
Create a which updates you table and change your Scope to #ViewScoped
It worked for me.
<h:form id="frmDemands">
<p:growl id="msgs" showDetail="true"/>
<p:remoteCommand name="rcCellEditUpdate"
update=":frmDemands:dtblDemands :frmDemands:msgs" />
<div>
<p:dataTable
id="dtblDemands"
value="#{demandUtility.demands}"
var="demand"
editable="true"
editMode="cell"
paginator="true"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15">
<p:ajax event="cellEdit" listener="#{applicantBean.onCellEdit}" oncomplete="rcCellEditUpdate();"/>
<f:facet name="header">Demands</f:facet>
<p:column headerText="ID">
<h:outputText value="#{demand.id}"/>
</p:column>
<p:column headerText="Amount">
<p:cellEditor>
<f:facet name="output"><h:outputText value="#{demand.amount}"/></f:facet>
<f:facet name="input"><p:inputText value="#{demand.amount}"/></f:facet>
</p:cellEditor>
</p:column>
<p:column headerText="State">
<h:outputText value="#{demand.state}"/>
</p:column>
<p:column>
<p:commandButton value="Delete" rendered="#{applicantBean.isDemandDeleteable( demand )}" actionListener="#{applicantBean.onDeleteDemand( demand.id )}" update="#form"/>
</p:column>
</p:dataTable>
</div>
</h:form>

Primefaces dataTable with multiple row count

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.

select all in datatable jsf primefaces

Im trying to create a select all button or check box that when clicked all the selectbooleanCheck boxes will be checked. is there no straight forward easy way.ive started creating the selectcheckbox that will when changed selectAll. thanks
<p:dataTable value="#{illRequestModel.list}"
var="illRequestRecord" width="100%" styleClass="request-table"
rows="10" paginator="true" id="requestGrid"
currentPageReportTemplate="Viewing Page {currentPage}"
paginatorTemplate="{CurrentPageReport} {PageLinks} "
paginatorPosition="bottom">
<p:column >
<f:facet name="header">
<h:selectBooleanCheckbox id="checkbox2" title="emailUpdates2" onchange="CheckAll()" >
</h:selectBooleanCheckbox>
</f:facet>
<h:selectBooleanCheckbox id="checkbox" title="emailUpdates"
value="#{illRequestRecord.selected}"
onchange="addNumber(#{illRequestRecord.localRequestId})">
<f:ajax listener="#{illRequestRecord.selectmethod}" />
</h:selectBooleanCheckbox>
</p:column>
<p:column id="localRequestIdCol"
sortBy="#{illRequestRecord.localRequestId}">
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:commandLink value="#{illRequestRecord.localRequestId}"
action="#{requestListController.displaySingleRecord}">
<f:param name="selectedItemId"
value="#{illRequestRecord.localRequestId}"></f:param>
</h:commandLink>
</p:column>
Why don't you use the same multi-selection datatable used in the PrimeFaces DataTable showcase
As you can see in:
<p:dataTable id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
It will automatically add a check-all functionality.
In case you want an external checkbox to check all, you can do the following.
Give a widgetVar to you datatable, let's call it dataTableWV
<p:dataTable widgetVar="dataTableWV" id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
And you have a checkbox:
<input id="checkAll" type="checkbox" />
You can register a click event on it like the next:
<script>
$(document).ready(function() {
$('#checkAll').on('click', function() {
//selects all records on the displayed page if pagination is supported.
dataTableWV.selectAllRowsOnPage();
//or you can select all the rows across all pages.
dataTableWV.selectAllRows();
});
});
</script>
<p:dataTable widgetVar="dataTableWV" id="multiCars" var="car" value="#{tableBean.mediumCarsModel}" paginator="true" rows="10" selection="#{tableBean.selectedCars}">
<f:facet name="header">
<p:commandButton value="select" onclick="PF('dataTableWV').selectAllRows()" />
<p:commandButton value="unselect" onclick="PF('dataTableWV').unselectAllRows()" />
</f:facet>
</p:dataTable>
Sample Code:-
**JAVA (your backing bean class)
==============================**
//Stores the checked items from data table.
private List<String> selectedIds = new ArrayList<>();
private List<String> getSomeList() {
// return list of strings to data table
return someList;
}
public void selectAllCheckboxes(ToggleSelectEvent event) {
if (selectedIds != null) {
selectedIds.clear();
if (event.isSelected()) {
selectedIds.addAll(someList); //Add all the elements from getSomeList()
}
}
}
**XHTML
=====**
<p:dataTable id="data-table-id" value="#{backingBean.someList}"
selection="#{backingBean.selectedIds}" rowKey="#{id}" var="id"
paginator="true" rows="10" paginatorPosition="bottom"
paginatorAlwaysVisible="false" rowSelectMode="checkbox"
rowsPerPageTemplate="10,20,30,50">
<p:column selectionMode="multiple" />
<p:ajax event="toggleSelect"
update="#this"listener="#backingBean.selectAllCheckboxes}"/>
</p:dataTable>

Primefaces dataTable Sorting does not seem to work

I am having difficulties sorting a dynamic dataTable
dataTable
<h:form prependId="false" id="Main_Form">
<p:dataTable id="dataTable" var="c" value="#{databaseSearch.customerList}"
paginator="true" rows="10" paginatorAlwaysVisible="false"
paginatorTemplate="Page {CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} Rows per page {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,15,30" draggableColumns="True">
<p:column sortBy="#{c.machine}" headerText="Machine">
<h:outputText value="#{c.machine}" />
</p:column>
<p:column sortBy="#{c.company}" headerText="Company">
<h:outputText value="#{c.company}" />
</p:column>
<p:column sortBy="#{c.contact}" headerText="Contact">
<h:outputText value="#{c.contact}" />
</p:column>
<p:column sortBy="#{c.phone}" headerText="Phone">
<h:outputText value="#{c.phone}" />
</p:column>
<p:column sortBy="#{c.email}" headerText="Email">
<h:outputText value="#{c.email}" />
</p:column>
<p:column exportable="false" headerText="Modify">
<center>
<p:commandButton id="basic" value="Update"
action="#{updateEntry.setMachine(c.machine)}"
oncomplete="dlg1.show();"
styleClass="ui-Machinebutton" update=":Update_Entry"/>
<p:tooltip for="basic" value="Update/Delete Database Entry"
showEffect="fade" hideEffect="fade" />
</center>
</p:column>
</p:dataTable>
</h:form>
I am using a #SessionScoped bean where databaseSearch.customerList would query the database and populate the dataTable. When I click on the column name to sort, the sort arrow mark changes but the table contents do not sort.
I am using PF 3.4.2
If you are querying your database in your getCustomerList method in every request this will not work. You may try with a local variable
public class DatabaseSearch{
private List<C> customerList;
public List<C> getCustomerList () {
if (customerList == null)
customerList = dao.getcustomerList();
return customerList ;
}
}

Event:cellEdit is not supported primefaces datatable cell edit

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" />

Resources