o7planning

Thymeleaf Loops Tutorial with Examples

  1. Loop
  2. Examples with the th:each loop

1. Loop

Thymeleaf provides you with 'each' loop, and you can use it through the th:each attribute. This is the only loop supported in Thymeleaf.
This loop accepts some types of data such as:
  • The objects that implement interface java.util.Iterable.
  • The objects that implement interface java.util.Map.
  • Arrays
The simplest syntax of th:each:
<someHtmlTag th:each="item : ${items}"> 
     ....
</someHtmlTag>
The <th:block> tag is a virtual tag in the Thymeleaf, it does not correspond to any HTML tags, but it is useful in many cases, for example, you can set the th:each attribute in this tag.
<th:block th:each="item : ${items}">
     ....
</th:block>
Simple example with th:each loop:
(Java Spring)
@RequestMapping("/loop-simple-example")
public String loopExample1(Model model) {
    String[] flowers = new String[] { "Rose", "Lily", "Tulip", "Carnation", "Hyacinth" };
    model.addAttribute("flowers", flowers);
    return "loop-simple-example";
}
loop-simple-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
</head>
<body>
    <h1>th:each</h1>
    <ul>
        <th:block th:each="flower : ${flowers}">
            <li th:utext="${flower}">..</li>
        </th:block>
    </ul>
</body>
</html>
Output:
(Output)
<!DOCTYPE HTML>
<html>
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
</head>
<body>
    <h1>th:each</h1>
    <ul>
            <li>Rose</li>
            <li>Lily</li>
            <li>Tulip</li>
            <li>Carnation</li>
            <li>Hyacinth</li>
    </ul>
</body>
</html>
The full syntax of th:each includes 2 variables: item variable and state variable.
<someHtmlTag th:each="item, iState : ${items}">
       .....
</someHtmlTag>

<!-- OR: -->

<th:block th:each="item, iState : ${items}">
       .....
</th:block>
State variable is an useful object. It contains the information telling you about the current state of loop, for example, the number of items of loop, current index of loop, ...
Below is a list of properties of state variable:
Property
Description
index
The current iteration index, starting with 0 (zero)
count
The number of elements processed so far
size
The total number of elements in the list
even/odd
Checks if the current iteration index is even or odd
first
Checks if the current iteration is the first one
last
Checks if the current iteration is the last one
Example with th:each and state variable:
(Java Spring)
@RequestMapping("/loop-example")
public String loopExample(Model model) {
    String[] flowers = new String[] { "Rose", "Lily", "Tulip", "Carnation", "Hyacinth" }; 
    model.addAttribute("flowers", flowers);
    return "loop-example";
}
loop-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>table th, table td {padding: 5px;}</style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>index</th>
          <th>count</th>
          <th>size</th>
          <th>even</th>
          <th>odd</th>
          <th>first</th>
          <th>last</th>
          <th>Flower Name</th>
        </tr>
        <tr th:each="flower, state : ${flowers}">
          <td th:utext="${state.index}">index</td>
          <td th:utext="${state.count}">count</td>
          <td th:utext="${state.size}">size</td>
          <td th:utext="${state.even}">even</td>
          <td th:utext="${state.odd}">odd</td>
          <td th:utext="${state.first}">first</td>
          <td th:utext="${state.last}">last</td>
          <td th:utext="${flower}">Flower Name</td>
        </tr>
    </table>
</body>
</html>
Result:

2. Examples with the th:each loop

A few other examples to help you better understand the loop in the Thymeleaf:
  • Example of using a loop with List object.
  • Example of using a loop with Mapobject.
  • Create an array directly on Thymeleaf Template and use loop for this object.
Person.java
package org.o7planning.thymeleaf.model;

public class Person {
    private Long id;
    private String fullName;
    private String email;
    public Person() {
    }
    public Person(Long id, String fullName, String email) {
        this.id = id;
        this.fullName = fullName;
        this.email = email;
    }
    public Long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFullName() {
        return fullName;
    }
    public void setFullName(String fullName) {
        this.fullName = fullName;
    }
    public String getEmail() {
        return email;
    }
    public void setEmail(String email) {
        this.email = email;
    }
}
th:each & List
Example with th:each and List:
(Java Spring)
@RequestMapping("/loop-list-example")
public String loopListExample(Model model) {
    Person tom = new Person(1L, "Tom", "tom@waltdisney.com");
    Person jerry = new Person(2L, "Jerry", "jerry@waltdisney.com");
    Person donald = new Person(3L, "Donald", "donald@waltdisney.com");
    List<Person> list = new ArrayList<Person>();
    list.add(tom);
    list.add(jerry);
    list.add(donald);
    model.addAttribute("people", list);
    return "loop-list-example";
}
loop-list-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>
      table th, table td {padding: 5px;}
      .row  {
         font-style: italic;
      }
      .even-row {
         color: black;
      }
      .odd-row {
         color: blue;
      }
    </style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>No</th>
          <th>Full Name</th>
          <th>Email</th>
        </tr>
        <tr th:each="person, state : ${people}"
               class="row" th:classappend="${state.odd} ? 'odd-row' : 'even-row'">
          <td th:utext="${state.count}">No</td>
          <td th:utext="${person.fullName}">Full Name</td>
          <td th:utext="${person.email}">Email</td>  
        </tr>
    </table>
</body>
</html>
Result:
th:each & Map
Example with th:each and Map:
(Java Spring)
@RequestMapping("/loop-map-example")
public String loopMapExample(Model model) {
    Person tom = new Person(1L, "Tom", "tom@waltdisney.com");
    Person jerry = new Person(2L, "Jerry", "jerry@waltdisney.com");
    Person donald = new Person(3L, "Donald", "donald@waltdisney.com");
    // String: Phone Number.
    Map<String, Person> contacts = new HashMap<String, Person>();
    contacts.put("110033", tom);
    contacts.put("110055", jerry);
    contacts.put("110077", donald);
    model.addAttribute("contacts", contacts);
    return "loop-map-example";
}
loop-map-example.html
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
    <meta charset="UTF-8" />
    <title>Loop</title>
    <style>
      table th, table td {padding: 5px;}
      .row  {
         font-style: italic;
      }
      .even-row {
         color: black;
      }
      .odd-row {
         color: blue;
      }
    </style>
</head>
<body>
    <h1>th:each</h1>
    <table border="1">
        <tr>
          <th>No</th>
          <th>Phone</th>
          <th>Full Name</th>
          <th>Email</th>
        </tr>
        <tr th:each="mapItem, state : ${contacts}"
               class="row" th:classappend="${state.odd} ? 'odd-row' : 'even-row'">
          <td th:utext="${state.count}">No</td>
          <td th:utext="${mapItem.key}">Phone Number</td>
          <td th:utext="${mapItem.value.fullName}">Email</td>  
          <td th:utext="${mapItem.value.email}">Email</td>
        </tr>
    </table>
</body>
</html>
Result:
Other example:
Example: Create an array directly in Thymeleaf Template and use a loop
loop-other-example.html (Template)
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8" />
<title>Loop</title>
<style>
table th, table td {
    padding: 5px;
}
</style>
</head>
<body>
    <h1>th:each</h1>
    <!-- Create an Array: -->
    <th:block th:with="flowers = ${ {'Rose', 'Lily', 'Tulip'} }">
        <table border="1">
            <tr>
                <th>No</th>
                <th>Flower</th>
            </tr>
            <tr th:each="flower, state : ${flowers}">
                <td th:utext="${state.count}">No</td>
                <td th:utext="${flower}">Flower</td>
            </tr>
        </table>
    </th:block>
</body>
</html>
Result: