Reputation: 4585
Sorting is not working in datatable in PrimeFaces. Please suggest.
See below my .xhtml file
<h:form>
<p:dataTable style="width: 60%" id="dt1" value="#{bean.list}" var="entry" first="0" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with given criteria" >
<f:facet name="header">
<h2>Cars View</h2>
</f:facet>
<p:column sortBy="#{entry.carno}" filterBy="#{entry.carno}">
<f:facet name="header">
<h:outputText value="Car Number" />
</f:facet>
<h:outputText value="#{entry.carno}"></h:outputText>
</p:column>
<p:column sortBy="#{entry.carsettings['car-model']}" filterBy="#{entry.carsettings['car-model']}">
<f:facet name="header">
<h:outputText value="Car Model"/>
</f:facet>
<h:outputText value="#{entry.carsettings['car-model']}"></h:outputText>
</p:column>
<p:column sortBy="#{entry.carsettings.year}" filterBy="#{entry.carsettings.year}">
<f:facet name="header">
<h:outputText value="Car Year"/>
</f:facet>
<h:outputText value="#{entry.carsettings.year}"></h:outputText>
</p:column>
<p:column sortBy="#{entry.carsettings.color}" filterBy="#{entry.carsettings.color}">
<f:facet name="header">
<h:outputText value="Car Color"/>
</f:facet>
<h:outputText value="#{entry.carsettings.color}"></h:outputText>
</p:column>
</p:dataTable>
</h:form>
@Sean
Look below code
List of Cars
<ui:composition template="/template.xhtml">
<ui:define name="content">
<f:view>
<f:event type="preRenderView" listener="#{MyBackingBean.load}"></f:event>
<center>
<h1>Car View</h1>
<h:outputText value="No data found" style="font-size: 15px;font-family: Arial, Verdana,Helvetica, sans-serif" rendered="#{MyBackingBean.noDataExist}"></h:outputText>
<h:form id="dataform1">
<p:dataTable var="item" value="#{MyBackingBean.dataList}" dynamic="true" paginator="true" rows="2" id="table" style="width:60%"
rendered="#{!MyBackingBean.noDataExist}" >
<p:column sortBy="#{item.id}" filterBy="#{item.id}">
<f:facet name="header">
<h:outputText value="ID" />
</f:facet>
<h:outputText value="#{item.id}" />
</p:column>
<p:column sortBy="#{item.carsettings['car-color']}" filterBy="#{item.carsettings['car-color']}">
<f:facet name="header">
<h:outputText value="Color" />
</f:facet>
<h:outputLink target="_blank" value="http://#{item.carsettings['car-color']}">
<h:outputText value="#{item.carsettings['car-color']}" />
</h:outputLink>
</p:column>
<p:column sortBy="#{item.carsettings.model}" filterBy="#{item.carsettings.model}">
<f:facet name="header">
<h:outputText value="Model" />
</f:facet>
<h:outputText value="#{item.carsettings.model}" />
</p:column>
<p:column sortBy="#{item.carsettings.manufacturer}" filterBy="#{item.carsettings.manufacturer}">
<f:facet name="header">
<h:outputText value="Manufacturer" />
</f:facet>
<h:outputText value="#{item.carsettings.manufacturer}" />
</p:column>
</p:dataTable>
</h:form>
</center>
</f:view>
</ui:define>
</ui:composition>
</h:body>
Sorting is not working in the above code
Please help
Upvotes: 17
Views: 46625
Reputation: 7216
The primefaces backing bean (ViewScoped!) must hold it's own List of rows. So, e.g., if you query the database every time you request the p:dataTable:value
, sorting will not work.
Solution: Collect the List from the Database and keep it in a local List variable in the backing bean.
public List<Row> getDataTable() {
if (tableDataList == null)
tableDataList = loadListOnce();
return tableDataList;
}
Upvotes: 47
Reputation: 9
I don't know if it's your case. There's a primefaces issue. A bug on sort of datatable. Take a look here: https://code.google.com/archive/p/primefaces/issues/2476
There are some workarounds:
you can use a lazyDataModel for your datatable, it works.
you can force the sort order.
In your datatable catch the sort event
<p:dataTable style="width: 60%" id="dt1" value="#{bean.list}" var="entry" first="0" paginator="true" rows="10" paginatorTemplate="{CurrentPageReport} {FirstPageLink} {PreviousPageLink} {PageLinks} {NextPageLink} {LastPageLink} {RowsPerPageDropdown}" rowsPerPageTemplate="5,10,15" emptyMessage="No cars found with given criteria" >
<p:ajax event="sort" listener="#bean.sortListener}" />
In your managed bean you set a order by string to add to your query
private String orderBy = "";
public void sortListener(SortEvent event) {
String orderColumn = event.getSortColumn().getValueExpression("sortBy").getExpressionString();
//you will get the content of the attribute SortBy of the column you clicked on, like #{entry.carno}
orderColumn = orderColumn.replace("#{entry.", "");
orderColumn = orderColumn.replace("}", "");
orderBy = " order by " + orderColumn + (event.isAscending()? " asc " : " desc ");
}
public List<Car> getList(){
String query = "[...your query...]" + orderBy;
...[execute your query and get your ordered list]
}
Upvotes: -1
Reputation: 1200
If you populate your table in the getter sorting wont work (as described above). You should put in your getter like:
public List<Row> getTableData() {
if (tableDataList == null)
tableDataList = dao.getTableData();
return tableDataList;
}
You can then reset(refresh) your "cash" by punting tableDataList = null; if you wont your datatabele refreshed.
Upvotes: 6
Reputation: 506
My Service had:
public List<PlayerEntity> getAllPlayers() {
return playerDao.readAll();
}
but that was wrong, because when I was calling getAllPlayers() from table
<p:dataTable id="data" value="#{myBean.allPlayers}"/>
I got from DAO refreshed data but still unordered. Instead of that I've created List field and method to update the List
private List<PlayerEntity> allPlayers = new ArrayList<PlayerEntity>();
public void updateAllPlayers(){
this.allPlayers = playerDao.readAll();
}
which method I'm running on bean initialization
public void setPlayerDao(PlayerDao playerDao) {
this.playerDao = playerDao;
updateAllPlayers();
}
and after Add, Delete or Modiffy the List
public boolean createPlayer(PlayerEntity playerEntity) {
(...)
updateAllPlayers();
return true;
}
Now my Service has
public List<PlayerEntity> getAllPlayers() {
return this.allPlayers;
}
and that solved my problem with sorting data in Primefaces table.
Upvotes: 1
Reputation: 111
The Problem is:
<f:event type="preRenderView" listener="#{MyBackingBean.load}"></f:event>
Sorting is done by the <p:dataTable/>
at PhaseId.APPLY_REQUEST_VALUES
on the list, with the <f:event type"preRenderView"/>
you reload the list at PhaseId.RENDER_RESPONSE
and so you lost the sorting.
Solution: use <f:event type="postAddToView"/>
<f:event type="postAddToView" listener="#{MyBackingBean.load}" />
This will reload the list at PhaseId.RESTORE_VIEW before sorting is done by <p:dataTable/>
.
Tested with PrimeFaces Version 3.1.1 and Mojarra 2.1.8
Upvotes: 11
Reputation: 981
I had a problem sorting when my backing bean was sessionScoped. Not sure what your exact problem is, but if you hit the sort button and nothing happens, try changing your scope to @ViewScoped.
Upvotes: 1