Spring Thymeleaf pass object attribute to href button submit - java

I'm trying to do a form action where I show selected lists for each of some grouped values. After the user chooses a value in one of these lists I want to put the name of this object into a button link as a parameter but the parameter values are empty. I don't know how can I do it.
Here is my code for that:
In my controller:
#RequestMapping(value="/teacher/depts", method=RequestMethod.GET)
public String depts(Model model) {
model.addAttribute("deptsfields", fieldOfStudyService.findAllFieldsForAllDepartments());
model.addAttribute("field", new FieldOfStudy());
return "teacher/depts";
}
#RequestMapping(value="/deptsfields", method=RequestMethod.POST)
public String deptsfields(#ModelAttribute(value="field") FieldOfStudy field) {
return "teacher/depts";
}
And my html page:
<form action="#" th:action="#{/deptsfields}" th:object="${field}" method="post">
<table>
<tr>
<th>WydziaƂ</th>
<th>Kierunek</th>
</tr>
<tr th:each="entry : ${deptsfields}">
<td th:text="${entry.getKey().details.departmentFullName}"
th:value="${entry.getKey().details.departmentFullName}"
th:field="*{details.department.details.departmentFullName}"></td>
<td>
<select id="fieldslist" class="form-control" th:field="*{details.fieldOfStudyName}">
<option selected="selected" value="">Wybierz...</option>
<option th:each="field : ${entry.getValue()}" th:value="${field.details.fieldOfStudyName}" th:text="${field.details.fieldOfStudyName}"></option>
</select>
</td>
</tr>
</table>
<a th:href="#{/teacher/groups(field=${field.details.fieldOfStudyName}, dept=${field.details.department.details.departmentFullName})}" class="btn btn-info" role="button">Dalej</a>
</form>
After click the button I'm redirected to this page:
http://localhost:8080/teacher/groups?field={here should be name but is empty}&dept={here should be name but is empty}
What I'm doing wrong?

You have an error in your link, try this
<a th:href="#{'/teacher/groups?field=' + ${field.details.fieldOfStudyName} + '&dept=' + ${field.details.department.details.departmentFullName}}" class="btn btn-info" role="button">Dalej</a>

Related

Required request parameter 'formulaId' for method parameter type String is not present - Thymeleaf, SpringBoot

I'm having an issue where I have a form that will save all updates to a formula. This loads fine and everything works except for when trying to delete an ingredient within a list that is in the updateFormula object.
When I pass my two #RequestParameters in to delete a specific ingredient, I recieve the error:
Required request parameter 'formulaId' for method parameter type String is not present
This has stumped me as the formulaId parameter is for the first #GetMapping method updateFormula, which retrieves the formula information that can be updated. I have tried adding the formulaId as a model object, and pass that into the deleteIngredientInFormula method, but that did not work either.
#GetMapping to get all formula details to display
#GetMapping("/update-formula")
public String updateFormula(#RequestParam("formulaId") String id, Model model) {
//unwraps the optional formula object if present, then adds to the model.
formulaService.getFormulaById(id).ifPresent(f -> model.addAttribute("updatedFormula",f));
return "Update-Formula-Form";
}
#GetMapping to select a specific ingredient in the list to delete
#GetMapping("delete-ingredient")
public String deleteIngredientInFormula(#RequestParam("ingredientId") String inId,
#RequestParam("formId") String formId) {
formulaService.deleteIngredientInFormula(formId, inId);
return "redirect:/update-formula";
}
Thymeleaf Page: Update-Formula-Form
<div class="container">
<h2>Formula Update Form</h2>
<form action="#" th:action="#{/save-updated-formula}" method="post" th:object="${updatedFormula}">
<input type="text" th:readonly="true" th:field="*{formulaId}">
<input type="text" th:field="*{formulaName}">
<input type="text" th:field="*{dosageForm}">
<input type="text" th:readonly="true" th:field="*{unitWeight}">
<input type="text" th:field="*{servingSize}">
<!--FORMULA INGREDIENTS (SELECT ACTION) -->
<div class="container table-responsive">
<table class="table table-striped">
<thead class="table-light">
<tr>
<td>Ingredient ID</td>
<td>Ingredient Name</td>
<td>Type</td>
<td>Potency</td>
<td>Manufacturer</td>
<td>Label Claim (mg)</td>
<td>Delete Ingredient</td>
</tr>
</thead>
<tbody>
<tr th:each="ingredient, holder : *{ingredients}">
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].ingredientId}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].ingredientName}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].type}"></td>
<td><input th:field="*{ingredients[__${holder.index}__].potency}"></td>
<td><input th:readonly="true" th:field="*{ingredients[__${holder.index}__].manufacturer}"></td>
<td><input th:field="*{ingredients[__${holder.index}__].labelClaim}"></td>
<td>
<a th:href="#{/delete-ingredient(ingredientId=${ingredient.getIngredientId()}, formId=${updatedFormula.getFormulaId()})}"
class="btn btn-info btn-sm">Delete</a>
</td>
</tr>
</tbody>
</table>
</div>
<button type="submit" class="btn btn-info col-2">Save Formula Details</button>
</form>
</div>
When you call the #GetMapping("delete-ingredient") endpoint you are then redirecting to update-formula which requires formulaId. That is why you are getting the error. You are basically redirecting to update-formula without any additional data. You need to add that as follows:
#GetMapping("delete-ingredient")
public String deleteIngredientInFormula(#RequestParam("ingredientId") String inId,
#RequestParam("formId") String formId) {
formulaService.deleteIngredientInFormula(formId, inId);
return "redirect:/update-formula?formulaId=" + formId;
}
Additionally, you might want to use the same parameter names for the same thing. You have #RequestParam("formulaId") String id and #RequestParam("formId") String formId which if I understood this correctly are one and the same thing formulaId.
Finally, you definitely shouldn't use a GET to delete data. That is why the DELETE HTTP method exists.

Convert string to long in java

I am working with a spring boot project and I am trying to create a route in the controller that works with a dynamic number of parameters. The route looks like this:
#RequestMapping(value = "/addItem", method = RequestMethod.POST)
public String addItem(ModelMap model, #RequestParam Map<String,String> allRequestParams) {
String stringId = allRequestParams.get("id");
System.out.println(stringId);
long id = Long.valueOf(stringId);
System.out.println(id);
...
}
I need to convert the id parameter to a Long and I have tried to do this with Long.valueOf(stringId) and Long.parseLong(stringId) but when I call the route with the parameter id as 1, I get this error:
Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is java.lang.NumberFormatException: For input string: "1
"] with root cause
java.lang.NumberFormatException: For input string: "1
I call the route from a form like this:
<form method="POST" action="addItem">
<div class="form-group">
<table id="details" class="table table-responsive">
<tr id="type">
<th class="text-left select-title">Type* :</th>
<td>
<select name="id" id="input" class="form-control form-control-sm inv-select" required>
<option value="" disabled selected>Selected...</option>
<%# include file = "common/dropdown.jsp" %>
</select>
</td>
</tr>
<tr id="component1">
<th class="text-left select-title">Type of Component * :</th>
<td>
<select id="select" name="component1" class="form-control form-control-sm inv-select" required>
<option value="" disabled selected>Selected...</option>
<%# include file = "common/dropdown.jsp" %>
</select>
</td>
<th class="text-left quant-title">Quantity * :</th>
<td class="quantity-field">
<input name="quantity1" type="number" step="any" placeholder="Quantity" class="quantity-input" required>
</td>
</tr>
<tr class="table-row">
<td>
<button onclick="addComponent()" id="add-component" class="btn btn-md btn-outline-success"> + Add Component</button><br>
</td>
<td>
<button onclick="removeComponent()" id="rem-component" class="btn btn-md btn-outline-danger"> - Remove Component</button><br>
</td>
</tr>
<tr>
<th>
<input type="submit" name="submit" id="submit">
</th>
</tr>
</table>
</div>
</form>
The print statements in the controller route are there for debugging and only the first print statement prints. How can I correctly convert the string to a long?
You said the string is "1\r\n".
However, Long.valueOf() only works strings that only consist of numbers.
In order to fix this, use trim():
Long.valueOf(stringId.trim());
I would recommend you to use Long#parseLong instead of Long#valueOf as it returns long instead of Long. That gets rid of useless object creation.
#RequestMapping(value = "/addItem", method = RequestMethod.POST)
public String addItem(ModelMap model, #RequestParam Map<String,String> allRequestParams) {
String stringId = allRequestParams.get("id");
System.out.println(stringId);
long id = Long.parseLong(stringId.trim());
System.out.println(id);
...
}

Passing thymeleaf information to a hidden form

I am trying to pass the information from a thymeleaf list and trying to add it to database.
I am getting data from the tmdb and it will be changing so i display the information obtain to the endpoint "/LatestMovies" this information is not saved in the db and ether should it be. so i am trying to add a save button for the custumer to add the movie listed.(its simple it just haves movieid and moviename)
Showing the movies listed i have no problem and it works fine but where i get error is when i add a hidden form. The current code i have is this:
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form action="#" th:action="#{/LatestMovies}" th:object="${addMovies}" method="post">
<p><input type="hidden" th:field="*{id}" th:attr="value = ${LatestMovies.id}" /></p>
<p><input type="hidden" th:field="*{movieName}" th:attr="value = ${LatestMovies.movieName}" /></p>
<p><input type="submit" value="Submit" /></p>
</form>
</td>
</tr>
</table>
#Controller
public class LatestMoviesController {
#Autowired
private LatestMoviesDao listOfMovies;
#Autowired
private savedMoviesDao movieRepo;
#GetMapping("/LatestMovies")
public String prueba(Model model) {
TmdbMovies movies = new TmdbApi("22914f477aaa3e7f86c6f5434df8d1eb").getMovies();
ResultsPage<MovieDb> movie = movies.getPopularMovies("en", 1);
for(int i=0; i <= 19; i++){
int movieId = movie.getResults().get(i).getId();
String movieName = movie.getResults().get(i).toString();
listOfMovies.save(new LatestMovies(movieId, movieName));
}
model.addAttribute("latestMovies", listOfMovies.findAll());
return "index";
}
#PostMapping("/LatestMovies")
public String save(#ModelAttribute("addMovies") Model model, SavedMovies addMovies) {
movieRepo.save(addMovies);
return "index";
}
}
Thx in advance
First, let's change your form. You don't need to add a new object to it, since you are already iterating through a list of them. That way, you will also avoid having to add the value for each field manually using th:attr. What we are gonna do, is send the required params separately and then build our movie object with them.
<div class="container">
<table class="table table-hover">
<tr>
<th>Id</th>
<th>Name</th>
</tr>
<tr th:each="LatestMovies : ${latestMovies}">
<td th:text="${LatestMovies.id}"></td>
<td th:text="${LatestMovies.movieName}"></td>
<td>
<form th:action="#{/LatestMovies}" method="post">
<p><input type="hidden" th:value="${LatestMovies.id}" name="id"/></p>
<p><input type="hidden" th:value="${LatestMovies.movieName}" name="name"/></p>
<p><input type="submit" value="Submit"/></p>
</form>
</td>
</tr>
</table>
</div>
Now, on your controller, do the following modifications.
#PostMapping("/LatestMovies")
public String save(#RequestParam("id") Integer id, #RequesParam("name") String name) {
SavedMovies movie = new SavedMovies();
movie.setId(id);
movie.setName(name);
movieRepo.save(movie);
return "index";
}
These changes should do the trick.

HTTP Status 400 - Required String parameter 'userid' is not present

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

Spring Thymeleaf - How to edit(update) a user selected entity(object) via Thymeleaf form?

In my application the user is show a list of exam objects and they select one to edit.
When they click the edit link it brings them to a HTML page where the URL contains that exams ID.
I would like to know how to pass the id of the exam to the controller.
I'm getting this error: "Missing URI template variable 'id' for method parameter of type Long"
I would also like to know how to make existing values appear in the forms text boxses.
HTML allSubjects.html where the user selects a subject to edit: (this all works)
<h4> exams:</h4>
<div th:each="exam : ${subject.exam}">
<h4 th:text="${exam.examTitle}"/>
<a th:href="#{/editExam.html(id=${exam.examId})}">Edit Exam</a>
Edit exam HTML:
<form action="#" th:action="#{/editExam.html{examId}}" th:object="${exam}" method="put">
<table>
<tr>
<td> Exam Title:</td>
<td><input type="text" th:field="*{examTitle}" th:text="${exam.examTitle}"/></td>
<!-- <td th:if="${#fields.hasErrors('examTitlee')}" th:errors="*{examTitle}">error message</td> -->
</tr>
<tr>
<td> Exam grade worth </td>
<td><input th:field="*{examGradeWorth}" /></td>
<!-- <td th:if="${#fields.hasErrors('examGradeWorth')}" th:errors="*{examGradeWorth}">error message</td> -->
</tr>
<tr>
<td>examGradeAchieved</td>
<td><input th:field="*{examGradeAchieved}"/></td>
</tr>
<tr>
<td><button type="submit">Submit post</button></td>
</tr>
</table>
</div>
</form>
My controller:
#RequestMapping(value = "/editExam.html{examId}", method = { RequestMethod.GET, RequestMethod.PUT })
public String editExam(#ModelAttribute("exam") #PathVariable(value = "id")Long examId, #RequestBody Exam exam,Model model, BindingResult result) {
examRepository.findOne(examId);
model.addAttribute("examTitle", exam.getExamTitle());
model.addAttribute("examGradeWorth", exam.getExamGradeWorth());
model.addAttribute("examGradeAchieved", exam.getExamGradeAchieved());
exam.setExamTitle(exam.getExamTitle());
exam.setExamGradeWorth(exam.getExamGradeWorth());
exam.setExamGradeAchieved(exam.getExamGradeAchieved());
examRepository.save(exam);
return "editExam";
}
WHen I try to run all the above code just to see if the form displays I get the following error: Missing URI template variable 'id' for method parameter of type String

Categories

Resources