0

I would like to display some data where I need to iterate with two nested DataTables (using Mojarra 2.2.13 and Primefaces 6.0). The inner table has a dynamic amount of columns. Since the objects I need to iterate over for the columns are of two different business objects I need two separate <p:columns/> tags.

BackingBean.java

@Named
@ViewScoped
public class BackingBean implements Serializable {
    private static final long serialVersionUID = 1L;

    private List<Family> families;
    private List<String> countries;

    public void generateFamilies() {
        this.families = new ArrayList<Family>();

        Family f = new Family("Beta");
        f.getCars().add("Mercedes");
        f.getCars().add("Porsche");
        f.getCars().add("VW");
        f.getCars().add("Dodge");
        f.getPersons().add("he");
        f.getPersons().add("she");
        families.add(f);

        f = new Family("Alpha");
        f.getCars().add("BMW");
        f.getPersons().add("he");
        f.getPersons().add("she");
        families.add(f);
    }

    private void generateCountries() {
        this.countries = new ArrayList<String>();
        this.countries.add("Germany");
        this.countries.add("England");
        this.countries.add("Spain");
    }

    public List<Family> getFamilies() {
        if (null == families) {
            generateFamilies();
        }
        return families;
    }

    public List<String> getCountries() {
        if (null == countries) {
            generateCountries();
        }
        return countries;
    }

    public class Family {
        private String name;
        private List<String> persons;
        private List<String> cars;

        public Family(String name) {
            this.name = name;
            this.persons = new ArrayList<String>();
            this.cars = new ArrayList<String>();
        }

        public String getName() {
            return name;
        }

        public List<String> getPersons() {
            return persons;
        }

        public List<String> getCars() {
            return cars;
        }
    }

}

index.xthml

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml"
    xmlns:h="http://java.sun.com/jsf/html"
    xmlns:p="http://primefaces.org/ui"
    xmlns:c="http://java.sun.com/jsp/jstl/core">

<h:head>
    <title>DataTable BUG</title>
</h:head>

<body>
    <h:form id="form">
        <p:dataTable id="families" value="#{backingBean.families}" var="family">
            <p:column headerText="Families">
                <h3>#{family.name}</h3>
                <p:dataTable id="persons" value="#{family.persons}" var="person">
                    <p:column headerText="Name">
                        Does #{person} ...
                    </p:column>
                    <p:columns value="#{family.cars}" var="car" headerText="#{car}">
                        ... have insurance for the #{car}? 
                    </p:columns>
                    <p:columns value="#{backingBean.countries}" var="country" headerText="#{country}">
                        ... have insurance for #{country}?
                    </p:columns>
                </p:dataTable>
            </p:column>    
       </p:dataTable>
    </h:form>   
</body>
</html>

The result I get is that all inner tables (id=persons) will look the same (see image 1). The first inner table dictates the amount of columns (8 in this example). The second row of the outer table (id=families) should display only 5 columns for the inner table (only the BMW column). But is still displays all the columns from the first row. If I remove one p:columns everything works as expected (see image 2).

I looked up the documentation for p:dataTable and there seem to be no limitations that only one p:columns per p:dataTable is allowed. Am I missing something?

Two dynamic column blocks One dynamic column block

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
cmoetzing
  • 742
  • 3
  • 16

1 Answers1

0

You are right, I can reproduce this scenario. Maybe it's a PrimeFaces bug or multiple p:columns are just not supported. As a work around you could use c:forEach for the country list:

  <c:forEach items="#{backingBean.countries}" var="country">
     <p:column headerText="#{country}">
        ... have insurance for #{country}
     </p:column>
  </c:forEach>
Alex Fire
  • 707
  • 3
  • 7
  • Yes, for this 'simple' example it would work. But as soon as the list is dynamic and needs to be fetched from `Family` (which is the scenario from the application where I found this) it won't (unfortunately). – cmoetzing Mar 02 '17 at 12:13
  • Yes, that's right, see [here](http://stackoverflow.com/questions/29021036/why-can-cforeach-or-uirepeat-not-access-pdatatable-var) for explanation. – Alex Fire Mar 03 '17 at 21:58