Search code examples
javahtmlspringthymeleaf

Thymeleaf: Comma separated values of a list?


I am beginner in Thymeleaf, I have a list and want to list elements in a line by separating comma e.g. London, Paris, Berlin, HonKong (there will be no comma after the the last element). However, the following code generate new row. So, how can I make it work as explained above?

<td th:each="city : ${country.cityList}">
    <td th:text="${city.name}? ${city.name} + ',' : ${city.name}"></td>
</td>

I know it also add an extra comma at the end of the last element and I need to use index e.g. for detecting the last index. How can I do this?


Solution

  • You can use a sequence of <span> tags to hold your text.

    You can use Thymeleaf's iteration status tracking values to know when you are handling the last item in the list.

    Combining these:

    <td>
        <span th:each="city,iterStat : ${country.cityList}"
              th:text="${city.name} + ${!iterStat.last ? ', ' : ''}"></span>
    </td>
    

    The iterStat.last value is a boolean which tells us when we are processing the final value - and the ! (not) operator is used to suppress the final comma + space.


    Update

    Based on the comment:

    how make href links for city.name but span only for comma ?

    For something like this, you can move the th:each expression into a parent tag - and this is where <th:block> may be useful, because it does not itself generate any HTML:

    <th:block th:each="city,iterStat : ${country.cityList}">
        <a th:text="${city}" th:href="${city}"></a><span th:text="${!iterStat.last ? ', ' : ''}"></span>
    </th:block>
    

    Inside the <th:block>...</th:block> you can use multiple child tags to build whatever you need.

    Using the above Thymeleaf, the end result could be the following HTML:

    <a href="São Paulo">São Paulo</a><span>, </span>
    <a href="Rio de Janeiro">Rio de Janeiro</a><span>, </span>
    <a href="Brasilia">Brasilia</a><span></span>
    

    This generates an empty <span></span> at the end.

    If you don't want that empty span, you can enhance the logic by using an explicit th:if expression:

    <th:block th:each="city,iterStat : ${country.cityList}">
        <a th:text="${city}" th:href="${city}"></a><span th:if="${!iterStat.last}">, </span>
    </th:block>
    

    Now, you will get something like this:

    <a href="São Paulo">São Paulo</a><span>, </span>
    <a href="Rio de Janeiro">Rio de Janeiro</a><span>, </span>
    <a href="Brasilia">Brasilia</a>
    

    Now, there is no empty span at the end.