Sujay DSa
Sujay DSa

Reputation: 1192

Thymeleaf: Form submit on click of table row

I have a table with orders and order ids. I would like to click on a row to view the order details in another page. My code:

        <form id="orderDetalsForm" th:action="@{/restaurant/orderdetails}"
            method="POST" th:object="${order}">
            <table class="table table-bordered table-hover">
                <thead>
                    <tr>
                        <th scope="col">Order Id</th>
                        <th scope="col">Order Details</th>
                        <th scope="col">Date</th>
                        <th scope="col">Amount</th>
                    </tr>
                </thead>
                <tbody>


                    <tr id="orderRow" th:each="order : ${orders}"
                        style="cursor: pointer" 
                        th:onclick="'getOrderItems(\''+${order.orderId}+ '\');'">
                        <td scope="row" th:text="${order.orderId}"></td>
                        <td th:text="${order.orderDetais}"></td>
                        <td th:text="${order.orderDate}"></td>
                        <td th:text="${order.amount}"></td>
                    </tr>

                    <tr>
                        <td colspan="3">Total</td>
                        <td th:text="${grandTotal}"></td>
                    </tr>
                </tbody>
            </table>
        </form>

I tried an ajax form submit:

    <script>
        function getOrderItems(orderId) {
            var url = "/restaurant/orderdetails";
            $.ajax({
                url : url,
                type : "post",
                data : {
                    "orderId" : orderId
                },
                success : function(data) {
                    console.log(data);
                },
                error : function() {
                    console.log("There was an error");
                }
            });
            
        }
    </script>

In my controller I have this:

@PostMapping(value="/restaurant/orderdetails")
public ModelAndView orderDetails(@RequestParam String orderId){
    List<Product> orderDetails = userService.getOrderDetails(orderId);
    ModelAndView modelAndView = new ModelAndView();
    modelAndView.addObject("orderDetails", orderDetails);
   
    modelAndView.setViewName("restaurant/orderdetails");
    return modelAndView;
}

While the ajax works, the page is not getting redirected to my orderdetails page.

Upvotes: 2

Views: 2470

Answers (2)

RoToRa
RoToRa

Reputation: 38390

You can't use AJAX to redirect to a page. AJAX is for getting data from the server that is then processed/displayed using JavaScript. You however basically want clicking on the row to behave like clicking a link or (since you are using a POST mapping) submitting a form.

First off, using POST makes this a bit more complicated. You should consider using a GET mapping, not only because it makes this problem easier, but also because a POST mapping isn't really appropriate here. POST is used to send data to the server, which you are not doing.

Another thing you should consider it that using a (pure) JavaScript solution to link the table row hinders accessibility. For example, users that can't/don't use a mouse (such as disabled people or search engines) won't be able to see or even use such a link. To solve this it is a good idea to add a proper link to the row. Then that link can used by "clicking" on it with the JavaScript of the click handler.

<tr th:each="order : ${orders}" onclick="orderRowClick(this)">
   <td scope="row"><a th:href="@{/restaurant/orderdetails(orderId=${order.orderId})}" th:text="${order.orderId}"></a></td>
   <td th:text="${order.orderDetais}"></td>
   <td th:text="${order.orderDate}"></td>
   <td th:text="${order.amount}"></td>
</tr>
<script>
  // Look for a link in the row and click on it
  function orderRowClick(row) {
     row.querySelector("a").click();
  }
</script>

Several more points:

  • IDs must be unique in HTML. By putting id="orderRow" on such a repeated row will result in invalid HTML.

  • You shouldn't be using on... attributes to assign event handlers. I'm just using it here or otherwise this answer will go too far.

  • Remove the <form> from around the table. It doesn't do anything.

If you do want to/have to use a POST mapping, then replace the link in the table row with a form with a hidden field containing the order ID and a submit button and in the JavaScript look for the form instead of the link and submit it: row.querySelector("form").submit();.

BTW there are several (possibly better) ways to do what you are trying. For example:

  • Forget the JavaScript and just put a link into every cell. With the right CSS the row/cells can be changed so that it looks like you are clicking on the row.

  • It seems like you are using Bootstrap, which has the "stretched link" feature. Unfortunately it's a bit tricky to get to work with table rows, but it's worth looking at.

Upvotes: 1

Sumit
Sumit

Reputation: 957

What I've understand so far is that you want to redirect user to a new page when the user clicks on the button on the table, for that there're different approaches -

  1. Issue with your approach -
    Since you're using ajax it wont be redirecting user to a new page ( because thats exactly how a AJAX works, for more info on AJAX us this link - https://developer.mozilla.org/en-US/docs/Web/Guide/AJAX ), unless you explicitly tells your ajax-code to redirect the user on a new page.
    For that you can simply put your page redirection code to a on your ajax success, something like this -
<script>
    //your code
        $.ajax({
              // your code
            success : function(data) {
                //page redirection code here
                window.location.href = "your-base-URL/restaurant/orderdetails/orderId="+orderId;

            },
            error : function() {
                console.log("There was an error");
            }
        });
     }
</script>

PS - This is not efficient programming practice since you're technically making an extra call to your server un-necessarily.

  1. Approach 2nd
    Simply make your html table buttin a-href link , like this -
<html>
  // your code
<a th:href="@{'/restaurant/orderdetails/orderId=' + ${order.orderId}}">Order details button </a>

//your rest of the code
</html>
  1. Approach-3rd , You can alternatively use java-script function for page redirection as well, simply modify you ajax function , something like this -

function getOrderItems(orderId) {

    //page redirection code here
  window.location.href = "your-base-URL/restaurant/orderdetails/orderId="+orderId;

}

Upvotes: 1

Related Questions