QYC
QYC

Reputation: 55

Thymeleaf th:field doesn't bind the value for input text

I want to send an object to the view for presentation and send it back to controller using springboot and Thymeleaf, however, I encounter a weird problem with Thymeleaf's th:value.

This is my controller:

@GetMapping("/food/buy/{fid}")
public String buyFood(HttpServletRequest request, @PathVariable("fid") Long fid, Model model) {
    Food food = consumerService.getFood(fid);
    System.out.println("foodid = " + food.getId());
    model.addAttribute("food", food);
    model.addAttribute("order", new OrderVO());
    return "user/direct/f_order";
}

and my view:

<form th:action="@{/user/buy/direct/food}" method="post" th:object="${order}">
    <table border="1px">
        <tr th:hidden="true">
            <td><input type="text" th:value="${food.id}" th:field="*{fid}" th:readonly="true"></td>
        </tr>
    </table>
</form>

and the VO class:

public class OrderVO {
    private Long fid, address;

    private Integer amount;

    @DateTimeFormat(pattern = "HH:mm")
    private Date deliverTime;
}

the problem is, the input field's value is null, but I'm sure that the food's id is not null (I print it in the controller)

I remove the th:field block, and the food.id can be properly presented. If I add the th:field block back, the problem reoccur.

So there may be something wrong with th:field, but I can't figure out. Can somebody point out my mistake?

===========================UPDATE============================

Some friends kindly points out that th:field may overwrite th:value, but I also use them in other views and it works fine:

<tr>
    <td>UserName</td>
    <td><input type="text" th:value="*{userName}" th:field="*{userName}"></td>
</tr>

The problem is getting incresing weird I think :(

Upvotes: 0

Views: 7091

Answers (3)

Florin Giurcă
Florin Giurcă

Reputation: 1

Supposing you have to collect a comment to a page. You must transmit to the controller, besides the comment, the name of the page. Ofcourse, the user don't have to re-enter the name of this page. This information must be passed to controller, but th:field only map the values entered by the user, not the values generated by default.
But you can transmit the name of this page to controller as parameter in URL. In html, you have something like that:

    <form  th:action="@{/saveComment(lastPage=${lastPage})}" th:object="${comments}" method="post" enctype="multipart/form-data">
        <div class="row">
 .................................................................................
            <h2>Enter your comment</h2>
            <textarea  th:field="${comments.comment}" rows="10" cols="100" name="comment" id="comment"></textarea>
            <label for="comment">Your comment here</label><br />
            <input type="submit" name ="submit" value="Submit" />
        </div>
    </form> 

In controller, you put stuff like this:

   @PostMapping("/saveComment")
    public String saveComment(Comments comments, String lastPage) {
        comments.setPage_commented(lastPage);
        commentsRepository.save(comments);
        return "redirect:/";
    }

It works fine to me.

Upvotes: 0

Aritra Paul
Aritra Paul

Reputation: 874

In tabualr form try using th:name instead of th:field to overcome th binding issue

th:name="|order.fid|"

and stick to java naming convention.

Upvotes: 0

Replace *{fid} with fid My team had this same issue and it worked

Upvotes: 0

Related Questions