1

I´m looking for a solution for my problem.

I have a table that needs to be like this.

--------------------------------------------------------------|
        |       |                   Title 3                   |
Title 1 |Title 2|---------------------------------------------|
        |       | SubTitle 1 |SubTitle 2|SubTitle 3|SubTitle 4|
--------------------------------------------------------------|
        |       |            |          |          |          |
Val A1  | ValB1 |    ValC1   |   ValC1  |   ValC1  |  ValC1   |
        |       |            |          |          |          |
        |-------|------------|----------|----------|----------|
        |       |            |          |          |          |
        | ValB2 |    ValC2   |   ValC2  |   ValC2  |  ValC2   |
        |       |            |          |          |          |
--------------------------------------------------------------|
        |       |            |          |          |          |
        |       |            |          |          |          |
Val A2  | ValB3 |    ValC3   |   ValC3  |   ValC3  |  ValC3   |
        |       |            |          |          |          |
        |       |            |          |          |          |
----------------------------------------------------------------

My goal it´s to make a table appear like I did above.

I´m using JSF and Primefaces 4.0.

I have this struture of class.

Class Master {

  private List<ClassA> classesA

  // getter and setter

}


Class A {

      private List<ClassB> classesB

      // getter and setter and fields

}


Class B {

      private List<ClassC> classesC

      // getter and setter and fields

}


Class C {

  // getter and setter and fields

}

So I tried to make with two datatables or using ui:repeat, but I don´t know what´s going to be the best choose. And the titles the owns like this.

Class A have title 1, Class B have title 2 and Class C have title 3 and subtitle 1,2,3 and 4.

Or use binding.

To be more easier to understand I put a picture about how I need to create the table.

enter image description here

Can someone help me?

Thanks

BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
user3503888
  • 435
  • 5
  • 17

2 Answers2

2

If you are sure that the object structure won't change in future then simple solution is to go for ui:repeat with nested tables, rowspan and colspan. But if the object structure often changes and you need to do it more than one time then go for custom component.If you need olap features then i suggest you to go for pivot4j or something similar.

update: see the xhtml below it creates the body of the table.

<table border="4" cellspacing="4" cellpadding="10">
        <tr>
            <th rowspan="2">A</th>
            <th rowspan="2">B</th>
            <th colspan="4">C</th>
        </tr>
        <tr>
            <th>p1</th>
            <th>p2</th>
            <th>p3</th>
            <th>p4</th>
        </tr>
        <ui:repeat var="classa" value="#{master.classesA}" varStatus="astat">
            <ui:repeat var="classb" value="#{classa.classesB}"  varStatus="bstat">
                <ui:repeat value="#{classb.classesC}" var="classc" varStatus="cstat">

                    <tr>
                        <h:panelGroup rendered="#{bstat.index eq 0 and cstat.index eq 0}">
                            <td rowspan="#{classa.colSpan}" >
                                <h:outputText value="#{classa.property}" />
                            </td>
                        </h:panelGroup>
                        <h:panelGroup rendered="#{cstat.index eq 0}">
                            <td rowspan="#{classb.classesC.size()}">                                                   
                                <h:outputText value="#{classb.property}" />
                            </td>
                        </h:panelGroup>

                        <td>
                            <h:outputText value="#{classc.prop1}" />
                        </td>
                        <td>
                            <h:outputText value="#{classc.prop2}" />
                        </td>
                        <td>
                            <h:outputText value="#{classc.prop3}" />
                        </td>
                        <td>
                            <h:outputText value="#{classc.prop4}" />
                        </td>
                    </tr>  
                </ui:repeat>

            </ui:repeat>

        </ui:repeat>
    </table>

and classes should look like this

 public class A {
    private List<B> classesB;
    private String property;

    public List<B> getClassesB() {
        return classesB;
    }

    public void setClassesB(List<B> classesB) {
        this.classesB = classesB;
    }

    public A(String pro) {
    classesB= new ArrayList<B>();
    property=pro;
    }

    public void addClassB(B b){
        classesB.add(b);
    }

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }

    public int getColSpan(){
        int size=0;
        for(B b : classesB){
            size+=b.getClassesC().size();
        }
        return size;
    }

}

public class B {
    private List<C> classesC;
    private String property;

    public B(String pro) {
        this.classesC = new ArrayList<C>();
        this.property=pro;
    }



    public List<C> getClassesC() {
        return classesC;
    }

    public void setClassesC(List<C> classesC) {
        this.classesC = classesC;
    }


    public void addClassC(C c){
        classesC.add(c);
    }

    public String getProperty() {
        return property;
    }

    public void setProperty(String property) {
        this.property = property;
    }


}
public class C {
    private String prop1;
    private String prop2;
    private String prop3;
    private String prop4;

    public C(String prop1, String prop2, String prop3, String prop4) {
        this.prop1 = prop1;
        this.prop2 = prop2;
        this.prop3 = prop3;
        this.prop4 = prop4;
    }

    public void setProp1(String prop1) {
        this.prop1 = prop1;
    }

    public void setProp2(String prop2) {
        this.prop2 = prop2;
    }

    public void setProp3(String prop3) {
        this.prop3 = prop3;
    }

    public void setProp4(String prop4) {
        this.prop4 = prop4;
    }

    public String getProp1() {
        return prop1;
    }

    public String getProp2() {
        return prop2;
    }

    public String getProp3() {
        return prop3;
    }

    public String getProp4() {
        return prop4;
    }


}

Test data in Master class.

private List<A> classesA;

@PostConstruct
public void init() {
    classesA = new ArrayList<A>();
    A a1 = new A("a1");
    A a2 = new A("a2");
    classesA.add(a1);
    classesA.add(a2);

    B b11 = new B("b11");
    B b12 = new B("b12");
    B b21 = new B("b21");

    a1.addClassB(b11);
    a1.addClassB(b12);
    a2.addClassB(b21);

    C c111 = new C("a", "b", "c", "d");
    C c112 = new C("d", "e", "f", "g");
    C c121 = new C("g", "h", "i", "j");
    C c211 = new C("k", "l", "m", "n");
    C c212 = new C("o", "p", null, null);

    b11.addClassC(c111);
    b11.addClassC(c112);
    b12.addClassC(c121);
    b21.addClassC(c211);
    b21.addClassC(c212);
}

public List<A> getClassesA() {
    return classesA;
}

public void setClassesA(List<A> classesA) {
    this.classesA = classesA;
}
Dev Khadka
  • 154
  • 1
  • 9
  • Thanks for your answer. But I don´t know how to do it, I tried to use ui:repeat but don´t now to generate de row for de `title 2` and `title 3` because one `row` in `title 2` can have many `rows` in `title 3`. Can you show me one example? – user3503888 Sep 08 '14 at 13:06
  • I put a picture to you understand – user3503888 Sep 08 '14 at 20:06
  • 1
    @user3503888 the above code creates similar output as in the picture. Ignore every thing just foucs on how ui:repeat tr, td , td with rowspan and panelgroup are used. – Dev Khadka Sep 09 '14 at 02:16
  • I test your code but didn´t show formated as a table. – user3503888 Sep 09 '14 at 12:43
  • add above ui:repeat and
    below ui:repaat. Also add th
    – Dev Khadka Sep 09 '14 at 12:52
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/60902/discussion-between-dev-khadka-and-user3503888). – Dev Khadka Sep 09 '14 at 14:06
0

You can use dataTable with subTable (and you can add columns in row if needed).

Vasil Lukach
  • 3,658
  • 3
  • 31
  • 40
  • Do you have a concrete example? – user3503888 Sep 09 '14 at 15:58
  • I have my own RichFaces code with similar table. Here is simple [subtable example](http://stackoverflow.com/questions/17488066/filling-columns-with-the-right-data-in-subtable-doesnt-work-jsf-primefaces) or [nested tables](http://stackoverflow.com/questions/13649578/how-to-represent-nested-data-in-primefaces-datatable) in PrimeFaces. – Vasil Lukach Sep 09 '14 at 18:30
  • My problem is, see it using inner `list`. – user3503888 Sep 09 '14 at 18:53