VictorGram
VictorGram

Reputation: 2661

JSP / STRUTS2: < display:table > : how to create table from nested list?

I am getting hard time generating a display:table on my JSP page that has 3 layers of nested list:

My main class is "ExpenditureTotalsByRegions" that has a list of "ExpenditureTotalsByTypes" "ExpenditureTotalsByTypes" has a list "ExpenditureTotalsByProjects"

The main problem is : Number of Rows and Columns in this table may vary as : number of regions will vary; number of types may vary / regions; number of projects vary /types

The JSP page gets a list of "ExpenditureTotalsByRegions" and should look like :

Region 1
----------------------------------------------------------
Types |  Project 1 | Project 2
----------------------------------------------------------
type1 | $1,000     | $2,000
type2 | $2,000     | $2,500


Region 2
----------------------------------------------------------
Types |  Project 1 | Project 3  |Project 4
----------------------------------------------------------
type3 | $3,000     | $4,000     | $5,000
type4 | $3,500     | $4,500     | $5,500
type5 | $3,550     | $4,550     | $5,550

(In the above example : 'Region 1', Region 2' are the name of the regions, 'type 1', 'type 2' etc are the name of the types and 'Project 1', 'Project2 ' etc are the name of the projects and $expenditures are the actual amounts spent in the projects)

The main class:

public class ExpenditureTotalsByRegions {

    protected String fRegion = null;
    protected List<ExpenditureTotalsByTypes> fTypeExpenditures = new ArrayList<ExpenditureTotalsByTypes>();

    public ExpenditureTotalsByRegions(String region,List<ExpenditureTotalsByTypes> typeExpenditures) {
        fRegion = region;
        fTypeExpenditures = typeExpenditures;
    }

    public String getRegion() {
        return fRegion;
    }

    public void setRegion(String region) {
        fRegion = region;
    }

    public List<ExpenditureTotalsByTypes> getTypeExpenditures() {
        return fTypeExpenditures ;
    }

    public void setTypeExpenditures( List<ExpenditureTotalsByTypes> typeExpenditures) {
    fTypeExpenditures = typeExpenditures;
    }

    }

Now, the 'ExpenditureType' class looks like:

    public class ExpenditureTotalsByTypes{

    protected String fTypeName;
    protected List<ExpenditureTotalsByProjects> fProjectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();


    public String getTypeName() {
    return fTypeName;
    }

    public void setTypeName(String typeName) {
        fTypeName= typeName;
    }


    public List<ExpenditureTotalsByProjects> getProjectExpenditures() {
        return fProjectExpenditures;
    }

    public void setProjectExpenditures( List<ExpenditureTotalsByProjects> projectExpenditures) {
        fProjectExpenditures = projectExpenditures;
    }

}

Now the "ExpenditureTotalsByProjects: class looks like:

public class ExpenditureTotalsByProjects {

    protected String fProjectName;
    protected Double fProjectExpenditure;


    public ExpenditureTotalsByProjects( String projectName, Double projectExpenditure)   {
        fProjectName = projectName;
        fProjectExpenditure = projectExpenditure;        
    }


    public String getProjectName() {        
        return fProjectName;
    }      

    public void setProjectName( String projectName ) {        
        fProjectName = projectName;
    }

    public Double getProjectExpenditure() {        
        return fProjectExpenditure;
    }      

    public void setProjectExpenditure( Double projectExpenditure ) {        
        fProjectExpenditure = projectExpenditure;
    }


}

My action class looks like :

public class ExpendituresTotalsReportByRegionsAction extends ActionBase {

    protected List<ExpenditureTotalsByRegions> fTableData = new ArrayList<ExpenditureTotalsByRegions>();

    public ExpendituresTotalsReportByRegionsAction(JpaTransactionManager transactionManager) {
        super(transactionManager);
    }

    @Override
    public String execute() throws Exception {
        if (fYear != 0) {
             fTableData = reportDao.getExpenditureTotalsReportByRegions(fYear);
         }

        return SUCCESS;
    }


    public List<ExpenditureTotalsByRegions> getTableData() {
        return fTableData;
    }

}

Now this is the way I am trying to construct the table on the JSP page and getting runtime error :

<body>
<div class="container">
<div class="prepend-1"><br>
    <display:table id="reportTable"
                   name="tableData"
                   requestURI=""
                   cellspacing="0px"
                   export="true"
                   class="displaytagTable">
        <display:setProperty name="decorator.media.html"
                             value="gov.doi.expenditures.decorator.TotalSpeciesDecorator"/>
        <display:setProperty name="decorator.media.rtf"
                             value="gov.doi.expenditures.decorator.ItextTotalSpeciesDecorator"/>
        <display:setProperty name="decorator.media.pdf"
                             value="gov.doi.expenditures.decorator.ItextTotalSpeciesDecorator"/>

            <display:caption class="titleText ">${reportTable.region}</display:caption>

            <c:forEach items="${reportTable.typeExpenditures}" var="typeList"> 

                <display:column title="Types" property="${typeList}.typeName"/>

                <c:forEach items="${typeList.projectExpenditures}" var="projectList">
                    <display:column title="${projectList}.projectName" property="${projectList}.projectExpenditure"/>
                </c:forEach>

            </c:forEach> 

    </display:table>
</div>
</div>

</body>

Test Data:

 List<ExpenditureTotalsByProjects> projectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();
         List<ExpenditureTotalsByTypes> TypesExpenditures = new ArrayList<ExpenditureTotalsByTypes>();
         List<ExpenditureTotalsByRegions> regionExpenditures = new ArrayList<ExpenditureTotalsByRegions>();


         //Test data for reg1 
         projectExpenditures.add(new ExpenditureTotalsByProjects("project1",1000.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project2",2000.00) );

         //1st Types with 2 projects in reg1
         ExpenditureTotalsByTypes sp1 = new ExpenditureTotalsByTypes();
         sp1.setTypes("Types1");
         sp1.setProjectExpenditures(projectExpenditures);
         TypesExpenditures.add(sp1);


         //2nd Types with 2 projects in reg1
         projectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();
         projectExpenditures.add(new ExpenditureTotalsByProjects("project1",1500.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project2",2500.00) );

         ExpenditureTotalsByTypes sp2 = new ExpenditureTotalsByTypes();
         sp2.setTypes("Types2");
         sp2.setProjectExpenditures(projectExpenditures);
         TypesExpenditures.add(sp2);


         //regionExpenditures.add(new ExpenditureTotalsByRegions("reg1",TypesExpenditures));

         tableData.add(new ExpenditureTotalsByRegions("reg1",TypesExpenditures));

         //Test data for reg2 
         TypesExpenditures = new ArrayList<ExpenditureTotalsByTypes>();

         projectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();
         projectExpenditures.add(new ExpenditureTotalsByProjects("project3",3000.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project4",4000.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project5",5000.00) );

         sp1 = new ExpenditureTotalsByTypes();
         sp1.setTypes("Types3");
         sp1.setProjectExpenditures(projectExpenditures);
         TypesExpenditures.add(sp1);

         projectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();
         projectExpenditures.add(new ExpenditureTotalsByProjects("project3",3500.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project4",4500.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project5",5500.00) );

         sp2 = new ExpenditureTotalsByTypes();
         sp2.setTypes("Types4");
         sp2.setProjectExpenditures(projectExpenditures);
         TypesExpenditures.add(sp2);

         projectExpenditures = new ArrayList<ExpenditureTotalsByProjects>();
         projectExpenditures.add(new ExpenditureTotalsByProjects("project3",3550.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project4",4550.00) );
         projectExpenditures.add(new ExpenditureTotalsByProjects("project5",5550.00) );

         ExpenditureTotalsByTypes sp3 = new ExpenditureTotalsByTypes();
         sp3.setTypes("Types5");
         sp3.setProjectExpenditures(projectExpenditures);
         TypesExpenditures.add(sp3);


         tableData.add(new ExpenditureTotalsByRegions("reg2",TypesExpenditures));

Getting error :"java.lang.RuntimeException: java.lang.RuntimeException: javax.servlet.jsp.JspException: Error looking up property" But I also need help with the table construction with 'forEach'. Please help

Let me know if you need more information. Thanks in advance.

Upvotes: 0

Views: 6198

Answers (1)

VictorGram
VictorGram

Reputation: 2661

One way to do this is :

<body>
<div class="container">
<div class="prepend-1"><br>
    <c:forEach items="${tableData}" var="regionList"> 
        <display:table id="TypeExpenditures"
                    name="${regionList.typeExpenditures}"
                    requestURI=""
                    cellspacing="0px"
                    export="true"
                    class="displaytagTable">


                <display:caption class="titleText ">${regionList.region}</display:caption>
                <display:column title="Types" property="typeName"/>

                <c:forEach items="${TypeExpenditures.projectExpenditures}" var="projectList"> 
                    <display:column title="${projectList.projectName}"  class='alignRight'>
                       $ ${projectList.projectExpenditure}
                    </display:column>
                </c:forEach>


        </display:table>
    </c:forEach>
</div>
</div>

</body>

Upvotes: 1

Related Questions