4

I'm making a simple intranet web view for a ordering system to show all orders that are currently processed. However I'm stuck with the thymeleaf markup:

public class Order {
  private Factory factory;

  private String orderNumber;

  private Date orderDate;

  ....

  private List<Article> articles;
}

public class Article {

  private String number;

  private String name;
}

What i want to accomplish is the following (with 1 order + 3 articles in that order):

<table class="table table-striped table-hover table-middle table-condensed table-bordered">
  <thead>
    <tr>
      <th>OrderNr</th>
      <th>Date</th>
      <th>Article Number</th>
      <th>ArticleName</th>
    </tr>
  </thead>
  <tbody>
    <tr>
      <td rowspan="3">Order 32</td>
      <td rowspan="3">27.03.2020</td>
      <td>17442</td>
      <td>Screws</td>
    </tr>
    <tr>
      <td>023423</td>
      <td>Potatoe</td>
    </tr>
    <tr>
      <td>32342</td>
      <td>YetAnotherItem</td>
    </tr>
  </tbody>
</table>

all the common stuff should be row-spanned over all articles and the articles should be viewed one each line. However i have no idea on how to accomplish that with two th:each (one for the order, one for the articles of the order). I could "flatten" out my view (each line represented by one Line-Object) with a ton of ifs in the markup but that is a very dirty hack-around in my opinion...

Can anyone help me out with a better solution?

Thanks a lot!

semteX
  • 43
  • 1
  • 5

1 Answers1

9
 <table>
     <thead>
         <tr>
             <th>OrderNr</th>
             <th>Date</th>
             <th>Article Number</th>
             <th>ArticleName</th>
         </tr>
     </thead>
     <tbody>
        <div th:remove="tag" th:each="order:${orderList}" 
             th:with="articleCount=${order.articleList.size()}">
            <tr>
                <td th:text="${order.orderNumber}" th:rowspan="${order.articleList.size()}"></td>
                <td th:text="${order.orderDate}" th:rowspan="${order.articleList.size()}"></td>
                <td th:text="${articleCount>0}?${order.articles[0].number}:''"></td>
                <td th:text="${articleCount>0}?${order.articles[0].name}:''"></td>
            </tr>
            <tr th:each="article,stats:${order.articles}" th:if="${!stats.first}">
                <td th:text="${article.number}"></td>
                <td th:text="${article.name}"></td>
            </tr>
        </div>
     </tbody>
</table>

th:remove="tag" for remove div after table generated.

Changed to avoid rendering problems. Thanks to comment of @Martin C.

Community
  • 1
  • 1
Ken Bekov
  • 13,696
  • 3
  • 36
  • 44
  • This will produce empty columns in the first row, which may lead to undesired visual effects (which may be styled away). Also the question is, how this works with accessibility. But good idea, anyhow :) – Martin C. Mar 15 '16 at 11:23
  • @MartinC. intrigued by your comment, tested this snippet and ... there is no empty columns. Rowspan merged all cells as expected. Of course I didn't test it for work with accessibility. There is just general idea. – Ken Bekov Mar 15 '16 at 11:53
  • Test it out with ``, you will see a slight rendering difference if you have the the first article in a new ``. It's very subtle and I don't think it's a problem, just wanted to point it out. (Disclaimer: I tested that directly on the HTML provided in the question, not on the Thymeleaf template) Just to make it clear: I like your solution, it was not meant as criticism.
    – Martin C. Mar 15 '16 at 11:56
  • @MartinC. you was right. In detailed comparison really seen differences in rendering – Ken Bekov Mar 15 '16 at 12:07
  • 1
    @MartinC. I changed template code. Thanks a lot for comment. – Ken Bekov Mar 15 '16 at 12:54
  • 1
    Thanks! i did not fully understand the usefulness of th:remove! Your solution is perfect now. The upvote will show as soon as i reach 15 rep! – semteX Mar 15 '16 at 12:57
  • In thymeleaf 3 there seems to be a th:block which can also solve this. Eg: https://www.thymeleaf.org/doc/tutorials/3.0/usingthymeleaf.html#synthetic-thblock-tag – Kishan B Oct 17 '21 at 18:31