How to transfer parameters in th:href in spring boot Thymeleaf? - spring

These are my simple Thymeleaf table HTML file and Spring MVC controller codes. First below is my table image.
I try to make some html codes to transfer the post id value to view codes when the 'Edit' or 'Delete' link are clicked, but I have no idea how to do. These are my Spring MVC Controller codes and view.html codes.
#Controller
public class PostController {
#Autowired
private PostService postService;
#RequestMapping("/posts/view/{id}")
public String view(#PathVariable("id") Long id, Model model) {
Post post = postService.findById(id);
model.addAttribute("post", post);
return "posts/view";
}
And,
<table id="blogTable" border="1" width ="1000" height="400" align = "center">
<thead>
<tr>
<th>Post ID</th>
<th>Post Title</th>
<th>Post Content</th>
<th>Date</th>
<th>Author</th>
<th>Action</th>
</tr>
</thead>
<tbody>
<tr th:each="post : ${posts}">
<td th:text="${post.id}">Post ID</td>
<td th:text="${post.title}">Post Title</td>
<td th:text="${post.body}">Post Content</td>
<td th:text="${post.date}">Date</td>
<!-- <td th:text="${post.auther.userName()}">Author</td> -->
<td>
Edit<br/> ==> How to transfer the post.id parameter to th:href?
Delete ==> How to transfer the post.id parameter to th:href?
</td>
</tr>
</tbody>
</table>
I am a beginner in HTML and Spring. How can I put post.id value into view mvc controller through th:href tag?

Use th:href like described in the documentation
th:href is an attribute modifier attribute: once processed, it will compute the link URL to be used and set the href attribute of the tag to this URL.
We are allowed to use expressions for URL parameters (as you can see in orderId=${o.id}). The required URL-encoding operations will also be automatically performed.
If several parameters are needed, these will be separated by commas like #{/order/process(execId=${execId},execType='FAST')}
Variable templates are also allowed in URL paths, like #{/order/{orderId}/details(orderId=${orderId})}
For example (notice the th:href and the parameter postId that receives the value from your variable post):
<td>
Edit<br/> ==> How to transfer the post.id parameter to th:href?
</td>

You can add parameters in parentheses:
<a th:href="#{/index(param1='value1',param2='value2')}">
Thymeleaf evaluates the above to:
<a href="/index?param1=value1,m2=value2">
For example, suppose we set default value to two parameters; name="Dracula" and age = 25.
<a th:href=#{/person(name=${name},age=${age})}></a>

I used in this format and work fine.
<a th:href="#{${urlBase} + '/#!/pedido' + ${other.value}" target="_blank">Link</a>

You can something try like following:
Edit<br/>
Delete

Related

Cannot access attribute in Thymeleaf

i got my student controller here and listStudent atribute
but in my index.html it cannot get atribute
Thanks for reading and helping me
as andrewJames mentioned already, you will need to access your List the same way you defined it.
Say you use the following Controller as you defined:
#GetMapping("/")
public String viewHomePage(Model model) {
model.addAttribute("students", studentService.getAllStudents());
return "index";
}
Then you will need to use "students" in your Thymleaf Template to access the List.
<tr th:each="student : ${students}">
<td th:text="${student.getScode()}">ID</td>
<td th:text="${student.getSname()}"></td>
<td th:text="${student.getDid()}"></td>
<td th:text="${student.getGid()}"></td>
<td th:text="${student.getSsid()()}"></td>
</tr>
Hope it helps.

: EL1008E: Property or field 'LEVEL' cannot be found on object of type 'java.util.ArrayList' - maybe not public or not valid?

please assist with the below. I am trying to display an arraylist returned from the controller and display it to an Html table but I get the above error.
here is my controller code:
#GetMapping(value="/chart" )
public List<List<CanvasjsChartData.DataPointModel>> chart(Model modelMap) {
List<List<CanvasjsChartData.DataPointModel>> dataPointsList = canvasjsChartService.getCanvasjsChartData();
modelMap.addAttribute("dataPointsList", dataPointsList);
System.out.println("dataPointsList");
return dataPointsList;
}
and this is the table I want to display my list in
<table class="table" id="dataTable" style="width:100%">
<thead>
<th>Level</th>
<th>Occurences</th>
</thead>
<tbody>
<tr th:each="item :${dataPointsList}">
<td th:text="${item.LEVEL}"> </td>
<td th:text="${item.OCCURENCES}"> </td>
</tr>
</tr>
</tbody>
I know for sure the ArrayList has the data I require as shown below I dont know why its giving me the error
Your debug shows you have an List<List<CanvasjsChartData.DataPointModel>> (two Lists inside of each other) -- when your HTML is expecting List<CanvasjsChartData.DataPointModel>. You should fix that in your controller/model by only returning a single list.
You could also display your HTML like this (where you loop over the 0th element of the outer array):
<tr th:each="item :${dataPointsList[0]}">
<td th:text="${item.LEVEL}" />
<td th:text="${item.OCCURENCES}" />
</tr>

How to set variable in thymeleaf?

I'm still looking for a way to set values ​​directly into JavaScript function param in thymeleaf. How to set ${variable} to javascript function param directly? Help me.
function **loadDetailView**(no){
location.href = "/home/docs/holiday/detail-view/"+no;
}
<tbody id="docsTr">
<tr th:if="${size} == '0'">
<td colspan=3>No data.</td>
</tr>
<tr th:unless="${size} == '0'" th:each = "docs : ${list}"
style="cursor:pointer;" onclick="**loadDetailView**(1)">
<td th:text="${docs.board_no}">1</td>
<td th:text="${docs.name}">Brian</td>
<td th:text="${docs.holiday_type}">Annual</td>
</tr>
</tbody>
I think you might be mixing concepts here. A javascript function can't recieve a thymeleaf parameter, because what thymeleaf does is "compiling" the page before sending it to the client. Once it's on the client (and javascript may execute) there is no thymeleaf anymore.
What you can do is make each onclick call to loadDetailView have a different parameter in each <tr>, in the following way:
<tr th:unless="${size} == '0'" th:each = "docs, iter : ${list}"
style="cursor:pointer;" onclick="loadDetailView([[${iter.index}]])">
Which would call loadDetailView with 0, 1, 2, etc depending on the row.

Spring Boot And Thymeleaf remain on the same page on post request is made

I've created an web app that searches for online car ads and populates the page with a few tables after a post request.It looks like this:
After Search:
Every table element has a save button which should save those values to the database but my problem is that the page gets refreshed after submitting a post request. How can I do this without refreshing the page?
Table:
<form th:action="#{/saveAd}" method="POST">
<table class="table table-sm table-hover">
<thead class="thead-dark">
<tr>
<th>Imagine</th>
<th>Titlu Anunt</th>
<!-- <th style="width: 16.66%">Link</th> -->
<th>Pret</th>
<th>Oras</th>
</tr>
</thead>
<tbody id="myTable">
<th:block th:each="element : ${lista}">
<trth:onclick="'javascript:rowClicked(\'' + ${element.url} + '\');'">
<td><img th:src="#{${element.img}}" class="size" /></td>
<td th:text="${element.title}"></td>
<td th:text="${element.pret}"></td>
<td th:text="${element.oras}"></td>
<td><input class="btn btn-danger" type="submit"value="Save"></td>
</tr>
</th:block>
</tbody>
Controller:
#RequestMapping(path = "/saveAd", method = RequestMethod.POST)
public String saveAd(#ModelAttribute("adValue") AdValue adValue) {
System.out.println(adValue.getImg());
System.out.println(adValue.getLink());
System.out.println(adValue.getOras());
System.out.println(adValue.getPret());
System.out.println(adValue.getTitle());
return "home";
}
And also, how could I bind the list to a model object after pressing the save button?
I guess you may like this project. It is similar with what you need :
https://github.com/adinafometescu/tutorials/tree/master/spring-elasticsearch
You can use .bootstrapTable(). It a very method to update dynamically your table.
<table id="car-table" class="table table-striped">
<thead>
<tr>
<th data-field="id">Id</th>
<th data-field="title">Title</th>
<th data-field="price">Price</th>
<th data-field="city">City</th>
<th data-width="10" data-formatter="saveButtonFormatter"/>
</tr>
</thead>
</table>
The beauty is that it will map the data-field to a java object.
js stuff:
function saveButtonFormatter(value, row, index){
var adId = row.id;
return "<button class=\"btn btn-danger \" data-title=\"Save\"
data-toggle=\"modal\" onclick=\"saveAd(\'"+adId+"\')\"
</button>"
}
The function saveAd(adId) will call the rest endpoint and will update the bootstrap table on success.
I see that in your thymeleaf you don't have inputs. I suggest to not post your entire object if you don't need user input, just the id.
// anotate the controller class with #RestController
#Autowired
AdService adService;
#PostMapping(path = "/ad/{id}")
public ResponseEntity<?> saveAd(#PathVariable("id") String id) {
adService.saveAd(id);
return new ResponseEntity<>(HttpStatus.ACCEPTED);
}
P.S : don't write code in Romanian :D

spring mvc mapping - send value between controllers

I have got webapp in spring 3 mvc. The case is that I have index page with url, when user click on them should be display another page with details of choosed information. Now the details page is shown but without any information (on index page is creating model with correct variable but not in details controller - in debug mode).
index controller method:
#RequestMapping(value="/{site}", method = RequestMethod.GET)
public String showDetails(#RequestParam(value = "site", required = true) String site, Model model){
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
return "details";
}
index html:
<form action="#" th:object="${product}" method="post" th:action="#{/details}">
<table border="0" width="600" th:each="sb, poz : ${product}" >
<tr >
<td rowspan="3" width="20"><span th:text="${poz.count}"></span></td>
<td>
<a th:href="#{/details/(site=${sb.tytul})}" th:value="${site}"><span th:text="${sb.tytul}"></span></a>
</td>
</tr>
<tr >
<td><span th:text="${sb.adres}"></span></td>
</tr>
<tr>
<td>category:<b><span th:text="${sb.category.name}"></span></b></td>
</tr>
</table>
</form>
details controller method:
#RequestMapping(value = "details/{site}", method = RequestMethod.GET)
public String showHomePage(#PathVariable(value = "site") String site, Model model){
model.addAttribute("product");
return "details";
}
details html:
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="${tytul}"></span></td>
<td>
<span th:text="${opis}"></span>
</td>
<td><span th:text="${adres}"></span></td>
</tr>
</table>
</form>
I don't have any ideas how to map the details site (I tried a lot of solution but nothing). Thanks for help.
With thymeleaf, using th:object, you need to reference the fields of that object with *{}
<form th:object="${product}" method="get" th:action="#{/details}">
<table border="1" width="600" >
<tr >
<td ><span th:text="*{tytul}"></span></td>
<td>
<span th:text="*{opis}"></span>
</td>
<td><span th:text="*{adres}"></span></td>
</tr>
</table>
</form>
assuming tytul, opis, and adres are fields of product. Unless it's a type, don't forget
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in your details controller method, otherwise you won't have a Catalog model attribute.
inside your details controller where are you setting product object in your model ?
model.addAttribute("product");
is just settingstring object "product", fetch the product object and set it in details controller like you have done in showDetails method
Change
model.addAttribute("product");
To
Catalog product = catalogEndpoint.getByTitle(site);
model.addAttribute("product", product);
in "showPage" method.

Resources