Search code examples
javathymeleaf

How to pass object to modal dialog in Thymeleaf?


I have a thymeleaf page that shows database content (persons) in a table.

<tr id="tableBody">
    <td th:text="${row.id}"/>
    <td th:text="${row.firstname}"/>
    <td th:text="${row.lastname}"/>
    <td>
        <button data-toggle="modal" data-target="#editModal" th:data-row="${row}">DEL</button>
    </td>
</tr>

The last column should be a button that deletes the row. But prior, show a modal dialog with the data being deleted.

Question: how can I pass the the full row person object to a modal dialog?

I started as follows, but I'm missing how I could actually pass the person object from the clicked row into the modal dialog as an object (so that I can show the person fields in the modal dialog again).

The following is kind of pseudo code:

<div class id="editModal" ...>
  <div class="modal-body">
    <div class="modal-body">
       You are about to delete: <div th:text="${row.firstname}"/> <div th:text="${row.lastname}"/>

       <form action="#" th:action="@{/delete/{id}" th:object="${row}" method="delete">
          <input type="text" hidden="true" th:field="${row.id}">
       </form>
    </div>

    <div class="modal-footer">
        <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
        <button type="submit" class="btn btn-primary" th:href="@{/delete/{id}(id=${row.id})}" th:method="delete">Remove</button>
    </div>
  </div>
</div>

Solution

  • Pure thymeleaf

    To do it in pure thymeleaf, you would need to create a dialog for every row in the table with a unique id, and open the dialog associated to the row being deleted.

    Example modals:

    <div th:each="row : ${rows}" th:attr="id=${'editModal' + row.id}">
      <div class="modal-body">
        <div class="modal-body">
           You are about to delete: <div th:text="${row.firstname}"/> <div th:text="${row.lastname}"/>
    
           <form action="#" th:action="@{/delete/{id}" th:object="${row}" method="delete">
              <input type="text" hidden="true" th:field="${row.id}">
           </form>
        </div>
    
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
            <button type="submit" class="btn btn-primary" th:href="@{/delete/{id}(id=${row.id})}" th:method="delete">Remove</button>
        </div>
      </div>
    </div>
    

    And the button which opens the dialog becomes:

    <button data-toggle="modal" th:attr="data-target=${'#editModal'+row.id}" data-row="${row}">DEL</button>
    

    With javascript

    If you can use javascript, I would recommend creating only a template of the modal dialog using thymeleaf, then clone it and and populate it dynamically.

    Example modal:

    <div class id="editModalTemplate">
      <div class="modal-body">
        <div class="modal-body">
           You are about to delete: <div data-value="firstname"/> <div data-value="lastname"/>
    
           <form action="#" th:action="@{/delete/_id_}" method="delete">
              <input type="text" hidden="true" name="id">
           </form>
        </div>
    
        <div class="modal-footer">
            <button type="button" class="btn btn-secondary" data-dismiss="modal">Cancel</button>
            <button type="submit" class="btn btn-primary" th:href="@{/delete/{id}(id='_id_')}" th:method="delete">Remove</button>
        </div>
      </div>
    </div>
    

    The delete button:

    <button class="btn-delete" data-id=${row.id} data-firstname="${row.firstname}" data-lastname="${row.lastname}">DEL</button>
    

    Javascript (using jQuery implementation as example):

    $('.btn-delete').click(function(){
        //clone dialog and remove ids to ensure uniqueness
        var $modal = $('#editModalTemplate').clone().removeAttr('id');
    
        //apply custom values where needed
        var $btn = $(this);
        var rowId = $btn.attr('data-id');
        var firstname = $btn.attr('data-firstname');
        var lastname = $btn.attr('data-lastname');
    
        $modal.find('[data-value="firstname"]').text(firstname );
        $modal.find('[data-value="lastname"]').text(lastname );
        $modal.find('[name="id"]').val($btn.attr('data-id'));
        $modal.find('form').attr('action').replace('_id_', rowId);     
        $modal.find('button[type="submit"]').attr('href', $modal.find('button[type="submit"]').attr('href').replace('_id_', rowId);
    
        //show dialog
        $modal.modal();
    });