I have an endpoint:
@GetMapping("book/param")
public String bookByParam(
@RequestParam(required = false,name = "name") String name,
@RequestParam(required = false,name = "author") String author,
@RequestParam(required = false,name = "genre") String genre,
@RequestParam(required = false,name = "genre") int price, Model m
){
List<Books> books = bookService.showSpecificBooks(name, author, genre,price);
m.addAttribute("books", books);
return "book";
}
For the params I wrote querys so they can be null that means if i dont input anything I will get all books.
Now I have my books.html template with following implemenation:
<form th:action="@{book/param}" th:object="${books}" method="get">
<label for="name">name:</label><br>
<input type="text" id=name th:field="name" placeholder="name">
<label for="author">author:</label><br>
<input type="text" id=author th:name="author" placeholder="author">
<label for="genre">genre:</label><br>
<input type="text" id=genre th:name="genre" placeholder="genre">
<label for="price">price:</label><br>
<input type="number" id=price th:name="price" placeholder="price">
</form>
I would expect that I would get a List of books within the range of the submitted values and when I have no input I would get (because of my Query) all books but all I get is a TemplateInputException: An error happened during template parsing. I also tried to wrap the object names like this:
<input type="text" id=name th:field="*{name}" placeholder="name">
or like this :
<input type="text" id=name th:field="${name}" placeholder="name">
but unfortunately it did not work. Can anyone see what I am doing from. Thanks in advance
CodePudding user response:
Use a model object and bind that to the form instead of separate query parameters. \
public class SearchParameters {
private String name, genre, author;
private int price;
// getters / setters
}
@ModelAttribute("params")
public SearchParams params() {
return new SearchParamters ();
}
@GetMapping("book/param")
public String bookByParam(@ModelAttribute("params") SearchParamters params, Model m
){
List<Books> books = bookService.showSpecificBooks(params.getName(), params().getAuthor(), params.getGenre(), params.getPrice());
m.addAttribute("books", books);
return "book";
}
TIP: You could also pass the SearchParameters
to your BookService
and just get the things in there. Saves you from modifying the method when you add an additional parameter, you just need to change the SearchParameters
and the BookService
implementation.
Now let your form use params
as a object and refer to the fields.
<form th:action="@{book/param}" th:object="${params}" method="get">
<label for="name">name:</label><br>
<input type="text" id=name th:field="name" placeholder="name">
<label for="author">author:</label><br>
<input type="text" id=author th:field="author" placeholder="author">
<label for="genre">genre:</label><br>
<input type="text" id=genre th:field="genre" placeholder="genre">
<label for="price">price:</label><br>
<input type="number" id=price th:field="price" placeholder="price">
</form>
This should bind your form object to the thymeleaf form and you will see earlier entered data.
To show your results you need to iterate over the books
list and show them in a table (or something else).
<table>
<tr><th>Name</th><th>author</th><th>Genre</th><th>Price</th></tr>
<tr th:each="book : ${books}">
<td th:text="${book.name}">Name</td>
<td th:text="${book.author}">Author</td>
<td th:text="${book.genre}">Genre</td>
<td th:text="${book.price}">Price</td>
<tr>
</table>
Something like the above should do.
CodePudding user response:
th:field works for entities. From what I see name is a request parameter. Try using th:name, as you do for author, genre, price.
<input type="text" id=name th:name="name" placeholder="name">
In order to iterate through the list of books you can try doing this:
<tr th:each="book : ${books}">
<td><span th:text="${book.name}"> Title </span></td>
<td><span th:text="${book.author}"> Author </span></td>
<td><span th:text="${book.genre}"> Genre</span></td>
<td><span th:text="${book.price}"> Price</span></td>
</tr>
In this case, there's no need for @RequestParam since the fields can be found inside Book entity.