I have a view in which I have a Form to create a new Exercise object, and a table to display all exercises. Now I want that the table automatically refreshes with the newly created exercise. Currently it displays the table as empty, until I manually go to localhost:8080/exercise again.
Here's my controller:
#Controller
public class ExerciseController {
#Autowired
private ExerciseService exerciseService;
#Autowired
private ModelMapper modelMapper;
#GetMapping("/exercise")
public String exerciseView(final Model model) {
List<Exercise> exerciseList = exerciseService.getAllExercises();
model.addAttribute("exerciseDTO", new ExerciseDTO());
model.addAttribute("title", "Create an Exercise");
model.addAttribute("exercises", exerciseList);
return "exercise";
}
#PostMapping("/exercise")
public String createExercise(#ModelAttribute final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
this.exerciseService.createExercise(exercise);
return "exercise";
}
}
And my thymeleaf template:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form action="#" th:action="#{/exercise}" th:object="${exerciseDTO}" method="post">
<p>Name: <input type="text" th:field="*{name}" /></p>
<p>Description: <input type="text" th:field="*{description}" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" th:field="*{bpm}" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Now I thought the createExercise method returning "exercise" would call the exerciseView method and thus calling exerciseService.getAllExercises(). Is there a way to achieve this functionality? Or is there an even better way, without reloading the whole page?
To serve up data without page refreshes you'd need a client side technology like Angular or React. Or plain old javascript. But you can't serve up new data to a page in spring mvc w/o page refreshes.
You can use AJAX to send requests from a client side to a server side and receive an answer without refreshing the page.
Unfortunately I don't have enough time and I can't complete the code but you can do something like this:
function submitItems() {
var contextPath = $("meta[name='ctx']").attr("content");
var exerciseDto = {};
exerciseDto.name = $("#name").val();
exerciseDto.description = $("#description").val();
exerciseDto.typeSelector = $("#typeSelector).val();
exerciseDto.bpmInput = $("#bpmInput").val();
$.ajax({
dataType : "json",
type : "post",
url : contextPath + "/exercise",
data : JSON.stringify(exerciseDto),
cache : false,
contentType : "application/json",
beforeSend : function(xhr) {
xhr.setRequestHeader(header, token);
},
success : function(data) {
console.log(data);
//HERE YOU NEED ACTION TO UPDATE TABLE.
},
error : function(jqXHR, textStatus, errorThrown) {
console.log(jqXHR.responseText);
console.log('getJSON request failed! ' + textStatus);
}
});
}
and then your view must be like this:
<!DOCTYPE HTML>
<html xmlns:th="http://www.thymeleaf.org">
<head th:replace="template :: head"></head>
<body>
<header th:replace="template :: navbar"></header>
<h1>Form</h1>
<form onsubmit="submitItems();return false;">
<p>Name: <input id="name" type="text" /></p>
<p>Description: <input id="description" type="text" /></p>
<p>Exercise type:
<select th:field="*{type}" id="typeSelector">
<option th:each="type : ${T(com.nsterdt.routinierbackend.data.enums.ExerciseType).values()}"
th:value="${type}" th:text="${type.displayName}">
</option>
</select>
</p>
<p id="bpmRow">BPM: <input type="number" id="bpmInput" /></p>
<p><input type="submit" value="Submit" /> <input type="reset" value="Reset" /></p>
</form>
<br>
<table>
<tr>
<th>Name</th>
<th>Description</th>
<th>Type</th>
<th>BPM</th>
</tr>
<tr th:each="exercise : ${exercises}">
<td th:text="${exercise.name}"></td>
<td th:text="${exercise.description}"></td>
<td th:text="${exercise.type}"></td>
<td th:text="${exercise.bpm}"></td>
</tr>
</table>
</body>
</html>
Bear in mind that you need to create an JS action that will update the table. There are quite a few ways of doing that (you can push new data to the Datatable or add new content using JS functions).
I hope this will help you understand a bit more how the AJAX works.
PS. You will have to update your controller as well to return the results, in your instance will be
#PostMapping("/exercise")
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
final Exercise exercise = this.modelMapper.map(exerciseDto, Exercise.class);
//this.exerciseService.createExercise(exercise);
//return "exercise";
return this.exerciseService.createExercise(exercise);
}
You will have to change this line
public createExerciseDomainTYPEHERE createExercise(#RequestBody final ExerciseDTO exerciseDto) {
to your createExercise Domain Type.
Related
<form name="update" id="update" action="update" method="post">
<table border="0">
<tr>
<th></th>
<th>Del</th>
<th>Name</th>
<th>Address</th>
<th>Remarks</th>
</tr>
<c:forEach items="${recList}" var="rec" varStatus="loop">
<tr>
<td><input type="checkbox" name="del" value="${loop.index}"/></td>
<td><input type="text" name="name" value="${rec.getName()}"/></td>
<td><input type="text" name="address" value="${rec.getAddress()}"/></td>
<td><input type="text" name="remarks" value="${rec.getRemarks()}"/></td>
<td><input type="hidden" name="index" value="${loop.index}"/>
<input type="submit" value="Update"/></td>
</tr>
</c:forEach>
</table>
</form>
This is my code for this view
My problem is when I click the UPDATE button, the form seems to send series of values like
name= "aiko,hashimoto,yuki,ode"
instead of sending only
name="hashimoto"
to the Controller if second UPDATE button is clicked. Can anyone help me with my issue?
<form> tag can't be inside <table>. By logic, I think it's best to put the inside the loop but it is not possible. Is there another way to solve this?
Submit your form with javascript function using ajax call like below sample code.
send single value from form submit not possible
function submitform(){
var messageId = $("#messageId").val();
$.ajax({
url:'<c:url value="/dummy/dummyMessageId"/>',
datatype:'JSON',
data: 'messageId=' + messageId ,
success : function(response) {
if (null != response && response.success) {
} else {
var errorDiv = $('#Error');
errorDiv.html(response.error.message);
}
}
});
}
<input type="button" value="Update" onclick="submitform()"/></td>
add above code in your HTML input button
my problem is that I need to get the radio buttons that are selected in HTML file and use it in the PostMapping.
<!DOCTYPE html>
<html lang="en" xmlns="http://www.w3.org/1999/xhtml"
xmlns:th="http://www.thymeleaf.org">
<head>
<meta charset="UTF-8">
<title>Do Test Excercise</title>
<script language="javascript">
</script>
</head>
<body>
<h1>Do Test Exercise</h1>
<form method="POST">
<span align="left" th:each="question : ${exercise.getQuestions()}">
<p valign="top" th:text="${question.text}">Text</p>
<tr align="left" th:each="solution : ${question.getSolutions()}">
<input width="5%" type="radio" th:name="${question.question_ID}" th:text="${solution.text}"
th:value="${solution.text}"/><BR>
</tr>
</span>
<input type="submit" value="Submit">
</form>
</body>
</html>
However I don't know how to get that values for the radio buttons and save it in a array of String
#GetMapping("doTest/{post}/{exercise}")
public String doTest(Model model, #PathVariable String exercise) {
model.addAttribute("exercise", exercisesDAO.getExerciseByType(exercise, "Test"));
return "exercise/doTestExercise";
}
#PostMapping("doTest/{post}/{exercise}")
public String doTest(#RequestParam(value = "solution") String[] solution, #PathVariable String post, #PathVariable String exercise, RedirectAttributes redirectAttributes) {
exercisesDAO.solve(exercise, solution, "admin", "Test");
redirectAttributes.addAttribute("post", post);
redirectAttributes.addAttribute("exercise", exercise);
return "redirect:/showMark/{post}/{exercise}";
}
Thanks
You need to change the name of your inputs from th:name="${question.question_ID}", to th:name="${'solution['+ question.question_ID + ']'}". After that, you need to change your controller, so that instead of an array of Strings, it will receive a HashMap, where you will get for each id, the chosen solution.
Form
<form method="POST" th:action="#{doTest/${post.id}/${exercise.id}}">
<span align="left" th:each="question : ${exercise.getQuestions()}">
<p valign="top" th:text="${question.text}">Text</p>
<tr align="left" th:each="solution : ${question.getSolutions()}">
<input width="5%" type="radio" th:name="${'solution['+ question.question_ID + ']'}" th:text="${solution.text}" th:value="${solution.text}"/><BR>
</tr>
</span>
<input type="submit" value="Submit">
</form>
Controller
#PostMapping("doTest/{post}/{exercise}")
public String doTest(#RequestParam(value = "solution") HashMap<String, String> solutions, #PathVariable String post, #PathVariable String exercise, RedirectAttributes redirectAttributes) { ... }
i tried this code for login page and am getting the above error , am new to spring please help me.
#Controller
#RequestMapping("/login")
public class LoginController {
#Autowired
private LoginService loginser;
#RequestMapping("/loginadmin")
public String loginAdmin() {
return "loginadmin";
}
#RequestMapping("/loginemployee")
public String loginEmployee() {
return "loginemployee";
}
#RequestMapping("/adminvalidate")
public #ResponseBody String validateAdmin(#RequestParam(value="userid") String userid, #RequestParam(value="password") String password) {
String result = loginser.validate(userid, password);
if (result.equals("pass")) {
return "redirect:/admin/view";
}
return "error";
}
}
ui
<div id="wrapper">
<div id="header">
<h1>Admin Login</h1>
</div>
</div>
<div id="container">
<div id="content">
<form:form action="adminvalidate"
method="POST">
<table>
<tbody>
<tr>
<td><label>User-Id : </label></td>
<td><input type="text" path="emp_Id" placeholder="User Id" id="userid"/></td>
</tr>
<tr>
<td><label>Password : </label></td>
<td><input type="password" path="emp_firstname" placeholder="Password" id="password"/></td>
</tr>
<tr>
<td><label></label></td>
<td><input type="submit" value="login"></td>
</tr>
</tbody>
</table>
<input type="button" value="back" onclick="window.location.href='/';return false">
</form:form>
</div>
</div>
i need to write code for login page that to check the credentials and am getting 400 error
Since you put an image instead of code ,I can not see the entire code of yours,
According to your question,the reason is the userid parameter is not passed to your controller method,check if you have set the name of user id input element as below:
<input type='text' name='userid' path='emp_id'>
Another possible way to avoid this issue is set the required=false in your controller method:
public #ResponseBOdy String validateAdmin(#RequestParam(value="userid",required=false)){
}
400 error comes when the server was unable to process the request sent by the client due to invalid syntax. check your URL syntax and you didn't give the method name in controller Like POST
Not sure what I'm doing wrong on this one. Attempting to make a button that can delete added entities from database. I'm getting a 405 error but I am not sure if I'm getting this because of something I'm doing in the controller or something badly I wrote in thymeleaf. Thanks for any help.
Controller:
#Controller
public class BuyerController {
private BuyerService buyerService;
#Autowired
public void setBuyerService(BuyerService buyerService){
this.buyerService = buyerService;
}
#RequestMapping("/add-buyer")
public String showBuyerPager(Model model){
List<Buyer> buyers = buyerService.findAllBuyers();
model.addAttribute("buyers", buyers);
model.addAttribute("buyer", new Buyer());
return "add-buyer";
}
#GetMapping("/showBuyerForm")
public String addBuyerForm(Model model){
model.addAttribute("buyer", new Buyer());
model.addAttribute("buyerId", new Buyer().getBuyerId());
return "add-buyer";
}
#PostMapping("/addBuyer")
public String postBuyerForm(#ModelAttribute("buyer") Buyer buyer, Model model){
buyerService.saveBuyer(buyer);
model.addAttribute("buyer", new Buyer());
return "redirect:/";
}
#GetMapping("/deleteBuyer")
public String deleteBuyer(#RequestParam("buyerid") Long id){
buyerService.deleteBuyer(id);
return "redirect:/";
}
}
View:
<!DOCTYPE html>
<html lang="en" xmlns:th="http://www.thymeleaf.org">
<head>
<title>Title</title>
<link href="styles.css" rel="stylesheet" type="text/css"/>
</head>
<body>
<header> Welcome to Toner Stock </header>
<h1>Add Buyer</h1>
<div id="mynav" align="center">
<ul>
<li>Home</li>
<li>Add Buyer</li>
<li>Add Manager</li>
<li>Current Stock</li>
<li>Transactions</li>
<li>Order Form</li>
</ul>
</div>
<div id="display-table" align="center">
<form th:action="#{/addBuyer}" th:object="${buyer}" style="width:100%" method="post">
<table>
<td><label>First Name: </label></td>
<td><input type="text" th:field="*{firstName}"/></td>
<td><label>Last Name: </label></td>
<td><input type="text" th:field="*{lastName}"/></td>
<td><label>Enter Address: </label></td>
<td><input type="text" th:field="*{buyerAddress}"/></td>
<td><input type="submit" value="save"/></td>
</table>
</form>
</div>
<div>
<div>
<table id="info-table" align="center" border="1">
<tr>
<th>First Name</th>
<th>Last Name</th>
<th>Address</th>
</tr>
<tr th:each="buyer : ${buyers}">
<td th:text="${buyer.firstName}"></td>
<td th:text="${buyer.lastName}"></td>
<td th:text="${buyer.buyerAddress}"></td>
<td>
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="post">
<input type="hidden" name="buyerid" id="buyerid" value="${buyer.buyerId}"/>
<input type="submit" value="Delete" onClick="return confirm('sure?')"/>
</form>
</td>
</tr>
</table>
</div>
</div>
<div>
<select>
<option th:each="buyer : ${buyers}"
th:text="${buyer.firstName}"
th:value="${buyer.buyerId}"
></option>
</select>
</div>
<div>
<div>
</div>
</div>
</body>
</html>
I don't know much about Thymeleaf but you can keep it simpler and change your front-end code from form to basic link :
<c:url var="deleteBuyer" value="/DeleteBuyer">
<c:param name="buyerId" value="${buyer.buyerId}" />
</c:url>
<a class="simpleLink" href="${deleteBuyer}">delete</a>
And handle it in your controller :
` #GetMapping("/DeleteBuyer")
public String deleteAnswer(#RequestParam("buyerId") int theId) {
buyerService.deleteBuyer(theId);
return "redirect:/";
}`
I hope this help you.
Change the
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="post">
To GET to conform with the Spring request mapping
<form th:action="#{/deleteBuyer}" th:object="${buyer}" method="get">
Here are all available HTTP Methods
Hi:) I want to display data on "input" when select "select option".
I included jsp page, which have "input" tag, so using ajax send data to included jsp page.
Here's my code. Name is "new_order.jsp"
<script>
$('select#product').change(function() {
var param = "code=" + $('#product').val();
$.ajax({
url : 'add_products/add_products.jsp',
contentType : "application/x-www-form-urlencoded; charset=UTF-8",
data : param,
type : 'POST',
dataType : 'html',
success : function(data, textStatus, jqXHR){
}
});
});
...
</script>
<body>
<table class="add_products_tb table" data-toggle="table">
<tr>
..
</tr>
<tr>
..
</tr>
<tr>
<td>
..
</td>
<td>
<table>
<tr>
<td>
<select name="product" id="product" class="selectpicker" data-width="150px">
<option data-hidden="true">-Select-
<%
try {
query = "select * from new_product";
rs = stmt.executeQuery(query);
while (rs.next()) {
product_code = rs.getString("product_code");
%>
<option value="<%= product_code %>"> <%= product_code %>
<%
}
} catch (SQLException e) {
out.println(e);
} finally {
}
%>
</select>
</td>
</tr>
</table>
</td>
<jsp:include page="add_products/add_products.jsp" />
</tr>
</table>
</body>
The Next Code. This is included jsp, "add_product.jsp"
<script>
$(document).ready(function() {
$('select#product').change(function() {
<%
product_code = request.getParameter("code");
int size = 0;
try {
query = "select * from new_product where product_code='"+product_code+"'";
rs = stmt.executeQuery(query);
while (rs.next()) {
size = rs.getInt("sizes");
%>
$('#size').val("<%= size %>");
<%
}
} catch (SQLException e) {
out.println(e);
} finally {
}
%>
});
});
</script>
...
<body>
<td>
<input type="text" id="size" class="form-control" name="size" />
</td>
<td>
<input type="text" id="color" class="form-control" name="color" />
</td>
<td>
<input type="text" id="price" class="form-control" name="price" value="0" readonly />
</td>
<td>
<input type="text" id="quantity" class="form-control" name="quantity" value="1" />
</td>
<td>
<input type="text" id="total_price" class="form-control" name="total" value="0" readonly />
</td>
</body>
The Problem is, I want to receive the data, "code", from "new_order.jsp" and display the data on "add_product.jsp", but it doesn't display on the page. I also have debugging the page, the data is sent to "add_product.jsp", but didn't display on input.
I changed a variable "product_code", placed on "add_product.jsp" script, to value, not jsp variable but special value in DB. So, there is data on "input"! Just One....
I want to display using jsp variable. Please help me...T.T Thanks.