Sorting is not working in datatable in PrimeFaces?
Asked Answered
C

7

17

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

Commutate answered 16/2, 2011 at 18:47 Comment(4)
More information please. What is happening? Nothing at all or something unexpected? What does the rest of your page look like? What is the scope of your backing bean?Archfiend
@user617966: Also, note that sorting (and filtering) non-Latin UTF-8 characters currently does not work in any version of Primefaces. Sorting only work with Latin characters.Bambino
I had the same problem, but alfonx's comment was the solution.Neuron
I have the same problem, were you able to solve the issue?Allusion
H
47

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;
}
Hinny answered 4/4, 2011 at 11:22 Comment(3)
This solved my problem, thanks. I hope it solves the OP's problem as well.Neuron
@Hinny Solved my issue. It's a shame th reliance on a backing list is not mentioned anywhere in the PF User's guide.Campo
Code example is in bkomac's answerMeatman
K
11

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

Karleen answered 25/6, 2012 at 7:47 Comment(2)
This worked great. I was using f:event type="preRenderView" and changing it to postAddToView works awesome! Thanks.Timber
Where exactly do we put this?Kinchen
C
6

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.

Clouet answered 6/4, 2013 at 21:24 Comment(1)
Adding the if(tableDataList == null) made it work for me. Thanks.Meatman
A
1

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.

Archfiend answered 16/2, 2011 at 22:20 Comment(3)
No, Sean. I have tried changing my backing bean to @ViewScoped but no results. When I hit the sort icon nothing happens. Any suggestions.Commutate
I would need to see more of your code. From what you posted it seems like it should work. If you don't find an answer here you should also try the PrimeFaces support forum.Archfiend
worked for me, viewscope and sessionscope both worked as expectedVerbid
G
1

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.

Grube answered 6/1, 2014 at 14:10 Comment(0)
F
0

have you tried @SessionScoped? it works fine to me, hope this help.

Florida answered 22/4, 2011 at 7:38 Comment(1)
Not for me! Neither ViewScoped nor RequestScoped do!Allusion
S
-1

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:

  1. you can use a lazyDataModel for your datatable, it works.

  2. 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]
}
Switzerland answered 16/7, 2016 at 11:18 Comment(1)
And even then, it is not considered a bug since it is "won't fix" and 5 years oldPostboy

© 2022 - 2024 — McMap. All rights reserved.