Implement a button in a table that returns data from the table using Thymeleaf and Spring Boot

13,747

Solution 1

I will show you how we solved that in our application. we generate a form for every action in a table row like this:

<table>
<thead>
    ...
</thead>
<tbody>
    <tr th:each="entry : ${allEntries}">
        ...

        <td>
            <form action="#" th:action="@{/dashboard/myEntries/} + ${{entry.id}}" method="get">
                <button th:id="'table_entry_childs_button_' + ${entry.id}" type="submit">
                    <i>details</i>
                </button>
            </form>
        </td>
        ...
</tbody>

That solution works fine for us. I'm encouraged that I was able to help you.

Solution 2

Thanks to the comment from pDer666 I have a solution!!

Changed the HTML to:

    <table>
    <tr><th>Device IP</th>
        <th>Status</th>
        <th>Model Name</th>
        <th>Serial No.</th>
        <th>Remove?</th>
    </tr>
    <tr th:each="d : ${devices}">
        <form action="#" th:action="@{/webservice/adddevice}" th:object="${addForm}" method="post">
        <td th:text="${d.address}">N/A</td>
        <td th:text="${d.status}">N/A</td>
        <td th:text="${d.modelName}">N/A</td>
        <td th:text="${d.serialno}">N/A</td>
        <td><input type="hidden" th:value="${d.address}" name="deviceIP"/><button type="submit" class="removebutton" name="action" value="remove">Remove</button></td>
        <td th:if="${#fields.hasErrors('deviceIP')}" th:errors="*{deviceIP}">IP Error</td>
        </form>
    </tr> 
</table>

Putting the form inside the table row loop structure creates a separate form for each row, and now when the button is clicked, my POST method receives only the IP address for the corresponding row.

THANK YOU pDer666!

Share:
13,747
Mark Underwood
Author by

Mark Underwood

Updated on July 13, 2022

Comments

  • Mark Underwood
    Mark Underwood almost 2 years

    tl;dr with Spring Boot and Thymeleaf, how do I return the column 1 value of the table in a form when the user clicks the button in column 5 of a particular row?

    Hi there! Long time listener, first time caller. I'd be much obliged for your help with this issue.

    I'm writing a server app using Spring Boot and Thymeleaf. The server interacts with a number of devices. I'm creating a web page that will show the list of devices and their IP addresses in a table (in a form). Each row of the table has info about the device and a "Remove" button to remove the device from the list. When the button is clicked, the form should return the IP address of the device to the underlying Controller so the Controller can remove the device from the (internal) list of devices.

    I can get it to either return nothing at all, or ALL of the IP addresses (as a string with commas separating the values), but I can't get it to return ONLY the address on the row of the clicked button.

    The searches I've done have turned up ways to do it for static tables, but not dynamically generated ones, or for regular "input" type inputs, not buttons. Nothing specific to click this button, return this value from the other column of the same row.

    I'm trying to do this in relatively pure Java and HTML, but I'm not opposed to some snippets of JavaScript if it solves the problem. I don't really know anything about JQuery... and JSP pages are also not an option for other project reasons.

    HTML:

      <form action="#" th:action="@{/webservice/adddevice}" th:object="${addForm}" method="post">
    <table>
        <tr><th>Device IP</th>
            <th>Status</th>
            <th>Model Name</th>
            <th>Serial No.</th>
            <th>Remove?</th>
        </tr>
        <tr th:each="d : ${devices}">
            <td th:text="${d.address}">N/A</td>
            <td th:text="${d.status}">N/A</td>
            <td th:text="${d.modelName}">N/A</td>
            <td th:text="${d.serialno}">N/A</td>
            <td><input type="hidden" th:value="${d.address}" name="deviceIP"/><button type="submit" class="removebutton" name="action" value="remove">Remove</button></td>
            <td th:if="${#fields.hasErrors('deviceIP')}" th:errors="*{deviceIP}">IP Error</td>
        </tr> 
    </table>
    

    My latest (and closest-to-the-mark) attempt uses the hidden input on each row to return the value... but it returns the value for ALL of the rows.

    The "devices" (class DeviceStatus) object is a List of your standard data object with a bunch of string members and get/set methods. It holds the info for the attached devices.

    The "addForm" (class AddForm) object is a single object with a string ("deviceIP") and get/set methods for that string.

    The controller GET method:

        @RequestMapping(value="/webservice/adddevice", method=RequestMethod.GET)
    public String showForm(Model model, AddForm addForm) {
        model.addAttribute("devices", getDevicesStatus());
        addForm.loadPrefs(deviceController);
    return "adddevice"; // the webpage is adddevice.html
    }
    

    and the controller POST method:

        @RequestMapping(value="/webservice/adddevice", method=RequestMethod.POST, params="action=remove")
    public String removeDevice(@Valid AddForm addForm, BindingResult bindingResult) {
    //addForm.removeDevice(deviceController);
    return "redirect:/webservice/results";
    }
    

    For now the POST method doesn't do anything... until I get the HTML Form working, there's not much point.

  • Mark Underwood
    Mark Underwood almost 8 years
    (Sorry if it's not kosher to answer your own question with someone else's solution. pDer666 really should get the credit for this!)