Thymleaf Spring MVC Button executes Java method - java

So this is what I have in my HTML file:
<ul>
<th:block th:object="${Post}">
<li class="post" th:each="Post : ${Posts}">
<p th:text ="${Post.getPostText()}"></p>
<button th:onclick = "${Post.upvote()}">Upvote</button>
<button th:onclick = "${Post.downvote()}">Downvote</button>
<p th:text = "${Post.getPostVotes()}"></p>
</li>
</th:block>
</ul>
I want the button to execute a method within the Post class. I'm not sure if I'm using the correct Thymeleaf 'tag'. Right now, when the page loads, it executes the post upvote and downvote methods.
Can anyone help out? I have a feeling I'm using the wrong Thymeleaf Tag.

You need to do a post or get request to invoke those methods. That will only work in JSF, but you can execute the method before de page is rendered as html.
for example this line
<p th:text ="${post.getPostText()}"></p>
will be executed before the page is rendered .
What I do here is to hide a form for both action, two buttons with a name attributes and pass some sort of identifier to know witch entity I'm updating.
In my controller would have two methods that responds to each parameter and return a view or JSON.

So they reason I couldn't do what I wanted to do was because Thymeleaf generates HTML as before the pages loads. It doesn't sit in the HTML waiting to be triggered. I ended up changing the HTML to go to a different URL that would be unique to the post.
<ul>
<th:block th:object="${Post}">
<li class="post" th:each="Post : ${Posts}">
<p th:text ="${Post.getPostText()}"></p>
<a th:href = "#{/post?id={id}&vote=1(id=${Post.getPostId()})}">Upvote</a>
<a th:href = "#{/post?id={id}&vote=0(id=${Post.getPostId()})}">Downvote</a>
<p th:text = "${Post.getPostVotes()}"></p>
</li>
</th:block>
</ul>
And this was the corresponding java code in my controller that would update the object:
#RequestMapping(value = "/post", params = {"id", "vote"})
public String PostVoting(#RequestParam("id") Long id, #RequestParam("vote") int vote)
{
if (currentUser.voteOnPost(id.toString())){
return "redirect:/home";
}
if(vote == 1){
int votes = thePostRepository.findById(id).get().getPostVotes() + 1;
thePostRepository.updateVotes(votes, id);
}
else{
int votes = thePostRepository.findById(id).get().getPostVotes() - 1;
thePostRepository.updateVotes(votes, id);
}
return "redirect:/home";
}
Also, this next part is important if you want to update things like I did:
#Transactional
#Modifying
#Query("UPDATE Post SET votes = :votes WHERE id = :id")
void updateVotes(#Param("votes") int votes, #Param("id") Long id);

Related

In Spring Boot Thymeleaf , how to pass list of object to th:value ??? I would like to create tag input

Here is my form html
<div class="card-body">
<form action="#{/orgCategoryTag/create}" method="POST">
<div class="form-group">
<label for="form-tags-1" class="text-dark font-bold">Add new tags</label>
<input id="form-tags-1" name="tags-1" type="text" th:value="${tags}">
</div>
<a
type="button"
class="btn btn-success" href="#"
data-placement="top" title="Tooltip on top">Add
</a>
</form>
</div>
Here is Get mapping for rendering form
#GetMapping(value = "/form")
public String categoryForm(Model model, BindingResult result) {
Long testId = (long)1;
OrgCategory orgCategory = new OrgCategory();
List<OrgCategoryTagModel> orgCategoryTags = orgCategoryTagRestController.getAllByCategoryId(testId);
model.addAttribute("category", orgCategory);
model.addAttribute("tags", orgCategoryTags);
model.addAttribute("add", true);
return "orgCategoryForm";
}
For displaying a list of options (tags in your context), please use a combo-box, they are better suited to display a list of options.
<select>
<option
th:each="tag: ${tags}"
th:text="${tag.name}"
th:value="${tag.id}"
/>
</select>
<select> is the tag for creating a combobox and <option> are the different options available in the combobox. I have used a for each loop to create different options for the combobox where tag represents your object OrgCategoryTagModel.
I do not know your object OrgCategoryTagModel, but I am assuming you want to display the name of the tag (tag.name) and use the id of OrgCategoryTagModel (tag.id) as the value to be saved when making a selection.

how to print list of list and other type of data in jsp

i am trying to fetch data from database in spring mvc, this is my code for fetching data
#Override
public List getOrderDetail(Integer shop_id) {
// TODO Auto-generated method stub
SQLQuery query = sessionFactory.getCurrentSession().createSQLQuery(
"SELECT order_id,shop_id,delivery_address,total_amount FROM master_order WHERE shop_id =" + shop_id);
SQLQuery query1 = sessionFactory.getCurrentSession().createSQLQuery(
"SELECT itm.image,itm.name,itm.brand,odr.quantity,itm.offerprice,(itm.offerprice*odr.quantity) AS Total,modr.cust_id FROM master_order modr\r\n"
+ "INNER JOIN tblorder odr ON modr.order_id = odr.order_id INNER JOIN item itm on odr.item_id = itm.item_id WHERE modr.shop_id ="+shop_id);
query.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
query1.setResultTransformer(Criteria.ALIAS_TO_ENTITY_MAP);
List results = query.list();
List results1 = query1.list();
results.add(results1);
System.out.println(results);
return results;
}
above System.out.println(results); statement give following output
[{shop_id=1, delivery_address=1, abc, xyz, aaa, USA, order_id=6, total_amount=1800}, [{image=Screenshot (19).png, quantity=8, Total=800, name=DhruvRajkotiya, offerprice=100, brand=gsgsrgs, cust_id=2}, {image=Screenshot (19).png, quantity=10, Total=1000, name=qwe, offerprice=100, brand=asdf, cust_id=2}, {image=Screenshot (19).png, quantity=1, Total=100, name=ewq, offerprice=100, brand=gsgsrgs, cust_id=2}]]
i want print order_id as well as {image=Screenshot (19).png, quantity=10, Total=1000, name=qwe, offerprice=100, brand=asdf, cust_id=2} in jsp page
this is my controller code
#RequestMapping(value = "/notifications", method = RequestMethod.GET)
public String notifications(Model model, HttpServletRequest request) {
if (request.getSession().getAttribute("shopkeeper") == null) {
return "redirect:login";
} else {
Shopkeeper sp = (Shopkeeper) request.getSession().getAttribute("shopkeeper");
model.addAttribute("order", shopkeeperService_shopkeeper.getOrderDetail(sp.getSk_id()));
return "shopkeeper/notifications";
}
}
this is my jsp code
<div class="row">
<c:forEach items="${ order}" var="order">
<div class="col-lg-12">
<div class="card">
<div class="card-header" style="padding-bottom: 5px;">
<h6># ${order.shop_id }</h6>
</div>
<div class="card-body">
<div class="col-lg-2" style="float: left;">Image</div>
<div class="col-lg-2" style="float: left;">Product name</div>
<div class="col-lg-2" style="float: left;">Product brand
</div>
<div class="col-lg-1" style="float: left;">Quantity</div>
<div class="col-lg-1" style="float: left;">Unit Price</div>
<div class="col-lg-1" style="float: left;">Total</div>
<div class="col-lg-3" style="float: left;">Approve of
request</div>
</div>
<div class="card-body">
<div class="col-lg-6" style="float: left;">Delivery
Address</div>
<div class="col-lg-6" style="float: left;">Total Amount</div>
</div>
</div>
</div>
</c:forEach>
</div>
i want to print
my question concept is order_id,address,total_amount one time and multiple bought item that can be one or more
how i can print
The way to "send" some data to a JSP page is to set and pass a request (or session) attribute.
From a Servlet, which handles current request, in a doGet() or doPost() method (depending on the HTTP request method used), you can do:
request.setAttribute("attributeName", attributeObject);
request.getRequestDispatcher("<name_of_your_page>.jsp").forward(request, response);
where the attributeName is a string, which will be treated as a reference to the attributeObject on a JSP page.
Then on the JSP page, you can use JSTL library and Expression Language (see this tutorial regarding JSTL and this one regarding JSP & EL in general). To iterate over the list, which has been passed as a request attribute, use <c:forEach> tag from JSTL.
First of all you need to import the core JSTL tags by placing this line on the top of your JSP:
<%# taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %>
Another useful statement to put under the latter is:
<%# page isELIgnored="false" %>
which tells your web browser to evalue the expressions written in EL instead of including them in HTML body as a plain text.
Provided that you used the string "orders" to name the collection set as attribute, the <c:forEach> tag usage can look similarly as below. You'll probably want to structure it differently and the field names (like order.order_id) can be different in your case, but I think you can get the idea.
<c:forEach item="order" items="${requestScope.orders}">
<p>${order.order_id}</p>
<p>${order.delivery_address}</p>
...
</c:forEach>
You can save the list as a model attribute. For example you want to save the current user:
model.addAttribute("user",user);
and access this attribute in your jsp file inside a div maybe :
<div> ${user.name} </div>
The controller method could look like this:
#RequestMapping( value = "/user", method = RequestMethod.GET )
public String displayUser(final Model model)
{
final User user = userService.findUserById(1); // here you'll provide custom implementation
model.addAttribute("user",user);
return "somejsppage.jsp";
}
If you want to add a List to your model:
final List<User> users = fillUserList(); // your implementation here
model.addAttribute("users",users);
You can access every element in that list via <c:forEach> tag:
<%#taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c"%>
<html>
<body>
<table>
<tr>
<th>First Name</th>
</tr>
<c:forEach items="${users}" var="user">
<tr>
<td>${user.firstName}</td>
</tr>
</c:forEach>
</table>
</body>
</html>

How to get variable value with thymeleaf

I am trying to get make an url to finish on a variable
my template is:
<div th:if="${!user.isEmailValidated()}" class="div-block-13">
<div class="email_confirmed">
Your email is not confirmed!
</div>
</div>
my controller is:
#GetMapping(value = "/email/send/{token}")
public String sendEmail(#PathVariable(value = "token") String token, Model model) {
return "sent-email";
}
I expect url .../email/send/{value of variable} but I get - email/send/$%7Buser.getToken()%7D
The expression ${user.getToken()} is not evaluated by thymeleaf because it's inside a plain href attribute. Use th:href to be able to use thymeleaf expressions: <a th:href="#{'/email/send/' + ${user.getToken()}}">

Having trouble identifying popover text

I'm having trouble coming up with a cssSelector statement for the following control.
<div class="popover-content">
<i class="icon-time"></i>
<h3>24 Hours Risk Free!</h3>
<p>
Book now and
<strong>cancel for free up to 24 hours</strong>
</p>
</div>
I need to simply write a test that verifies this warning exists. Anyone have any ideas?
You can use JQuery
<a id="btnT" class="btn btn-xs btn-warning">Test</a>
var x = false;
$(document).ready(function(){
$('#btnT').popover({
placement: 'bottom',
title: '${trainingDetail.title}',
content: '${trainingDetail.description}',
trigger: 'click',
html : true,
container: 'body'
}).hover(function() {
if (x) {
$(this).popover('hide');
x = false;
}
else {
$(this).popover('show');
x = true;
}
});
});
Just find out the div tag using class and get its text. It will get you all the text in it for the h3 and p tags.
driver.findElement(By.className("popover-content")).getText();
Assuming you are able to already hover over it etc etc... Use the Actions class and moveToElement method.

Updating datatables with ajax

I am using spring MVC 4 and dandelion jsp datatables.
I wish to update a column in the table's column (progress percentage) every X seconds without reloading the entire page (probably via ajax).
The update should refer to the controller each X seconds, fetch the requested data and update the column with the results.
I tried to add a simple ajax for external div (not within the table) as a start but it seems to corrupt the table:
<script>
function testAjax() {
$.ajax({
url : 'ajaxtest.html',
success : function(data) {
$('#result').html(data);
}
});
}
<script>
var intervalId = 0;
intervalId = setInterval(testAjax, 6000);
</script>
<body>
<div id="result">123</div>
<div class="container-table">
<datatables:table id="listRecordsModel" data="${listModel}" row="record" cssClass="table table-hover table-striped table-bordered" cellspacing="2" scrollX="120%"
theme="bootstrap2" pageable="true" info="true">
<datatables:column title="Record ID" property="recordId"/>
.
.
.
The controller:
#RequestMapping(value = "/ajaxtest", method = RequestMethod.GET)
public #ResponseBody
String getTime() {
System.out.println("------------------------------------random");////////////////////
return "WORKS!!!";
Is there a simple way doing that?
Thanks,
Mike
I found the problem - the path to the html file was wrong and met with the initial method in the controller so the page loaded from scratch every 6 seconds.
I replaced url : 'ajaxtest.html', with url : '../../ajaxtest.html',.
Thanks anyway!

Categories

Resources