Reset RowCount for filter-enabled paginated lazy DataTable??

UI Components for JSF
Post Reply
kman
Posts: 57
Joined: 03 Nov 2010, 09:21
Location: Hong Kong

07 Jan 2011, 05:20

Hi,

I've a p:DataTable that is lazy-loading, pagination-enabled, filter-enabled and sort-enabled for several columns.

I managed to allow the DataTable keeps re-execute the implemented load() method after user posted any new filtering/sorting parameters, therefore the records on the screen can be refreshed and updated.

As the pagination rendering is totally rely on the total number of record passed to the DataTable (i.e. setRowCount()), let the DataTable "knows" the correct and actual rowCount is critically important for a concise display.

In my case, due to the DataTable is pagination-enabled mixed with filtering-enabled, we can't get the total number of record simply from the ResultSet.size(), as it will be just the "rows" value set at the <p:dataTable rows="n">, so we need to launch another query to database for getting the actual record count for such filtering condition.

However, I have no idea where to reset the RowCount (i.e. setRowCount()) after a new filtering conditions comes.

I've tried to put setRowCount() inside the load() method but this way will mess up my DataTable result.

Apart from the implemented load() method, I have no idea that any other intrinsic methods will be executed also? So that I can put setRowCount() there. Or, any other workaround for this?

Thanks for your suggestion.
PrimeFaces 3.0M1, Sun Mojarra 2.0.4 FCS, Sun GlassFish JSTL 1.2,
Apache Log4J 1.2.16, EclipseLink 2.1.1.v20100817-r8050,
Eclipse Helios

User avatar
kwintesencja
Posts: 316
Joined: 08 Feb 2010, 20:33
Location: Brazil

07 Jan 2011, 11:52

Hi kman,

I do it in the load method and it works, just use the selected filter in the query:

Code: Select all

 @Override
            public List<Income> load(int first, int pageSize, String sortField, boolean sortOrder, Map<String, String> filter) {
                List<Income> lazyIncomes = new ArrayList<Income>();
                lazyIncomes = populateLazyIncome(first, pageSize, filter,sortField,sortOrder);
                return lazyIncomes;
            }

            private List<Income> populateLazyIncome(int first, int pageSize, Map<String, String> map, String sortField, boolean sortOrder) {
                Long typeId = -1L;
                if (!map.isEmpty()) {
                    typeId = Long.parseLong(map.get("type.description"));// i got only one filter here
                    this.setRowCount(financeService.findMonthIncomesByUserAndType(currentMonth.getDate(), typeId).size());//here i make the query using the filter
                } else {
                    this.setRowCount(getUserIncomesSize());
                }
                return getLazyCurrentUserIncomesInTheMonth(typeId, first, pageSize, sortField, sortOrder);
            }

As you said u have done that so maybe you have another problem. You can refer to a detailed example here:http://primefaces.prime.com.tr/forum/vi ... 9ee#p22129



I hope it helps.
Att,

--

Rafael Mauricio Pestano


Primefaces 5.x + JavaEE7(Glassfish 4.x and Wildfly 8)
Conventions Framework
Blog
@realpestano

kman
Posts: 57
Joined: 03 Nov 2010, 09:21
Location: Hong Kong

11 Jan 2011, 04:40

thanks kwintesencja for your prompt reply!

By your suggestion and after several tests I've done, I can assure that the "setRowcount()" could be placed inside "load()" method to be executed properly at the same time when any new filters/sorting/pagination paramters comes. However, one more issue has to be taken into account that due to one minor bug in "PrimeFaces Library version 2.2RC2" (pls read the external referencing threads below).

I finally find out the reason why, in my case, the LazyDataTable got messed up, which I actually means is it shows "no records found", at the first time in loading my page for dataTable data.

After googling and reading several threads in forum, it can be concluded that it is arised from a minor bug in "PrimeFaces Library version 2.2RC2" and a workaround to this is "just simply setRowCount to the value greater then 0 in the constructor" (http://primefaces.prime.com.tr/forum/vi ... 163#p26826)

References: Belows is my full code for demonstration that almost fully avoided all major problems I've encountered of the LazyDataTable.

front-end xhtml:

Code: Select all

<p:dataTable id="dtbMyLazyDataTable" widgetVar="dtbMyLazyDataTable"
   value="#{myBean.myData}" lazy="true" var="record"
   paginator="true" pageLinks="20" rows="5" rowIndexVar="rowIdx">

    <f:facet name="footer">
        <h:outputText id="rowCount"
            value="Total number of records: #{myBean.myDataRowCount}" />
    </f:facet>
    <p:column headerText="#">
        <h:outputText value="#{rowIdx+1}." />
    </p:column>
</p:dataTable>
MyBean.java:

Code: Select all

@ManagedBean
@ViewScoped
public class MyBean implements Serializable
{
    private static final long serialVersionUID = 1L;
    private LazyDataModel<MyEntity> myData;


    public LazyDataModel<MyEntity> getMyData()
    {
        if( myData == null )
        {
            myData = new LazyDataModel<MyEntity>()
            {
                private static final long serialVersionUID = 1L;

                public List<MyEntity> load( int first, int pageSize, String sortField,
                                            boolean isSortAscend,
                                            Map<String, String> filters )
                {
                    List<MyEntity> rtn = null;
                    
                    // After executing "findAll()", it will determine the "Actual Row Count" under such
                    // filtering condition and save it to a variable "actualRowCount" and offer its
                    // public getter method for external retrieval.
                    rtn = getMyEntityService().findAll( first, pageSize, sortField, isSortAscend, filters );

                    // This line of "setRowCount()" is critical for subsequent re-loading of the DataTable:
                    this.setRowCount( getMyEntityService().getActualRowCount() );

                    return rtn;
                }
            };

            // This line of "setRowCount()" is critical for properly displaying the DataTable at the first time
            // the page, and therefore the LazyDataTable, is loaded.
            // One point has to be taken into account here is that to give it a value greater than zero at the first time.
            myData.setRowCount( getMyEntityService().getActualRowCount() );
        }
        return myData;
    }

    public int getMyDataRowCount()
    {
        return (getMyData() == null ? 0 : getMyData().getRowCount());
    }
}
MyEntityService.java:

Code: Select all

public class MyEntityService implements Serializable
{
    private static final long serialVersionUID = 1L;

    // The initial vaue should be greater than zero for LazyDataTable to function properly.
    // It is due to a bug for PrimeFaces Library version 2.2RC2.
    // Reference:
    // Re: 2.2.RC2 lazy datatable rowCount problem:
    // "Simply setRowCount to the value greater then 0 in the constructor":
    // http://primefaces.prime.com.tr/forum/viewtopic.php?f=3&t=6163#p26826
    private int actualRowCount = 1;


    public int getActualRowCount()
    {
        return actualRowCount;
    }

    private void setActualRowCount( int actualRowCount )
    {
        this.actualRowCount = actualRowCount;
    }

    public List<MyEntity> findAll( int pFirstResultPos, int pPageSize, String pSortField, boolean pSortAscend,
            Map<String, String> pFilters )
    {
        List<MyEntity> rtn = null;

        rtn = (List<MyEntity>) findAllQry( pFirstResultPos, pPageSize, pSortField, pSortAscend, pFilters );

        // "pPageSize > 0" means Pagination-enabled:
        iActualRowCount = (pPageSize > 0? findAllQryActualRowCount( pFilters ): rtn.size());

        setActualRowCount( iActualRowCount );
        return rtn;
    }
}

Other references:
PrimeFaces 3.0M1, Sun Mojarra 2.0.4 FCS, Sun GlassFish JSTL 1.2,
Apache Log4J 1.2.16, EclipseLink 2.1.1.v20100817-r8050,
Eclipse Helios

User avatar
kwintesencja
Posts: 316
Joined: 08 Feb 2010, 20:33
Location: Brazil

11 Jan 2011, 13:48

Good you made it :D


I dont know if its listed in the links you posted but there is also another situation that you have to handle which is when you delete a row in a lazy datatable and its the last rowin the page, so you have to call the resetPagination method.

reference is here:http://primefaces.prime.com.tr/forum/vi ... ion#p25405


issue for this bug: http://code.google.com/p/primefaces/iss ... il?id=1485

Another problem with the lazy table is that its dosnt work well with session scoped mbean so you have to use viewscoped.

Thanks for the detailed topic i hope it helps the community.
Att,

--

Rafael Mauricio Pestano


Primefaces 5.x + JavaEE7(Glassfish 4.x and Wildfly 8)
Conventions Framework
Blog
@realpestano

Post Reply

Return to “PrimeFaces”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 40 guests