Primefaces: multiple datatables on page - sorting - sorting

I'm using Primefaces 5.2.
On my page, I have several p:datatables with the same columns and the same sortBy expression.
Something like:
<p:dataTable .. id="tab1">
<p:column sortBy="#{prop1}">
#{prop1}
</p:column>
</p:dataTable>
<p:dataTable .. id="tab2">
<p:column sortBy="#{prop1}">
#{prop1}
</p:column>
</p:dataTable>
Sorting works fine so far, but I get strange behaviour and finally a NullPointerException if I sort one of the tables (let's call it table A) and then refresh the page (e.g. by firing a h:commandButton). In this case ALL tables have the same column highlighted as table A. Also, as soon as I sort a table other than table A afterwards, the following exception occurs:
21:33:36,149 SEVERE javax.enterprise.resource.webcontainer.jsf.application (default task-25) Error Rendering View[/stocks.xhtml]: java.lang.NullPointerException
at org.primefaces.component.datatable.DataTable.findColumnInGroup(DataTable.java:905) [primefaces-5.2.jar:5.2]
at org.primefaces.component.datatable.DataTable.findColumn(DataTable.java:896) [primefaces-5.2.jar:5.2]
at org.primefaces.component.datatable.DataTable.getSortColumn(DataTable.java:1401) [primefaces-5.2.jar:5.2]
at org.primefaces.component.datatable.feature.SortFeature.singleSort(SortFeature.java:136) [primefaces-5.2.jar:5.2]
at org.primefaces.component.datatable.DataTableRenderer.preRender(DataTableRenderer.java:109) [primefaces-5.2.jar:5.2]
at org.primefaces.component.datatable.DataTableRenderer.encodeEnd(DataTableRenderer.java:83) [primefaces-5.2.jar:5.2]
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:919) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1863) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.facelets.component.RepeatRenderer.encodeChildren(RepeatRenderer.java:104) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.facelets.component.UIRepeat.process(UIRepeat.java:621) [jsf-impl-2.2.8-jbossorg-1.jar:]
at com.sun.faces.facelets.component.UIRepeat.encodeChildren(UIRepeat.java:1110) [jsf-impl-2.2.8-jbossorg-1.jar:]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.render.Renderer.encodeChildren(Renderer.java:176) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponentBase.encodeChildren(UIComponentBase.java:889) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1856) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at javax.faces.component.UIComponent.encodeAll(UIComponent.java:1859) [jboss-jsf-api_2.2_spec-2.2.8.jar:2.2.8]
at com.sun.faces.application.view.FaceletViewHandlingStrategy.renderView(FaceletViewHandlingStrategy.java:456) [jsf-impl-2.2.8-jbossorg-1.jar:

The solution is to add rowStatePreserved="true" to the table containing the other tables. This was added in Primefaces 5.1.14 and is part of JSF 2.1.
Credits for: sdjavaudvk (http://forum.primefaces.org/viewtopic.php?f=3&t=43441).
<p:dataTable id="tab1" var="resumo" value="#{resumoView.resumos}" rows="20"
paginator="true"
rowsPerPageTemplate="5,10,15,20"
rowStatePreserved="true">
...

Have you tried using a different form for each datatable? Like this:
<h:form>
<p:dataTable id="tab1"> ... </p:dataTable>
</h:form>
<h:form>
<p:dataTable id="tab2"> ... </p:dataTable>
</h:form>

We encountered the same problem on Primefaces6.0.
We had a form containing two tables, and a specific column can be either filtered via a list of values (filterMatchMode exact) or via an input text (filterMatchMode contains).
The first table didn't have a working filter (we encountered the same NullPointerException as you did), and the second was working fine.
The two tables were in a component, and the column filtered and sorted in the two tables was built conditionnaly with the JSTL like this :
<c:choose>
<c:when test="#{cc.attrs.filterOperatorExact}">
<p:column headerText="Header name"
sortBy="#{vector.operatorForDisplay}"
filterBy="#{vector.operatorForDisplay}" filterMatchMode="exact"
filterOptions="#{cc.attrs.filtersOperatorList}">
<h:outputText value="#{vector.operatorForDisplay}" />
</p:column>
</c:when>
<c:otherwise>
<p:column headerText="Header name"
sortBy="#{vector.operatorForDisplay}"
filterBy="#{vector.operatorForDisplay}" filterMatchMode="contains">
<h:outputText value="#{vector.operatorForDisplay}" />
</p:column>
</c:otherwise>
</c:choose>
Using the "JSF way" to do this with the rendered attribute, the problem disappeared :
<p:column headerText="Header name"
sortBy="#{vector.operatorForDisplay}"
filterBy="#{vector.operatorForDisplay}" filterMatchMode="exact"
filterOptions="#{cc.attrs.filtersOperatorList}"
rendered="#{cc.attrs.filterOperatorExact}">
<h:outputText value="#{vector.operatorForDisplay}"/>
</p:column>
<p:column headerText="Header name"
sortBy="#{vector.operatorForDisplay}"
filterBy="#{vector.operatorForDisplay}" filterMatchMode="contains"
rendered="#{not cc.attrs.filterOperatorExact}">
<h:outputText value="#{vector.operatorForDisplay}"/>
</p:column>
Hope it helps.

Related

Primefaces validate cell editing values

I have a datatable, where I add rows dynamically (a button click), and let users edit those rows with primefaces cell editing.
I want to add validation for the cells, however, the validation does not occur when the input texts (in the cell) are pristine.
In order for the validation to work, the user have to actually write something in the input text (make it dirty), then deletes it, only then the validation (required for this case) will be kicked-in.
example code:
<f:view>
<p:growl autoUpdate="true"/>
<h:form>
<p:commandButton value="add row" update="table" action="#{myBean.addRow}"/>
<p:dataTable value="#{myBean.users}" var="var" id="table" editMode="cell" editable="true">
<p:column headerText="Quantity">
<p:cellEditor>
<f:facet name="output">
<h:outputText value="#{var.name}"/>
</f:facet>
<f:facet name="input">
<p:inputText value="#{var.name}" required="true">
<f:validateRequired />
</p:inputText>
</f:facet>
</p:cellEditor>
</p:column>
</p:dataTable>
<p:commandButton value="submit" action="#{myBean.submit}"/>
</h:form>
</f:view>
Using primefaces 5.3 and JSF 2.2.
Update:
This bug is fixed since version 6.2
https://github.com/primefaces/primefaces/issues/2512

p:datatable displayed wrongly after ajax update

I have problem with a primefaces datable, I have a filter on a column and before to filter the result my datatable is displayed properly like this:
When I choose a filter, the combobox of the filter is properly poulated:
A soon I choose the item for the filter, the results are properly filtered but I have a display of the datatable like this:
I just see the results who should be display in a datatable but the table is gone.
The code seems good and I don't see where is the problem:
<p:outputPanel autoUpdate="true" class="ui-g-12">
<div class="card">
<h1>Gestion des noeuds</h1>
<h:form>
<p:dataTable value="#{nodeController.nodes}"
var="node"
tableStyle="table-layout: auto;"
rowKey="#{node.nodeId}"
paginator="true"
paginatorPosition="bottom"
paginatorAlwaysVisible="false"
rows="15"
widgetVar="nodeTable"
filteredValue="#{nodeController.filterNodes}"
editable="true"
selection="#{nodeController.selectedNode}"
selectionMode="single"
paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}">
<p:column headerText="ID">
<h:outputText value="#{node.nodeId}"/>
</p:column>
<p:column headerText="Nom">
<h:outputText value="#{node.modeName}"/>
</p:column>
<p:column headerText="Description">
<h:outputText value="#{node.nodeDescription}"/>
</p:column>
<p:column filterBy="#{node.typeNodeId}" filterMatchMode="exact" headerText="Type">
<f:facet name="filter">
<p:selectOneMenu onchange="PF('nodeTable').filter()">
<f:selectItem itemLabel="filtre" itemValue="#{null}" noSelectionOption="true"/>
<f:selectItems value="#{nodeController.nodeTypes}"/>
</p:selectOneMenu>
</f:facet>
<h:outputText value="#{node.typeNodeId}"/>
</p:column>
<p:column headerText="IPv4">
<h:outputText value="#{node.ipv4}"/>
</p:column>
<p:column headerText="IPv6">
<h:outputText value="#{node.ipv6}"/>
</p:column>
<p:column headerText="powwo agent">
<h:selectBooleanCheckbox value="#{node.agentInstalled}"/>
</p:column>
<p:column headerText="Network status" style="text-align:center">
<p:graphicImage rendered="#{node.isconnected}" name="images/ConnectionStatus25.png" library="omega-layout" width="20"/>
<p:graphicImage rendered="#{!node.isconnected}" name="images/Siren-25.png" library="omega-layout" width="20"/>
</p:column>
<p:column>
<p:rowEditor/>
</p:column>
</p:dataTable>
<p:commandButton value="effacer"
update="msg"
actionListener="#{nodeController.deleteSelectedNode()}"
style="width:auto;margin-bottom:10px;margin-top: 10px"/>
</h:form>
</div>
</p:outputPanel>
Did you already meet this issue with the rendered of a datable? Any idea how to fix it?
Effectively, your title and first sentence are not correct. It is not a bug in the datatable but a 'bug' in your code. You should not use autoupdate="true" on the p:outputPanel in this case. It updates all its content on each ajax update that happens inside it, including an ajax update during filtering. This latter also updates the datatable which means two conflicting updates. Off-topic: If you'd created a Minimal, Complete, and Verifiable example , you'd have found this out during removal of code.
If you have this problem when you have an ajax listener on one of the filter/page/sort/... events on the datatable and you need the autoUpdate="true" on the panel for other events in the wrapping panel, you could also prevent the autoUpdate to happen for these specific events by adding a ignoreAutoUpdate="true" to the specific events. So e.g.
<p:ajax event="filter" ignoreAutoUpdate="true" ... />

sortBy of p:dataTable inside a ui:repeat does not work

I have a problem here.
I'm using a <ui:repeat> to create datatables, because the user can select from a other datatable multiple rows that create these multiple datatables.
It's all working fine, but the sortBy does not.
How can I use the sortBy here?
<ui:repeat var="something" value="#{SomeClassManagedBean.somethingHere}">
<p:dataTable value="#{something.rows}" var="row" sortBy="#{row.value2}">
<p:column headerText="Value 1" sortBy="#{row.value1}">
<h:outputLabel value="#{row.value1}" />
</p:column>
<p:column headerText="Value 2" sortBy="#{row.value2}">
<h:outputLabel value="#{row.value2}" />
</p:column>
<p:column headerText="Value 3" sortBy="#{row.value3}">
<h:outputLabel value="#{row.value3}" />
</p:column>
</p:dataTable>
</ui:repeat>
I have fixed the problem.
Hope this can help other developers with the same issue.
I just used p:tabView and p:tab instead ui:repeat.
The tables are more organized now and everything is working fine.

p:dataTable sortBy not working

<p:dataTable value="#{externalUsersBean.usersList}" var="user" paginator="true" rows="25">
<p:column headerText="UID" sortBy="#{user.uid}">
<h:outputText value="#{user.uid}"/>
</p:column>
<p:column headerText="Username" sortBy="#{user.username}">
<h:outputText value="#{user.username}"/>
</p:column>
...
...
</p:dataTable>
I tried changing scope in the bean to ViewScoped, yet not working.
I tried using sortBy="uid" syntax, yet not working.
I can't understand what I'm doing wrong.

Datatable not refreshing with ajax

I have two calendar controls and one command button. basically i want to give a range of date to pick the data from the database and then when i press the command button the datatable is displayed in the dialog box, the problem is java bean class is working it is loading the exact data which i want, but the datatable is not refreshing with command button click
my code is given;
<h:form id="form" >
<p:calendar value="#{calendarBean.dateFrom}" id="calFrom" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectFrom}" />
</p:calendar>
<p:calendar value="#{calendarBean.dateTo}" id="calTo" pattern="yyyy-mm-dd">
<p:ajax event="dateSelect" listener="#{calendarBean.handleDateSelectTo}" />
</p:calendar>
<p:commandButton value="Submit" action="#{calendarBean.submit()}" update="fTable" onclick="aDlg.show()">
<f:ajax render=":form:fTable" execute="#form"></f:ajax>
</p:commandButton>
<p:dialog id="aDialog" header="Filter List" widgetVar="aDlg"
modal="true" showEffect="explode"
hideEffect="explode" >
<p:panel id="pnl">
<p:dataTable id="fTable" value="#{calenderBean.list}" var="row" >
<p:column headerText="ID">
<h:outputText value="#{row.ID}"/>
</p:column>
<p:column headerText="Name">
<h:outputText value="#{row.Name}"/>
</p:column>
<p:column headerText="Time">
<h:outputText value="#{row.Time}"/>
</p:column>
<p:column headerText="User">
<h:outputText value="#{row.userName}"/>
</p:column>
</p:dataTable>
</p:panel>
</p:dialog>
</h:form>
kindly guide me regarding this issue
First thing to do, is remove the f:ajax, it's not working good with Primefaces. Also the update attribute should do everything.
This said, I have the very same code as yours which is working good.
If removing f:ajax is not working, try to check your managed bean scope (May be it's of request scope and data is re-initialized with every request)
Try Updating the dialog instead.
update="fTable"

Resources