En este post te mostraré a usar th:each en Thymeleaf para iterar o recorrer colecciones, algo así como dibujar una lista o repetir un elemento HTML.
Además de repetir una lista te enseñaré la sintaxis básica de th:each.
Finalmente veremos un ejemplo con Spring Boot para renderizar una lista de productos traída desde un repositorio que a su vez se conecta con MySQL.
Usar th:each en Thymeleaf
Para recorrer una lista, arreglo o ArrayList en Thymeleaf hay que especificar el atributo th:each
al elemento que se va a repetir. Por ejemplo:
<ul>
<li th:each="variable : ${lista}" th:text="${variable}"></li>
</ul>
En el ejemplo de arriba se va a repetir el elemento <li>
por cada elemento que haya en lista
.
Dibujar tabla usando th:each
También se puede dibujar una tabla con Thymeleaf y th:each
como se ve en el siguiente ejemplo:
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Precio</th>
</tr>
</thead>
<tbody>
<tr th:each="producto : ${productos}">
<td th:text="${producto.nombre}"></td>
<td th:text="${producto.precio}"></td>
</tr>
</tbody>
</table>
En este caso hay que repetir el elemento <tr>
de la tabla HTML. Dentro de ese elemento tenemos acceso a la variable.
Acceder al índice y tamaño de la lista
Si quieres saber en cuál índice estás o deseas saber el tamaño de la lista, declara una segunda variable que será el iterador de la lista. Así:
<table>
<thead>
<tr>
<th>Nombre</th>
<th>Precio</th>
<th>Índice</th>
</tr>
</thead>
<tbody>
<tr th:each="producto,iterador : ${productos}">
<td th:text="${producto.nombre}"></td>
<td th:text="${producto.precio}"></td>
<td th:text="${iterador.index}"></td>
</tr>
</tbody>
</table>
Fíjate en la línea 10, en la misma se está declarando una variable que servirá para iterar la lista de productos.
En este caso además de la variable que será cada elemento de la lista tenemos al iterador. El iterador tiene la propiedad index
y size
.
Ejemplo de th:each con Spring Boot
Ahora que hemos explicado lo más básico sobre th:each en Thymeleaf veremos cómo combinarlo con Spring Boot. En mi caso debo renderizar una lista de productos.
Tengo mi repositorio de productos:
package hello;
import org.springframework.data.repository.CrudRepository;
public interface ProductosRepository extends CrudRepository<Producto, Integer> {
Producto findFirstByCodigo(String codigo);
}
En mi controlador tengo un método que muestra la vista de productos:
@GetMapping(value = "/mostrar")
public String mostrarProductos(Model model) {
model.addAttribute("productos", productosRepository.findAll());
return "productos/ver_productos";
}
Finalmente la vista es la siguiente:
<!DOCTYPE html>
<html lang="es" xmlns:th="http://www.thymeleaf.org"
xmlns:layout="http://www.ultraq.net.nz/thymeleaf/layout"
layout:decorate="master">
<body>
<main layout:fragment="contenido">
<div class="col-12">
<h2>Productos</h2>
<div th:classappend="'alert-' + (${clase != null} ? ${clase} : info)" th:if="${mensaje != null}"
th:text="${mensaje}"
class="alert">
</div>
<a class="btn btn-success mb-2" th:href="@{/productos/agregar}">Agregar</a>
<table class="table table-bordered">
<thead>
<tr>
<th>Nombre</th>
<th>Código</th>
<th>Precio</th>
<th>Existencia</th>
<th>Editar</th>
<th>Eliminar</th>
</tr>
</thead>
<tbody>
<tr th:each="producto : ${productos}">
<td th:text="${producto.nombre}"></td>
<td th:text="${producto.codigo}"></td>
<td th:text="${producto.precio}"></td>
<td th:text="${producto.existencia}"></td>
<td>
<a class="btn btn-warning" th:href="@{/productos/editar/} + ${producto.id}">Editar <i
class="fa fa-edit"></i></a>
</td>
<td>
<form th:action="@{/productos/eliminar}" method="post">
<input type="hidden" name="id" th:value="${producto.id}"/>
<button type="submit" class="btn btn-danger">Eliminar <i class="fa fa-trash"></i>
</button>
</form>
</td>
</tr>
</tbody>
</table>
</div>
</main>
</body>
</html>
Con el siguiente resultado:
Conclusión
En conclusión utiliza th:each
para repetir elementos o iterar listas, arreglos, ArrayLists, etcétera.
Recuerda que puedes declarar una segunda variable para acceder al iterador y a su vez al índice o al tamaño de la lista.
Aprende más sobre Thymeleaf o Spring Boot en mi página.