Search code examples
thymeleaf

Thymeleaf nested list/ArrayList - get total size of all elements


List has 2 elements [0], [1].

Element in list - [0] has five elements in nested ArrayList [0] [1], [2], [3], [4], [5]

[1] has 4 elements [0], [1], [2], [3] , [4]

How can I get the total length/size in Thymeleaf, i.e 9? I need to use it outside of any loops if possible to hold a temporary value.

Which brings me to the next question, how can I hold local custom variables in Thymeleaf using just the .size and not iterating through the data structure? I am ready to write a loop to get this .size if needed but I want to store it in a local variable that I can possibly reuse later in another loop!

Example:

<div th:each="test : ${testList}">
    <div th:each="testItem : ${test.subArrayList}">
        <div th:each="testItemSub : ${testItem}">
            <span> Get total size of "${testItemSub.name}" and store in a variable</span>
        </div>
    </div>
</div>

Solution

  • You can set up a local variable via the th:with attribute per http://www.thymeleaf.org/doc/usingthymeleaf.html#local-variables . However, I've found no way to update that local variable within the element once it's set. In other words, unlike JSP, variables cannot be created and manipulated within the view/template.

    The easiest way to solve your particular use case would be:

    1. Set an model object containing a method that will take in the ArrayList as its parameter and return the count. Obviously, you can implement any logic you need in Java code.
      • Similarly, a Spring bean instead of a model object can be used. Used by the syntax: ${@myBean.doSomething()}
    2. Use the #ids expression utility object that comes with Thymeleaf. It can be used as a counter within the template if you use an id of ''. However, this will only work if there is only one such counter within the entire template. Ref: http://www.thymeleaf.org/doc/usingthymeleaf.html#ids

    Example usage of #ids based on the original question:

    <div th:each="test : ${testList}">
        <div th:each="testItem : ${test.subArrayList}">                                 
                <div th:each="testItemSub : ${testItem}">
                        <span> Get total size of "${testItemSub.name}" and store in a variable</span>
                        <!--/*/ <th:block th:text="${#ids.seq('')}"></th:block> /*/-->
                </div>
        </div>
    </div>
    <p>There are a total of <span th:text="${#ids.prev('')}">123</span> elements.</p>