How to refresh a row in Primefaces? - jsf

In a Primefaces <p:dataTable>, on each row, I have a column containing a commandButton.
This commandButton update a value of the bean corresponding to the current row.
How to refresh the current row where I have just clicked so that the reader column will refresh?
<p:dataTable id="repositoryBean"
currentPageReportTemplate="Total : {totalRecords}"
lazy="true"
resizableColumns="false"
rows="200"
rowsPerPageTemplate="10,15,20"
sortBy="#{row.name}"
sortOrder="ascending"
style="margin:20px 0px;"
value="#{repositoryBean.users}"
var="row"
styleClass="small-datatable"
editable="true"
>
<p:ajax event="rowSelect" listener="#{repositoryBean.onDisplay}"
onstart="PF('loading').show()"
/>
<p:column headerText="#{label.cvs_repo_user_firstname}" sortBy="#{row.firstname}" sortOrder="ascending">
<h:outputText value="#{row.firstname}" />
</p:column>
<p:column headerText="#{label.cvs_repo_user_is_reader}" sortBy="#{row.reader}" sortOrder="ascending">
<h:outputText value="#{row.reader}" />
</p:column>
<p:column headerText="#{label.cvs_repo_user_action}" style="text-align:center" >
<p:commandButton
value="Reader"
styleClass="btn-off"
action="#{repositoryBean.onSetReader(row)}"
/>
</p:column>
</p:dataTable>

Use the Omnifaces utility library for this. It has 'Ajax' functionality to update rows of a datatable and even has a specific PrimeFaces example.
It works like:
Ajax.updateRow(table, index);
where table is the reference to the component (not id!, but via binding) and index is the row index.

Related

p:dataTable unselect row without using meta key (selecting works)

I'm using:
Server: Wildfly 8.2
JSF: 2.2
Primefaces: 5.2
JDK:8
I have a datatable with multiple selection. I use rowSelectMode='add' so clicking on different rows without modifier keys adds new rows instead of unselecting all selected ones.
<p:dataTable id="table"
value="#{ixController.files}"
var="item" paginatorTemplate="{FirstPageLink} {PreviousPageLink}
{PageLinks}
{NextPageLink} {LastPageLink}"
selection="#{ixController.selecteds}"
rowKey="#{item.id}"
rowSelectMode="add"
selectionMode="multiple">
<p:column headerText="Files">
#{item.fileName}
</p:column>
As stated it works fine for adding rows, however I need to press Ctrl to unselect rows, and the customers wish to just click again on the row and unselect it.
Is that possible somehow?
Use check box instead that way they can select and un-select just by clicking it, follow Prime Faces example:
<p:dataTable id="checkboxDT" var="car" value="#{dtSelectionView.cars6}" selection="#{dtSelectionView.selectedCars}" rowKey="#{car.id}" style="margin-bottom:0">
<f:facet name="header">
Checkbox
</f:facet>
<p:column selectionMode="multiple" style="width:16px;text-align:center"/>
<p:column headerText="Id">
<h:outputText value="#{car.id}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Brand">
<h:outputText value="#{car.brand}" />
</p:column>
<p:column headerText="Color">
<h:outputText value="#{car.color}" />
</p:column>
<f:facet name="footer">
<p:commandButton process="checkboxDT" update=":form:multiCarDetail" icon="ui-icon-search" value="View" oncomplete="PF('multiCarDialog').show()" />
</f:facet>
</p:dataTable>
I cant find an attiribute for this, however, there is a way:
<p:dataTable value="#{groupBean.groups}" var="grp" rowKey="#{grp.id}"
selectionMode="single" selection="#{groupBean.group}">
<p:ajax event="rowSelect" listener="#{groupBean.onRowSelect}" update="#all" />
As you see, when a row clicked, selectedItem setted to groupBen.goup object.
public void onRowSelect(SelectEvent event) {
if (prevGroupId == group.getId())
group = new PersonelGroup();
else
prevGroupId = group.getId();
}
In onRowSelect method, you can check if user click same row for the second time by comparing previous selected item id. And by instanciating group object to new, DataTable has been updated to no selection state.
It is important to not forget to add update="#all" attiribute of DataTable.

p:dataTable (row selection) selection and pe:inputNumber not working

I have a <p:dataTable > which is updated from a button and is also filled. The data is displayed correctly. But the PROBLEM is that when I click/select any row, NO RESPONSE; previously while being clicked, the row was highlighted, now-> no highlight. I have done this type of design many times but this time the <p:dataTable> is behaving weirdly. I cannot find the root of problem.
My XHTML snippet for table is :
<p:dataTable id="tblSales" rowIndexVar="rowsn"
paginator="true" value="#{invSaleMB.dummyList}"
var="saleObj" selectionMode="single"
selection="#{invSaleMB.dummySaleObj}"
rowKey="#{saleObj.item.itemTypeId}">
<p:column headerText="#">
<h:outputLabel value="#{rowsn+1}" />
</p:column>
<p:column headerText="Name">
<h:outputLabel value="#{saleObj.item.itemTypeName}" />
</p:column>
<p:column headerText="Count">
<h:outputLabel value="#{saleObj.count}" />
</p:column>
<p:column headerText="Unit Price">
<h:outputLabel value="#{saleObj.unitPrice}" />
</p:column>
<p:column headerText="Total Price">
<h:outputLabel value="#{saleObj.total}" />
</p:column>
</p:dataTable>
My backing bean is #ViewScoped.
And another component which is not responding to an update trigger is <pe:inputNumber> and value for this component is 'double'. I changed the <pe:inputNumber> to <p:inputText> and worked well and displayed accurate data.
<pe:inputNumber id="totalCost" disabled="true" value="#{invSaleMB.totCost}" />
The datatable and pe:inputNumber are on same form.
What have you changed between "before" (was working) and "now" (not working)?. You are sure "#{saleObj.item.itemTypeId}" is unique for each element of the table? More code of the page could be useful.
For pe:inputNumber to work remember to include xmlns:pe="http://primefaces.org/ui/extensions" in your html tag.

Dataexporter returns empty rows after filtering

I have a datatable in my xhtml view with filtering enabled. Additionally, there's the Primefaces export (for Excel) function in the context menu. When I use this function without filtering the datatable it works fine, but when I filter first and den export the data I get a file with empty rows.
This is my code:
<p:panel header="#{msg['prs.list']}">
<p:contextMenu for="persons">
<p:menuitem value="#{msg['com.view']}" icon="#{msg['icon.view']}"
action="#{personBean.redirectToEditPerson}"/>
<p:menuitem value="#{msg['student.new']}" icon="#{msg['icon.new']}"
action="#{personBean.redirectToNewStudent}"/>
<p:menuitem value="#{msg['prs.new']}" icon="#{msg['icon.new']}"
url="edit.xhtml"/>
<p:menuitem value="#{msg['report.export.excel']}" ajax="false" icon="#{msg['icon.export']}">
<p:dataExporter type="xls" target="persons" fileName="export" />
</p:menuitem>
</p:contextMenu>
<p:dataTable id="persons" var="person" value="#{personBean.personList}"
rowKey="#{person.id}" selection="#{personBean.selectedPerson}" selectionMode="single"
emptyMessage="#{msg['com.noEntries']}" paginator="true" rows="15">
<p:column headerText="Id">
<h:outputText value="#{person.id}"/>
</p:column>
<p:column headerText="#{msg['prs.name']}" filterBy="name" filterMatchMode="contains">
<h:outputText value="#{person.name}"/>
</p:column>
<p:column headerText="#{msg['prs.surname']}" filterBy="surname" filterMatchMode="contains">
<h:outputText value="#{person.surname}"/>
</p:column>
<p:column headerText="#{msg['prs.email']}" filterBy="email" filterMatchMode="contains">
<h:outputText value="#{person.email}"/>
</p:column>
</p:dataTable>
<f:facet name="footer">
<p:button value="#{msg['prs.new']}" icon="#{msg['icon.new']}"
outcome="edit"/>
</f:facet>
</p:panel>
I'm using Primefaces 4, JSF 2 and Java 7 on Wildfly 8
Solved. I found a warning in my log regarding the filteredValue property of the datatable.
[0m[33m17:26:45,701 WARNING [org.primefaces.component.datatable.DataTable] (default task-4) DataTable form:persons has filtering enabled but no filteredValue model reference is defined, for backward compatibility falling back to page viewstate method to keep filteredValue. It is highly suggested to use filtering with a filteredValue model reference as viewstate method is deprecated and will be removed in future.
I therefore added this property which then solved the problem
<p:dataTable id="persons" var="person" value="#{personBean.personList}"
rowKey="#{person.id}" selection="#{personBean.selectedPerson}"
selectionMode="single" emptyMessage="#{msg['com.noEntries']}"
paginator="true" rows="15" filteredValue="#{personBean.filtered}">
And added the following property in PersonBean as well
private List<PersonEntity> filtered;
public List<PersonEntity> getFiltered() { return filtered; }
public void setFiltered(List<PersonEntity> filtered) { this.filtered = filtered; }

Unable to process expanded row data in primefaces datatable

This is my xhtml code containing a datatable using row expansion. Using primefaces 4.0, jsf mozarra 2.2.4
<p:dataTable id="myTable" value="#{myBean.lazyModel}" var="dd"
rowKey="#{dd.hashCode()}" paginator="true"
selection="#{myBean.myModel.selectedRecords}" rows="#{myBean.pageSize}"
paginatorPosition="top"
paginatorTemplate="{CurrentPageReport} {FirstPageLink}
{PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}"
rowsPerPageTemplate="5,10,20,50,100" widgetVar="dataTable"
currentPageReportTemplate="(Number of Records: {totalRecords})"
lazy="true">
<p:ajax event="rowToggle" listener="#{myBean.onRowToggle}" process="#this"/>
<p:column>
<p:rowToggler />
</p:column>
<p:column selectionMode="multiple" id="select" />
<p:column id="cpn" headerText="#{messages['cpn']}"
filterMatchMode="contains" sortBy="#{dd.cpn}" filterBy="#{dd.cpn}">
<p:inputText id="cpnid" value="#{dd.cpn}" />
</p:column>
<p:column id="user" headerText="#{messages['user']}"
filterMatchMode="contains" sortBy="#{dd.number}"
filterBy="#{dd.number}">
<p:inputText id="addid" value="#{dd.number}" />
</p:column>
:
:
<p:rowExpansion id="rowExpansion">
<p:panelGrid>
<p:row>
<p:column>
<h:outputText value="#{messages['name']}" />
</p:column>
<p:column>
<p:inputText id="name" name="txtBox" value="#{dd.name}" />
</p:column>
<p:column>
<h:outputText value="#{messages['ageGroup']}" />
</p:column>
<p:column id="agecol">
<p:selectOneMenu id="agegrp" value="#{dd.agegrp}">
<f:selectItem itemLabel="21-25" itemValue="21-25" />
<f:selectItem itemLabel="26-30" itemValue="26-30" />
</p:selectOneMenu>
</p:column>
</p:row>
</p:panelGrid>
</p:rowExpansion>
</p:dataTable>
Now I expanded a row and entered name and selected age group and collapsed the row. If I reexpand the same row I couldn't see the values I have entered. When I debugged on collapsing the row The name field and age grp fields setters are called with null parameters.
If I remove the ajax rowToggle event then there is no request is sent to the server on row collapse.
All the examples I found are showing only static data on row expansion.
Is there any way to process data user entered on row collapse?
Any help is highly appreciated.
I had the same problem. Do you use this datatable in a dialog?
Try set dynamic=false in parent dialog.
Dynamic dialog may override your ajax request
Try to add <p:ajax partialSubmit="true" /> inside each input forms
Just remove sortBy from child table.
It's works to me.
Or,
In xhtml file (MasterDataTable):
<p:ajax event="rowToggle" listener="#{superView.ontoggle()}" />
On View file:
public void ontoggle() {
UIComponent table = FacesContext.getCurrentInstance().getViewRoot().findComponent("form:MasterDataTable:ChildDataTable");
if (table != null) {
table.setValueExpression("sortBy", null);
}
}

RadioButton row select event in p:datatable

RadioButton/Checkbox based row selection is a common use case and DataTable provides a solution for this with column selection mode feature.
<p:dataTable var="car" value="#{tableBean.cars}" paginator="true" rows="10"
selection="#{tableBean.selectedCar}">`
<f:facet name="header">
RadioButton Based Selection
</f:facet>
<p:column selectionMode="single" />
<p:column headerText="Model">
<h:outputText value="#{car.model}" />
</p:column>
<p:column headerText="Year">
<h:outputText value="#{car.year}" />
</p:column>
<p:column headerText="Manufacturer">
<h:outputText value="#{car.manufacturer}" />
</p:column>
<f:facet name="footer">
<p:commandButton value="View" image="ui-icon ui-icon-search"
update="displaySingle" oncomplete="singleCarDialog.show()"/>
</f:facet>
</p:dataTable>
I want to know if I choose the first column's radioButton ,how I get a event for this.
Because I want to let a button disabled when choose the first column or the last column's radioButton .
And I also want to get the index of the column when selected the column ,Now I use the selectedCar to compare the list,and get the index of the column. It looks ugly.Anyone can help me ?
This is a solution for PrimeFaces <= 2.x only.
There is a good example at Primeface's showcase. There is an attribute rowSelectListener that can be used like this:
rowSelectListener="#{tableBean.onRowSelect}"
and in the backing bean:
public void onRowSelect(SelectEvent event) {
FacesMessage msg = new FacesMessage("Car Selected",
((Car) event.getObject()).getModel());
FacesContext.getCurrentInstance().addMessage(null, msg);
}

Resources