Search code examples
jsfprimefaceslazy-loadingjsf-2.2primefaces-datatable

Two Primefaces datatables on same page cause filtering problems


I have a single page which includes two datatables. Their data are lazy loaded and paginated. To retrieve the rows that i need, i override the filterMap for the load() function. I pass this filterMap on the initialization of the LazyResult list. Unfortunately this causes problems with my filterMaps.

In detail:

1) On my page i got following lines to initialize both LazyLists, each for each table

<f:event type="preRenderView" listener="#{handler.initTable1}" />
<f:event type="preRenderView" listener="#{handler.initTable2}" />

2) In my ManageBean i am initializing the LazyList

public void initTable1() {
    filterMap.clear();
    filterMap.put("organization", "IBM");    
    lazyResults1= new ResultsLazyList<MyEntity1, MyBean1, MyDTO1>(
                            myBean1, filterMap);
}

public void initTable2() {
    filterMap.clear();
    filterMap.put("city", "London");    
    lazyResults2= new ResultsLazyList<MyEntity2, MyBean2, MyDTO2>(
                            myBean2, filterMap);
}

Inside the custom created ResultsLazyList, i am overriding the load method of LazyDataModel. Also note that i am passing as a paremeter the filterMap in the constructor (which used in the load method) so that i will have from the first run the results that i want.

Problem

Now, if i have just one table in my page, everything works fine. Adding more filters, sorting etc. Once i add the second table as shown above then the following happens.

Step 1) While the client page is loading, it calls first the initTable1 method. The lazyResults1 is initialized with the filterMap which is set in the constructor. The load method of lazyResults1 is not triggered yet and my filterMap at this point has the values organization=IBM

Step 2) While the client page is loading, it calls the initTable2 method. This overrides the values of my filterMap with city=London and initializes the lazyResults2. Note at this point the load method of lazyResults1 or lazyResults2 has not been triggered yet.

Step 3) Finally the load method lazyResults1 is triggered, but with the filterMap containing the values set in initTable2. So in the backend, my application tries to query on MyEntity1 with a field that exists on MyEntity2.

Question

1) Is there a way to somehow initialize lazyResults1 and trigger the load method so that my lazyResults1 is loaded with data before initTable2() is called and overrides my filterMap ?

2) I have seen some people using to ManagedBeans, each for each table, but i want to avoid this.

3) Another way is two pass 2 filterMaps in my ResultsLazyList constructor.

4) If there is another way to override the filterMap on the load method, then the way i am doing it, that would maybe solve my problem.


Solution

  • Two different tables, two different data sets... So why do you share filters between them? By reusing the same filterMap you're saying "I want the same filters to apply to both tables". If that's not what you want, then define separate filterMaps for each table.

    1) Is there a way to somehow initialize lazyResults1 and trigger the load method so that my lazyResults1 is loaded with data before initTable2() is called and overrides my filterMap ?

    These are just hacks because you're trying to have it both ways - to share and not share filters simultaneously.

    Let's say the filters were exposed in UI like this: Filters And the user changes the "Year" filter. Do you expect this change to affect some other table? Probably not. Because this set of filters belongs to this table only.