Search code examples
javahtmlthymeleaf

Thymeleaf about th:block statement


I'm trying to use th:block to make table more specific to analyze my data..

i was trying

<table>
   <thead>
      <tr>
       <th>something</tr>
       <th>something2</tr>
       <th>something3</tr>
      </tr>
   </thead>
   <tbody>
    <tr>
        <th:block th:if="${not #maps.isEmpty(result)}" th:each="firstEntry : ${result}">
           <th:block th:if="${firstEntryStat.count == 0}">
              <tr>
           </th:block>

           <td th:text="${firstEntry.value}"></td>

           <th:block th:if="${firstEntryStat.count == 0}">
              </tr>
           </th:block>
           
        </th:block>
   </tbody>
</table>

i attempted to make this kind of table (at the end of the post)

but it ends with the error which is

The element type "th:block" must be terminated by the matching end-tag "</th:block>"

so i tried another way,

 <table>
       <thead>
          <tr>
           <th>something</tr>
           <th>something2</tr>
           <th>something3</tr>
          </tr>
       </thead>
       <tbody>
        <tr>
            <th:block th:if="${not #maps.isEmpty(result)}" th:each="firstEntry : ${result}">
             <tr th:if="${firstEntryStat.count == 0}">

               <td th:text="${firstEntry.value}"></td>

             </tr th:if="${firstEntryStat.count == 0}">
               
            </th:block>
       </tbody>
    </table>

However, it produced the error like

The end-tag for element type "tr" must end with a '>' delimiter.

is there any way to make datatable like the picture above?

My map data has structure like

Maps< String , Maps< String, Maps< String, Long>>> result = new HashMap<>();
result = {
  "First": {
    "time": {
      "now": "",
      "past": "",
      "future": ""
    },
    "sleifj": {
      "now": "",
      "past": "",
      "future": ""
    }
  },
  "Second": {
    "time": {
      "now": "",
      "past": "",
      "future": ""
    },
    "sleifj": {
      "now": "",
      "past": "",
      "future": ""
    }
  }
}

=================================================================== Additional Data Info My map data looks like

First
  - time
        - now : slejflesf
        - past : lsijefleisf
        - future : lsajiefeasf
  - sleifj 
        - now : slejflesf
        - past : lsijefleisf
        - future : lsajiefeasf
Second
  - time
        - now : slejflesf
        - past : lsijefleisf
        - future : lsajiefeasf
  - sleifj 
        - now : slejflesf
        - past : lsijefleisf
        - future : lsajiefeasf




------------------------------------------------------
  Map Name  |  Sub Name  |  Now  |  Past  |  Future  |
------------------------------------------------------
  First     |    time    | asfas | lsefa  | saeflkjle|
            ------------------------------------------
            |    sleifj  | dsff  | sfesf  | sefasefa |
------------------------------------------------------
  Second    |    time    | asfas | lsefa  | saeflkjle|
            ------------------------------------------
            |    sleifj  | dsff  | sfesf  | sefasefa |
------------------------------------------------------

Solution

  • In your first example you'r missing a </tr> between the 2 </th:block> tags aswel as you'r trying to nest 2 table rows which is not advisable.

    The second example stil has the same problems but for this I don't think you can use th:if on a closing tag.

    Looking at the ASCII mockup you've written what you'd probably want to do is just leave the first <td> element empty on any item in the submap that is not the first. (see mock code below)

    <table>
        <thead>
            <tr>
                <th>Map Name</th>
                <th>Sub Name</th>
                <th>Now</th>
                <th>Past</th>
                <th>Future</th>
            </tr>
        </thead>
        <tbody>
            <th:block th:each="mapNameItem : ${result}">
                <tr th:each="subMapItem : ${mapNameItem}">
                    <td th:if="subMapItemStat.count == 0" th:text="mapNameItem.key" />
                    <td th:if="subMapItemStat.count != 0" />
                    
                    <td th:text="subMapItem.key" />
                    <td th:text="subMapItem.get('now')" />
                    <td th:text="subMapItem.get('past')" />
                    <td th:text="subMapItem.get('feature')" />
                </tr>
            </th:block>
        </tbody>
    </table>
    

    Potentially you'd want to move the outermost th:each on the th:block to the tbody instead depending on your formatting needs.