Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

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.

like image 980
Mark Underwood Avatar asked Jan 05 '23 14:01

Mark Underwood


1 Answers

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.

like image 132
pDer666 Avatar answered Jan 08 '23 04:01

pDer666