1 Reply Latest reply on Mar 28, 2013 1:21 PM by Peter Hinds

    rich faces rich:dataTable missing rows with child rich:dataTable

    Peter Hinds Newbie

      I have found that when rich:dataTable objects get nested, the rows in one of the first sub-tables do not get rendered on the resulting webpage. Has anybody found this before or can anybody suggest a solution?

       

      I have created a dummy jsf page and backing bean that demonstrates my problem. Apologies if this is a long post but I think I'm better off giving proper detail.

       

      In the example I created 4 nested datatables (see jsf below), where each datatable is used to display an object in the following hierarchy:

       

      Farm

      --Field

        --Animal

          --Tag

       

       

      Each item in the hierarchy has three children (so each farm has 3 fields, each field has 3 animals and each animal has 3 tags). Given the code below, I would expect the tables to be displayed as follows:

       

      farm1

      --field1

        --animal1

          --tag1

          --tag2

          --tag3

        --animal2

          --tag4

          --tag5

          --tag6

        --animal3

          --tag7

          --tag8

          --tag9

      --field2

        --animal4

          --tag10

          --tag11

          --tag12

        --animal5

          --tag13

          --tag14

          --tag15

        --animal6

          --tag16

          --tag17

          --tag18

      --field3

        --animal7

      etc.

       

      etc.

       

      However, what is actually rendered is the following (i.e. the animals in field1 are not listed):

       

      farm1

      --field1 (the animals are not listed for this field)

      --field2

        --animal4

          --tag10

          --tag11

          --tag12

        --animal5

          --tag13

          --tag14

          --tag15

        --animal6

          --tag16

          --tag17

          --tag18

      --field3

        --animal7

      etc.

       

       

      I can see from the debug that the backing bean has the correct data so I don't think it's a data issue.

       

      If I remove the last nested dataTable from the jsf page (marked 'TROUBLESOME TABLE' in the jsf below), then it will render correctly. For example it will display as:

       

      farm1

      --field1

        --animal1

        --animal2

        --animal3

      --field2

        --animal4

        --animal5

        --animal6

      --field3

        --animal7

      etc.

       

      The jsf page looks like this:

      {code:xml}<ui:define name="body">

          <a4j:form id="coOpForm">

              <rich:dataTable id="farmsTable" value="#{coOpBean.farms}" var="farmVar" width="100%">

                  <rich:column>

                      <f:facet name="header">Farm Name</f:facet>

                      <h:outputText value="#{farmVar.name}" />

                  </rich:column>

       

                  <rich:column breakBefore="true" colspan="2">

                      <rich:dataTable id="fieldsTable" var="fieldVar" value="#{farmVar.fields}" width="50%">

                          <rich:column>

                              <f:facet name="header">Fields in #{farmVar.name}</f:facet>

                              <h:outputText value="#{fieldVar.fieldName}" />

                          </rich:column>

       

                          <rich:column breakBefore="true" colspan="3">

                              <rich:dataTable id="animalsTable" var="animalVar" value="#{fieldVar.animals}" width="50%">

                                  <rich:column>

                                      <f:facet name="header">Animals in #{fieldVar.fieldName} in #{farmVar.name}</f:facet>

                                      <h:outputText value="#{animalVar.name}" />

                                  </rich:column>

       

                                  <!-- START OF TROUBLESOME TABLE -->

                                  <rich:column breakBefore="true" colspan="4">

                                      <rich:dataTable id="tagsTable" var="tagVar" value="#{animalVar.tags}" width="50%">

                                          <rich:column>

                                              <f:facet name="header">Tags for #{animalVar.name} in #{fieldVar.fieldName} in #{farmVar.name}</f:facet>

                                              <h:outputText value="#{tagVar.code}" />

                                          </rich:column>

                                      </rich:dataTable>

                                  </rich:column>

                                  <!-- END OF TROUBLESOME TABLE -->

       

                              </rich:dataTable>

                          </rich:column>

                      </rich:dataTable>

                  </rich:column>

              </rich:dataTable>

          </a4j:form>

      </ui:define>

      {code}

       

      The backing bean and associated classes look like this:

       

      CoOpBean.java:

       

      {code}

      @Component("coOpBean") 

      @Scope(WebApplicationContext.SCOPE_SESSION)

      public class CoOpBean {

       

       

      private static final Log logger = LogFactory.getLog(CoOpBean.class);

       

       

      List<Farm> farms;

      String name;

       

      /**

      * @return the farms

      */

      public List<Farm> getFarms() {

          return farms;

      }

      /**

      * @return the name

      */

      public String getName() {

          return name;

      }

      /**

      * @param farms the farms to set

      */

      public void setFarms(List<Farm> farms) {

          this.farms = farms;

      }

      /**

      * @param name the name to set

      */

      public void setName(String name) {

          this.name = name;

      }

      }

      {code}

      Farm.java:

      {code}

      public class Farm {

       

      private static int counter = 1;

       

      private final String name;

      private final List<Field> fields;

       

      public Farm(){

          name = "farm" + counter++;

          fields = new ArrayList<Field>();

          for (int i = 0; i < 3; i++){

              fields.add(new Field());

          }

      }

       

      /**

      * @return the name

      */

      public String getName() {

          return name;

      }

      /**

      * @return the fields

      */

      public List<Field> getFields() {

          return fields;

      }

       

       

      }

      {code}

      Field.java:

      {code}

      public class Field {

       

      private static int counter = 1;

       

      private String fieldName;

      private List<Animal> animals;

       

      public Field(){

          fieldName = "field" + counter++;

          animals = new ArrayList<Animal>();

          for (int i = 0; i < 3; i++){

              animals.add(new Animal());

          }

      }

       

       

      /**

      * @return the fieldName

      */

      public String getFieldName() {

          return fieldName;

      }

      /**

      * @return the animals

      */

      public List<Animal> getAnimals() {

          return animals;

      }

       

      }

      {code}

      Animal.java:

      {code}

      public class Animal {

       

      private static int counter = 1;

       

      private final String name;

      private final List<Tag> tags;

       

      public Animal(){

          name = "animal" + counter++;

          tags = new ArrayList<Tag>();

          for (int i = 0; i < 3; i++){

              tags.add(new Tag());

          }

      }

       

       

      /**

      * @return the name

      */

      public String getName() {

          return name;

      }

      /**

      * @return the tags

      */

      public List<Tag> getTags() {

          return tags;

      }

       

       

      }

      {code}

      Tag.java:

      {code}

      public class Tag {

       

      private static int counter = 1;

       

      /**

      * @param code

      */

      public Tag() {

          super();

          this.code = "tag" + counter++;

      }

      private final String code;

      /**

      * @return the code

      */

      public String getCode() {

          return code;

      }

       

      }

      {code}