0

I'm using Thymeleaf to render some objects to a fragment in my Springboot application. I'm using the table from this code snippet (Bootstrap 3 DataTables Example): Bootstrap - How to sort table columns. In the table below I included a few random rows of static data. I noticed that when I remove the objects rendered with Thymeleaf and leave only the static data the sortable table works, but when I include the rendered data from the loop the functionality from the bootstrap table stops working. What could be going wrong? My hunch is that the data from Thymeleaf is not available in the DOM when the objects are rendered. Maybe something from this tutorial could help? Still not sure how to implement. https://datatables.net/examples/plug-ins/dom_sort.html

Index:

<!-- Bootstrap CSS -->
<link href="https://maxcdn.bootstrapcdn.com/bootstrap/3.3.7/css/bootstrap.min.css" rel="stylesheet"/>
<link href="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/css/dataTables.bootstrap.min.css" rel="stylesheet"/>

Fragment HTML:

<div th:fragment="requests" xmlns:th="http://www.w3.org/1999/xhtml">

<table id="example" class="table table-striped table-bordered table-hover" style="max-width: 85% !important;">
   <thead>
      <tr>
         <th><b>Requested By</b></th>
         <th><b>Request Type</b></th>
         <th><b>Reason</b></th>
         <th><b>Requested Date</b></th>
         <th><b>Status</b></th>
      </tr>
   </thead>
   <tbody>
      <tr>
         <td>asdfa</td>
         <td>343f</td>
         <td>asdfa</td>
         <td>sdf</td>
         <td>f34</td>
      </tr>
      <tr>
         <td>123</td>
         <td>asdfa</td>
         <td>asdf</td>
         <td>cv</td>
         <td>asdfa</td>
      </tr>
      <tr th:each="request : ${requests}">
         <div th:switch="${request.get('requestStatus')}">
            <div th:case="Pending">
               <td th:text="${request.get('author').get('username')}" class="initial-name">Employee Initials</td>
               <td th:text="${request.get('requestType')}">Request Type</td>
               <td th:text="${request.get('requestText')}">Reason</td>
               <td th:text="${request.get('dateRequested')}">Requested Date</td>
               <td th:switch="${request.get('requestStatus')}">
                  <th:block th:case="Pending" th:text="${request.get('requestStatus')}"><span class="nnit-red">Pending</span></th:block>
                  <th:block th:case="Approved" th:text="${request.get('requestStatus')}"><span class="green">Approved</span></th:block>
                  <th:block th:case="Rejected" th:text="${request.get('requestStatus')}"><span class="nnit-red">Rejected</span></th:block>
               </td>
            </div>
         </div>
      </tr>
   </tbody>
</table>

    <script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.1.1/jquery.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/jquery.dataTables.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/datatables/1.10.12/js/dataTables.bootstrap.min.js"></script>

    <script type="text/javascript">
        $(document).ready(function() {
          $('#example').DataTable();
        });
    </script>

</div>
Community
  • 1
  • 1
Martin Erlic
  • 5,467
  • 22
  • 81
  • 153
  • 1
    I don't think is "allowed" to have that `DIV` between the `TR` and the `TD`. Did you try without that div? – Sigrist Apr 05 '17 at 14:29
  • Yeah, you're totally right. Now I need to figure out to get that additional data in there without breaking the table. I tried replacing the div with a but that doesn't work. But anyway yeah, that's a solution. Thanks man! – Martin Erlic Apr 05 '17 at 14:39
  • Okay I removed the two inner divs and added an if condition to the ``TR`` above: ````. This preserved the data and the table works. – Martin Erlic Apr 05 '17 at 14:44

1 Answers1

0

As indicated by Sigrist above, the two divs beneath the tbody TR were causing the problem. I removed those. In order to retain the if condition I include the Thymeleaf tag in the row itself after the each statement. This table will render all object data as well as preserve the boostrap pagination and ajax search features:

<table id="example" class="table table-striped table-bordered table-hover" style="max-width: 85% !important;">
   <thead>
      <tr>
         <th><b>Requested By</b></th>
         <th><b>Request Type</b></th>
         <th><b>Reason</b></th>
         <th><b>Requested Date</b></th>
         <th><b>Status</b></th>
      </tr>
   </thead>
   <tbody>
      <tr th:each="request : ${requests}" th:if="${request.get('requestStatus') == 'Pending'}">
         <td th:text="${request.get('author').get('username')}" class="initial-name">Employee Initials</td>
         <td th:text="${request.get('requestType')}">Request Type</td>
         <td th:text="${request.get('requestText')}">Reason</td>
         <td th:text="${request.get('dateRequested')}">Requested Date</td>
         <td th:switch="${request.get('requestStatus')}">
            <th:block th:case="Pending" th:text="${request.get('requestStatus')}"><span class="red">Pending</span></th:block>
            <th:block th:case="Approved" th:text="${request.get('requestStatus')}"><span class="green">Approved</span></th:block>
            <th:block th:case="Rejected" th:text="${request.get('requestStatus')}"><span class="red">Rejected</span></th:block>
         </td>
      </tr>
   </tbody>
</table>
Martin Erlic
  • 5,467
  • 22
  • 81
  • 153