Although Thymeleaf provides an easy way to iterate over List or Map objects but if one doesn't know the exact syntax for iteration then it could be tricky and one might get surprising results. Today we would discuss how to iterate over a List or Map object in Thymeleaf using th:each attribute.
Table Of Content
1. Introduction
2. Iterate Over List Object
3. Iterate Over Map Object
4. Keeping Iteration Status
5. Conclusion
One could use Thymeleaf's provided th:each attribute to iterate over List or Map objects. One could iterate below objects using th:each attribute:
Let's understand it by an example. Suppose we have a small Product Search Utility that's implemented by Thymeleaf. Here, products is the model attribute that contains the Product List object.
Again let's take an example. Suppose we would like to iterate over a Map Object something like
One could keep track of their iteration using the status variable. The only constraint is that the status variable will only be available inside the fragment of code defined by the tag holding the th:each attribute. Status variables contain the following data:
If one don’t explicitly set a status variable then Thymeleaf will always create one for us by suffixing Stat to the name of the iteration variable:
Now we know how to iterate and access values inside a List or Map Object in Thymeleaf. Although the iteration mechanism is same for all the objects whether it's List or Map but accessing values inside a List or Map is slightly different.
Table Of Content
1. Introduction
2. Iterate Over List Object
3. Iterate Over Map Object
4. Keeping Iteration Status
5. Conclusion
1. Introduction
One could use Thymeleaf's provided th:each attribute to iterate over List or Map objects. One could iterate below objects using th:each attribute:
- Any object implementing java.util.Iterable
- Any object implementing java.util.Map
- Any array
- Any other object will be treated as if it were a single-valued list containing the object itself.
2. Iterate Over List Object
Let's understand it by an example. Suppose we have a small Product Search Utility that's implemented by Thymeleaf. Here, products is the model attribute that contains the Product List object.
<h2>Product Search</h2> <div style="margin: 30px;"> <form th:action="@{/product-search}"> <section> <label> <input type="text" id="searchbox" name="searchbox" placeholder="enter product ID / Product Label" required style="width:500px;" minlength=3> </label> <input type="submit" value="Search" id="submit"> </section> <div th:if="${not #lists.isEmpty(products)}"> <h3>Search Results</h3> <table> <thead><tr><th>Product ID</th><th>Product Label</th><th>Product Description</th></tr></thead> <th:block th:each="product : ${products}"> <tr> <td><a th:href="@{/productdetails(id=${product.id})}" th:text="${product.id}">Product ID..</a></td> <td th:text="${product.label}">Product Label..</td> <td th:text="${product.description}">Product Description..</td> </tr> </th:block> </table> </div> <div th:if="${#lists.isEmpty(products)}"> <h3>Search Results</h3> Try Again!! Using some other Product ID or Product Label </div> </form> </div> </div>
3. Iterate Over Map Object
Again let's take an example. Suppose we would like to iterate over a Map Object something like
- Map<Integer, String> reportMap: Suppose we have populated a Map object while uploading a CSV file. The Key here is the row number in the CSV file and Value is the string containing message in the format <Success|Failed - Reason for Success or Failure of Upload >
<div th:if="${not #lists.isEmpty(reportMap)}"> <table> <tr><td>Row No</td><td>Status</td><td>Message</td></tr> <th:block th:each="row : ${reportMap}"> <tr> <td th:text="${row.key}">Row No</td> <td th:text="${#strings.listSplit(row.value,'-')[0]}">Status</td> <td th:text="${#strings.listSplit(row.value,'-')[1]}">Message</td> </tr> </th:block> </table> </div>
- Map<String, List<String>> stateToDistrictMap: Suppose we have a Map object which have State as it's Key and List of districts in a State as it's Value. Then how would we iterate over this kind of Map object.
<div th:if="${not #lists.isEmpty(stateToDistrictMap)}"> <table> <tr><td>State</td><td>Districts</td></tr> <th:block th:each="state : ${stateToDistrictMap}"> <tr> <td th:text="${state.key}">State</td> <th:block th:each="district : ${state.value}"> <td th:text="${district}">District</td> </th:block> </tr> </th:block> </table> </div>
4. Keeping iteration Status
One could keep track of their iteration using the status variable. The only constraint is that the status variable will only be available inside the fragment of code defined by the tag holding the th:each attribute. Status variables contain the following data:
- The current iteration index, starting with 0. This is the index property.
- The current iteration index, starting with 1. This is the count property.
- The total amount of elements in the iterated variable. This is the size property.
- The iter variable for each iteration. This is the current property.
- Whether the current iteration is even or odd. These are the even/odd boolean properties.
- Whether the current iteration is the first one. This is the first boolean property.
- Whether the current iteration is the last one. This is the last boolean property.
<table> <thead><tr><th>Product ID</th><th>Product Label</th><th>Product Description</th></tr></thead> <tr th:each="product,iterStat : ${products}" th:class="${iterStat.odd}? 'odd'"> <td><a th:href="@{/productdetails(id=${product.id})}" th:text="${product.id}">Product ID..</a></td> <td th:text="${product.label}">Product Label..</td> <td th:text="${product.description}">Product Description..</td> </tr> </table>
<table>
<thead><tr><th>Product ID</th><th>Product Label</th><th>Product Description</th></tr></thead>
<tr th:each="product : ${products}" th:class="${productStat.odd}? 'odd'"><td><a th:href="@{/productdetails(id=${product.id})}" th:text="${product.id}">Product ID..</a></td>
<td th:text="${product.label}">Product Label..</td>
<td th:text="${product.description}">Product Description..</td>
</tr>
</table>
5. Conclusion
Now we know how to iterate and access values inside a List or Map Object in Thymeleaf. Although the iteration mechanism is same for all the objects whether it's List or Map but accessing values inside a List or Map is slightly different.
- For List : Iteration variable would directly give the value inside a List whereas
- For Map: {iteration_variable.key} would give the Map's key and {iteration_variable.value} would give the corresponding value of the Key. If the {iteration_variable.value} is a List then again one could use th:each attribute to iterate over this List as per the requirement.
3.b.) List is not coming on new line ,Can you please help ???
ReplyDeleteList is not coming on new line- It means although the list are getting populated but it's values are not coming in new line. Depending upon your requirement, you can use br tag or use ul/ol or use CSS.
DeleteAmigos necesito una solución para enviar la información de un table al Controller que se envié como una List.
ReplyDeleteUsing Google Translator, I got your query i.e. "Friends I need a solution to send the information of a table to the Controller that was sent as a List.".
DeleteI understand that, you would like to send the information of a table to the Controller.
Assumption: On Click of a button you would like to send the table information.
Solution: On click event, gather table data using Javascript/jQuery and then use AXIOS(promise based HTTP client) POST to send this data to controller. You have to use @RequestBody annotation in the controller layer.