matgr
matgr

Reputation: 117

Relating List-of-List Spring-Boot Model Fields to Thymeleaf

I'm new to StackOverflow and have hated the idea of asking a question as I've seen so many shot down in flames as being asked poorly or answered elsewhere, but I don't seem to be able to find an answer no matter how hard I try. Here goes!

I have the following models in a Spring-Boot application:

public class Timesheet {

    //some straightforward getters/setters (e.g. id)

    public List<TimesheetRow> getTimesheetRow() {
        return timesheetRow;
    }

    public void setTimesheetRow(List<TimesheetRow> timesheetRow) {
        this.timesheetRow = timesheetRow;
    }
}

public class TimesheetRow {

    //some straightforward getters/setters (e.g. rowId)

    public List<TimesheetTask> getTimesheetTask() {
        return timesheetTask;
    }

    public void setTimesheetTask(List<TimesheetTask> timesheetTask) {
        this.timesheetTask = timesheetTask;
    }
}

public class TimesheetTask {

    //some straightforward getters/setters (e.g. taskId)

}

Hopefully so far so good, and I've written the Service and DAO layers to get the appropriate data back - I've manually written some data to the DB and validated that when I call the access methods, the right data is being returned.

However, an issue presents itself when I try to render this data using Thymeleaf. The code I have so far is thus (please excuse the terrible formatting, I'm just trying to get it working before I tidy up the table structure):

 <table>
     <tr th:each="row,iteration : ${timesheet.timesheetRow}">
         <td>
              <!--This part actually works. Huzzah!-->
              <input type="hidden" th:field="*{timesheetRow[__${iteration.index}__].id}"/>
              <input type="text" th:field="*{timesheetRow[__${iteration.index}__].projectId}" />
         </td> 
         <td>
         <span th:each="task,iteration2 : ${row.timesheetTask}">

              <!--These two lines are particularly poor, and are just my futile attempts at trying different ways to try and reference appropriately. Sorry.-->
              <input type="hidden" th:field="*{timesheetRow.get(__${iteration.index}__).getTimesheetTask.get(__${iteration2.index}__).getId()}"/>
              <input type="text" th:field="*{task.work}"/>

         </span>
         </td>
     </tr>
 </table>

I've attempted to solve this myself based off the following answers:

nested (double) loop with thymeleaf

How to bind an object list with thymeleaf?

...but while the first talks about going "two layers deep," I don't seem to be able to access the second layer down, i.e. the Timesheet Tasks in each individual Timesheet Row.

As far as I can tell, the conceptual code I'm attempting is something along the lines of

timesheet.timesheetRow[0].timesheetTask[0] 

or similar, but this is obviously horrific syntax which Java doesn't recognise so there's every chance ThymeLeaf is just as unlikely to do anything with it.

This may be entirely impossible using ThymeLeaf and I'm considering refactoring the code to just add all of the Task fields to the Timesheet Row, but is this possible? If so, how might it be accomplished?

Many thanks in advance, and any feedback about how I might improve my asking technique for the dark day when I have to ask another question arrives will be much appreciated!

Upvotes: 3

Views: 326

Answers (1)

Azocan Kara
Azocan Kara

Reputation: 243

Here is the correct syntax :

<table>
     <tr th:each="row,iteration : ${timesheet.timesheetRow}">
         <td>
              <input type="hidden" th:field="*{timesheetRow[__${iteration.index}__].id}"/>
              <input type="text" th:field="*{timesheetRow[__${iteration.index}__].projectId}" />
         </td> 
         <td>
         <span th:each="task,iteration2 : ${row.timesheetTask}">
              <input type="hidden" th:field="*{timesheetRow[__${iteration.index}__].timesheetTask[__${iteration2.index}__].id}"/>
              <input type="text" th:field="*{timesheetRow[__${iteration.index}__].timesheetTask[__${iteration2.index}__].work}"/>

         </span>
         </td>
     </tr>
</table>

Upvotes: 1

Related Questions