Issues with MasterDetail Level 2 dataTable paginator

Community Driven Extensions Project
Post Reply
kahlon1005
Posts: 41
Joined: 19 Jun 2013, 00:54

21 Nov 2013, 20:17

I am trying to reuse primefaces extension masterDetail component example 1 Basic navigation level by level. Everything works fine. But, when I am adding paginator="true" rows="2" to the datatables. Level 2 dataTable return no results on page 2. Also, when navigating back to page 1 of level 2 the results are lost.

I have not provided the code here because I am able to reproduce this issue with the same code as showcase. But, if any one needs the code or images, please let me know.
PrimeFaces 5.3 | Spark 2.1 | Wildfly 10.0 | Mojarra 2.2.0 | Eclipse | Prime Faces Extension 3.2.0 | Omnifaces 2.0 | Java 1.8

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

21 Nov 2013, 21:48

What steps do you do? I haven't understood. Do you go to the page 2 on the level 1 and then navigate to the level 2? I think you can try to set process / update in <p:ajax event="page" .../> to masterDetail.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

kahlon1005
Posts: 41
Joined: 19 Jun 2013, 00:54

22 Nov 2013, 03:17

The steps to reproduce this issue are

1. Go to sample page. Two records will appear as expected.
2. Click on 1st record football with 4 child records to navigate to level 2. Here on level 2, two of four records will appear as expected on page 1.
3. Click on paginator button 2. No records found, when 2 records were expected. (ERROR)
4. Now click paginator button 1. No records found there either. (ERROR)

Hope, this will help to sort out the issue.

Although, the code is not much different then the showcase example. I thought, it would be helpful to provide code in order to reproducing and fixing the issue. So, please find the code below.

My sample.xhtml

Code: Select all

<ui:composition template="/templates/layout.xhtml"
                xmlns="http://www.w3.org/1999/xhtml"
                xmlns:f="http://java.sun.com/jsf/core"
                xmlns:h="http://java.sun.com/jsf/html"
                xmlns:ui="http://java.sun.com/jsf/facelets"
                xmlns:p="http://primefaces.org/ui"
                xmlns:c="http://java.sun.com/jsp/jstl/core"
                xmlns:fn="http://java.sun.com/jsp/jstl/functions"
                xmlns:pe="http://primefaces.org/ui/extensions"
                xmlns:app="http://guard.com/facelets">

    <ui:define name="content">
            <h:form>
                <pe:masterDetail id="masterDetail" level="#{simpleMasterDetailController.currentLevel}">  

                    <pe:masterDetailLevel level="1" levelLabel="Sports">  
                        <p:dataTable id="sports" value="#{simpleMasterDetailController.sports}" var="sport" paginator="true" rows="2">  
                            <p:column headerText="Sport">  
                                <p:commandLink value="#{sport.name}">  
                                    <pe:selectDetailLevel contextValue="#{sport}"/>  
                                </p:commandLink>  
                            </p:column>  
                            <p:column headerText="Number of countries with leagues">  
                                <h:outputText value="#{fn:length(sport.countriesWithLeague)}"/>  
                            </p:column>  
                        </p:dataTable>  
                    </pe:masterDetailLevel>  

                    <pe:masterDetailLevel level="2" contextVar="sport" levelLabel="Countries having #{sport.name} leagues" >  
                        <p:dataTable id="countries" value="#{sport.countriesWithLeague}" var="country" paginator="true" rows="2">   
                            <p:column headerText="Country">  
                                <p:commandLink value="#{country.name}">  
                                    <pe:selectDetailLevel contextValue="#{country}"/>  
                                </p:commandLink>  
                            </p:column>  
                            <p:column headerText="Code">  
                                <h:outputText value="#{country.code}"/>  
                            </p:column>  
                        </p:dataTable>  
                    </pe:masterDetailLevel>  

                    <pe:masterDetailLevel level="3" contextVar="country" levelLabel="#{country.sport} leagues of #{country.name}">  
                        <p:dataTable id="leauges" value="#{country.leagues}" var="league">  
                            <p:column headerText="League">  
                                <h:outputText value="#{league.name}"/>  
                            </p:column>  
                            <p:column headerText="Number of teams">  
                                <h:outputText value="#{league.numberOfTeam}"/>  
                            </p:column>  
                        </p:dataTable>  
                        <h:panelGrid columns="2" style="margin-top: 10px">  
                            <p:commandButton value="Go to Sports" icon="ui-icon-arrowthickstop-1-w">  
                                <pe:selectDetailLevel level="1"/>  
                            </p:commandButton>  
                            <p:commandButton value="Go to Countries" icon="ui-icon-arrowthick-1-w">  
                                <pe:selectDetailLevel step="-1"/>  
                            </p:commandButton>  
                        </h:panelGrid>  
                    </pe:masterDetailLevel>  

                </pe:masterDetail> 
            </h:form>
   </ui:define>
</ui:composition>

SimpleMasterDetailController Bean

Code: Select all



package com.prime.myproject.controller;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.enterprise.context.SessionScoped;
import javax.inject.Named;


@Named
@SessionScoped 
public class SimpleMasterDetailController implements Serializable {  
  
    private static final long serialVersionUID = 20111120L;  
  
    private List<Sport> sports;  
    private int currentLevel = 1;  
  
    public SimpleMasterDetailController() {  
        if (sports == null) {  
            sports = new ArrayList<Sport>();  
  
            // football  
            List<Country> countries = new ArrayList<Country>();  
            Country country = new Country("Switzerland", "CH", "Football", getLeagues("Switzerland"));  
            countries.add(country);  
            country = new Country("England", "UK", "Football", getLeagues("England"));  
            countries.add(country);  
            country = new Country("Spain", "ES", "Football", getLeagues("Spain"));  
            countries.add(country);  
            country = new Country("Netherlands", "NL", "Football", getLeagues("Netherlands"));  
            countries.add(country);  
            sports.add(new Sport("Football", countries));  
  
            //basketball  
            countries = new ArrayList<Country>();  
            country = new Country("Germany", "DE", "Basketball", getLeagues("Germany"));  
            countries.add(country);  
            country = new Country("USA", "US", "Basketball", getLeagues("USA"));  
            countries.add(country);  
            country = new Country("Poland", "PL", "Basketball", getLeagues("Poland"));  
            countries.add(country);  
            sports.add(new Sport("Basketball", countries));  
  
            // ice hockey  
            countries = new ArrayList<Country>();  
            country = new Country("Russia", "RU", "Ice Hockey", getLeagues("Russia"));  
            countries.add(country);  
            country = new Country("Canada", "CA", "Ice Hockey", getLeagues("Canada"));  
            countries.add(country);  
            sports.add(new Sport("Ice Hockey", countries));  
        }  
    }  
  
    public List<Sport> getSports() {  
        return sports;  
    }  
  
    public int getCurrentLevel() {  
        return currentLevel;  
    }  
  
    public void setCurrentLevel(int currentLevel) {  
        this.currentLevel = currentLevel;  
    }  
  
    private List<League> getLeagues(String country) {  
        List<League> leagues = new ArrayList<League>();  
  
        leagues.add(new League(country + " SuperLeague", 20));  
        leagues.add(new League(country + " NotBadLeague", 15));  
        leagues.add(new League(country + " CrapLeague", 30));  
  
        return leagues;  
    }  
}  

Sport.java

Code: Select all



package com.prime.myproject.pojo;

import java.io.Serializable;
import java.util.List;


public class Sport implements Serializable {  
  
    private static final long serialVersionUID = 20111120L;  
  
    private String name;  
    private List<Country> countriesWithLeague;  
  
    public Sport(String name, List<Country> countriesWithLeague) {  
        this.name = name;  
        this.countriesWithLeague = countriesWithLeague;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public List<Country> getCountriesWithLeague() {  
        return countriesWithLeague;  
    }  
} 

League.java

Code: Select all


package com.prime.myproject.pojo;

import java.io.Serializable;


public class League implements Serializable {  
  
    private static final long serialVersionUID = 20111120L;  
  
    private String name;  
    private int numberOfTeam;  
  
    public League(String name, int numberOfTeam) {  
        this.name = name;  
        this.numberOfTeam = numberOfTeam;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public int getNumberOfTeam() {  
        return numberOfTeam;  
    }  
}

Country.java

Code: Select all



package com.prime.myproject.pojo;

import java.io.Serializable;
import java.util.List;


public class Country implements Serializable {  
  
    private static final long serialVersionUID = 20111120L;  
  
    private String name;  
    private String code;  
    private String sport;  
    private List<League> leagues;  
  
    public Country(String name, String code, String sport, List<League> leagues) {  
        this.name = name;  
        this.code = code;  
        this.sport = sport;  
        this.leagues = leagues;  
    }  
  
    public String getName() {  
        return name;  
    }  
  
    public String getCode() {  
        return code;  
    }  
  
    public String getSport() {  
        return sport;  
    }  
  
    public List<League> getLeagues() {  
        return leagues;  
    }  
}  

PrimeFaces 5.3 | Spark 2.1 | Wildfly 10.0 | Mojarra 2.2.0 | Eclipse | Prime Faces Extension 3.2.0 | Omnifaces 2.0 | Java 1.8

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

22 Nov 2013, 18:37

Ok. I will check it. But the problem is clear. You need a <p:ajax event="page" .../> with attached p:selectDetailLevel to the p:dataTable. Like in the 3. use case with p:ajax.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

22 Nov 2013, 20:16

I could reproduce the issue. You can fix it if you pass objects via bean and not via "contextValue" / "contextVar" approach. See other use cases.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

wy6688
Posts: 4
Joined: 09 Sep 2013, 22:39

22 Nov 2013, 22:06

I have the same issue, if the table paginated, the page will be empty if you click any page button for this table.
only when you go back upper level and then re-enter this level, the page will be displayed again.

User avatar
Oleg
Expert Member
Posts: 3805
Joined: 02 Oct 2009, 09:41
Location: Germany, Black Forest

25 Nov 2013, 13:31

This is because the object passed via "contextValue" / "contextVar" is not available in this case for the data table (it is saved in the request only). So, as I already suggested, the solution would be to pass objects via bean. Simple save the value for data table in a bean (via action) and don't use "contextValue" / "contextVar" approach.
PrimeFaces Cookbook (2. edition): http://ova2.github.io/primefaces-cookbook/ Learning Angular UI Development with PrimeNG: https://github.com/ova2/angular-develop ... th-primeng Blog: https://medium.com/@OlegVaraksin

djmj
Posts: 400
Joined: 16 Dec 2011, 01:23

16 Apr 2021, 23:22

Even if its an old thread i stumble upon this problem every few days.
There are two related problems with this component if we are using composite components. How, shall the "reusable" and "independent" composite component, know if its inside a masterdetail at first, and if its using contextVar?

Scope issue of MasterDetail

It should put the contextVar into the viewScope instead request scope which would fix all issues.

MasterDetail is a single view - multi request component and thus must use the view scope to store its variables.


SelectDetailLevel - should not check for master

My current workaround is optional rendering pe:selectDetailLevel on every ajax component which involves the whole composite tree.
For this i must pass, very cumbersome a flag "inMasterDetail" to all child components and render the selectDetailLevel using JSTL because the same component is used also not inside a MasterDetail. In this case it would throw an error.

My code is full of #{cc.attrs.inMasterDetail} this way to make it work.

Code: Select all

<c:if test="#{cc.attrs.inMasterDetail}">
	<pe:selectDetailLevel/> 
</c:if>
Primefaces: 11.0.0 RC2
Primefaces-Extension: 11.0.0
PrimeFaces-Mobile: 11.0
OmniFaces: 3.11
Jsf: Mojarra 2.3.8
Server: Glassfish 5.1.0

Post Reply

Return to “Extensions”

  • Information
  • Who is online

    Users browsing this forum: No registered users and 6 guests