Pass id to the controller - spring

Firstly, I am passing values from database to the table. In the first column I want to create a form that will pass the id to delete function in Controller.
<tr th:each="blg: ${all}" th:object="${blg}" >
<td>
<form th:action="#{/delete}" th:object= "${blg}" method="post">
<input type="text" th:field="${blg.id}"/>
<button type="submit">Delete</button>
</form>
</td>
<td th:text="*{title}"> title </td>
<td th:text="*{content}"> title </td>
<td th:text="*{category}"> title </td>
<td th:text="*{signature}"> title </td>
</tr>
Controller:
#GetMapping("/show")
public String show(Model model){
List<Blog> all = br.findAll();
model.addAttribute("all",all);
return "show";
}
#RequestMapping(value="/delete", method=RequestMethod.POST)
public String deletePost(#RequestParam Long id){
br.delete(id);
return "redirect:/show";
}
The thymeleaf engine doesn't map the object as this error occcurs:
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'blg' available as request attribute.
What is the way to create a correct form in this case?

Update your html code as shown below:
<tr th:each="blg: ${all}" >
<td>
<form th:action="#{|/delete/${blg.id}|}" method="post">
<button type="submit">Delete</button>
</form>
</td>
<td th:text="${blg.title}"> title </td>
<td th:text="${blg.content}"> title </td>
<td th:text="${blg.category}"> title </td>
<td th:text="${blg.signature}"> title </td>
</tr>
Better to use HTTP method DELETE for delete operations.
The reason because th:object tried to look in your request attribute for the attribute blg. But blg is a result of an iteration.

Related

Neither BindingResult nor plain target object for bean name 'user' available as request attribute error

I am new on spring. I am just trying to create my own CRUD OneToMany project. I have user and course table in my database. Course table has user_id foreign key references user(id).
When user successfully logged into the page, homePage.jsp comes and user courses are listed. When we click "Add Course" button in homePage.jsp, course-form.jsp file comes and we should add course.
The problem is, when I try to add course, I lost my user modelAttribute because in this time another attribute is on process with spring mvc.
When addedCourse form action performed these error occurs,
Cannot invoke "com.veg.entity.User.addCourse(com.veg.entity.Course)" because "user" is null
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is org.hibernate.HibernateException: Could not obtain transaction-synchronized Session for current thread
My Controller,
#PostMapping("/showFormForAdd")
public String showFormForAdd(#ModelAttribute("user") User theUser, Model theModel) {
Course theCourse = new Course();
theCourse.setUser(theUser);
theModel.addAttribute("course", theCourse);
theModel.addAttribute("user", theUser);
return "course-form";
}
#PostMapping("addedCourse")
public String addedCourse(#ModelAttribute("course") Course theCourse, Model theModel) {
User user = theCourse.getUser();
userService.save(user, theCourse);
theModel.addAttribute("user", user);
return "homePage";
}
homePage.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="showFormForAdd" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Add Course" class="add-course"/>
</form:form>
</span>
<table>
<tbody>
<tr>
<th>Course id</th>
<th>Course title</th>
</tr>
<c:forEach var="temp" items="${user.courses}">
<tr>
<td> ${temp.id} </td>
<td> ${temp.title} </td>
</tr>
</c:forEach>
</tbody>
</table>
course-form.jsp
<p>Welcome ${user.username}</p>
<span>
<form:form action="loggedUser" modelAttribute="user" method="POST">
<form:hidden path="username"/>
<form:hidden path="password"/>
<input type="submit" value="Back to Course List" class="add-course"/>
</form:form>
</span>
<!-- In the below I lost my user modelAttribute because I should use course attribute -->
<form:form action="addedCourse" modelAttribute="course" method="POST">
<table>
<tbody>
<tr>
<td> Title </td>
<td> <form:input path="title"/> </td>
</tr>
<tr>
<td colspan="2">
<input type="submit" value="Add Course" class="add-course"/>
</td>
</tr>
</tbody>
</table>
</form:form>
I have #Transactional in my service, #Repository in my DAO and there is no problem with sessionFactory.

How do i sent dynamic values from form (post method) back to controller

I am quite new to laravel,
Basically, I have this Form where I am showing values Dynamically, and those values i need to pass into controller again for Delete, but not understanding how to do it.
my blade is as bellow
<div class="col-md-12">
#if(isset($rtn_user_id))
#csrf
<table>
<tr>
<td>Customer Name</td> <td>Vechile Name</td> <td>Imei</td><td>Actions</td>
</tr>
<tr>
<td> {{$rtn_user_id}}</td> <td></td> <td> {{$rtn_device_name}}</td> <td>{{$rtn_imei}}</td> <td><button type="button">Delete</button></td>
</tr>
</table>
#endif
</div>
</form>
my operation.delete_imei is like this
so I want to pass the values of $rtn_imei to the controller
public function delete_imei(Request $request)
{
$post_imei = $request->imei;
dd($pos_imei)
}
web.php
Route::post('deleteimei', 'Operation#delete_imei')->name('operation.delete_imei');
Can you please help me with this
You need to issue an HTTP post to /deleteimei, which is really an HTML/JS question, depending on how you choose to do it.
Assuming you're not using a JS library which makes life easier, this is how you'll want to do it (change the selectors etc. to suit):
document.getElementsByTagName('button').click = function() {
xhttp.open('POST', '/deleteimei', true);
xhttp.send();
location.reload();
}
In Blade File
#csrf
#if(isset($rtn_user_id))
<tr>
<td>Customer Name</td> <td>Vechile Name</td> <td>Imei</td><td>Actions</td>
</tr>
<tr>
<td> {{$rtn_user_id}}</td> <td></td> <td> {{$rtn_device_name}}</td> <td>{{$rtn_imei}}</td> <td><button formaction="{{route('operation.delete_imei',$rtn_imei)}}" type="submit" class="btn btn-danger btn-sm"><i class="fa fa-trash-o" aria-hidden="true"></i></button></td>
</tr>
</table>
#endif
</div>
</form>
web.php
Route::delete('deleteimei/{id}', 'Operation#delete_imei')->name('operation.delete_imei');
-In Operation Controller
public function delete_imei($id) {
$post_imei = $id;
dd($pos_imei)
$data=DB::delete('delete from delete_imei where id=?',[$id]);
return redirect(route('index'));
}
i think you should edit your blade like this and this will send your form's data to your controller and you will be suitable for get your request's datas.
<form role="form" method="POST" action="{{ route('operation.delete_imei') }}">
#csrf
<div class="col-md-12">
#if(isset($rtn_user_id))
<table>
<tr>
<td>Customer Name</td> <td>Vechile Name</td> <td>Imei</td><td>Actions</td>
</tr>
<tr>
<td> {{$rtn_user_id}}</td> <td></td> <td> {{$rtn_device_name}}</td> <td>{{$rtn_imei}}</td> <td><button type="button">Delete</button></td>
</tr>
</table>
#endif
</div>
</form>
if you want to pass some data from blade to controller just put some hidden input in your form and set the value of that with your data you want to pass:
<input id="invisible_id" name="invisible" type="hidden" value="{{$data}}">

Getting the selected values from a checkbox list to the controller with Spring Boot

I'm using Spring Boot with Thymeleaf as viewer, and I want to delete all selected items from a table. Therefore, I need to pass to the controller a list with the values from the selected checkboxes.
This is my approach for the controller:
#PostMapping("/admin/rates/prices/delete")
public String delete(#ModelAttribute Rate price, ServletWebRequest request){
if(request.getParameterValues("idChecked") != null){
for(String idCheckedStr : request.getParameterValues("idChecked")){
int idrate = Integer.getInteger(idCheckedStr);
rateRepository.deleteRate(idrate);
}
}
return "redirect:/admin/rates/prices";
}
I get a Null Pointer Exception:
java.lang.NullPointerException: null
at com.rentalwebs.controllers.rates.PriceListController.delete(PriceListController.java:42)
I think this method should collet the values::
request.getParameterValues("idChecked")
This is the line at the form, which creates each checkbox with the Thymeleaf annotations:
<input type="checkbox" th:name="idChecked" th:value="${price.idrate}"/>
That's the view code for the form:
<form th:action='#{/admin/rates/prices/delete}'
method="POST"
th:object="${rate}">
<button type="submit" name='delete' value="delete"
class='btn btn-secondary btn-sm'
th:text="#{delete}"
data-toggle="tooltip" data-placement="right"
th:title="#{delete.selected}">
</button>
<p></p>
<table class='table table-sm responsive'>
<thead class='thead-default'>
<tr>
<th><input type="checkbox" id="checkAll"/></th>
<th th:text='#{from}'></th>
<th th:text='#{to}'></th>
<th th:text='#{price}'></th>
</tr>
</thead>
<tbody>
<tr th:each="price : ${prices}">
<td>
<input type="checkbox" th:name="idChecked" th:value="${price.idrate}"/>
</td>
<td th:text="${#temporals.format(price.datefrom, 'dd/MM/yyyy')}"></td>
<td th:text="${#temporals.format(price.dateto, 'dd/MM/yyyy')}"></td>
<td th:text="${price.price} + ' €'"></td>
</tr>
</tbody>
</table>
</form>
Thank you in advance for your help :-)
This is the code with the solution, taken from the comments:
#PostMapping("/admin/rates/prices")
public String delete(#RequestParam("idChecked") List<String> idrates){
if(idrates != null){
for(String idrateStr : idrates){
int idrate = Integer.parseInt(idrateStr);
rateRepository.deleteRate(idrate);
}
}
return "redirect:/admin/rates/prices";
}

Write handler methods for dynamically generated buttons and text boxes

I have this small data on JSP form. I use JSTL to iterate over data. In each row, I have two dynamically generated textboxes and a button. Question is: how do I write a generic handler method for this data, which handles dynamically generated textboxes and buttons. Here is my JSP
<c:forEach items="${menus}" var="menu" >
<tr>
<td align="left" >${menu.getMenuId()}</td>
<td align="right"><input type="text" name="menu_name" value="${menu.getMenuName()}"/></td>
<td align="right"><input type="text" name="menu_price" value="${menu.getMenuPrice()}"/></td>
<td align="right"><c:out value="${menu.getIsAvailable()}" /></td>
<td align="right"><input type="submit" value="Add Item ${menu.getMenuId()}"></td>
</tr>
</c:forEach>
<h4>Add Product</h4>
Name: <input type="text" name="chosen_menu_name" />
Price: <input type="text" name="chosen_menu_price" />
<input type="submit" value="Add to cart">
And here is my controller (though I dont know what to put it there - at the moment I am using two seperate textbox and a button for taking the input)
#RequestMapping(method = RequestMethod.POST)
public ModelAndView AddMenu(#RequestParam("chosen_menu_name") String mymenu, #RequestParam("chosen_menu_price") String menu_price, #ModelAttribute("cart") ArrayList<Menu> mycart, Model model)
{
Menu menu = new Menu();
menu.setMenuId(0);
menu.setMenuName(mymenu);
menu.setMenuPrice(Double.parseDouble(menu_price));
model.addAttribute("menus", GetMenus());
mycart.add(menu);
return new ModelAndView("edit_menu");
//return "show_menu";
}
As one can see from the JSP, I am using two seperate textboxes and a button for taking input and passing it to the controller. How do I write a generic handler method for this data, which handles dynamically generated textboxes and buttons?
I'm assuming that you don't want those other two field and button. You want to add items directly from table.
You have to make each and every row as one form like below :
<c:forEach items="${menus}" var="menu" >
<tr>
<form method="POST" action="controllerName">
<td align="left">
${menu.getMenuId()}
<input type="hidden" name="menu_id" value="${menu.getMenuId()}"/>
</td>
<td align="right">
<input type="text" name="menu_name" value="${menu.getMenuName()}"/>
</td>
<td align="right">
<input type="text" name="menu_price" value="${menu.getMenuPrice()}"/>
</td>
<td align="right">
<c:out value="${menu.getIsAvailable()}"/>
</td>
<td align="right">
<input type="submit" value="Add Item">
</td>
</form>
</tr>
</c:forEach>
And controller like below:
#RequestMapping(method = RequestMethod.POST)
public ModelAndView AddMenu(#RequestParam("menu_id") String menuId, #RequestParam("menu_name") String mymenu, #RequestParam("menu_price") String menu_price, #ModelAttribute("cart") ArrayList<Menu> mycart, Model model)
{
Menu menu = new Menu();
menu.setMenuId(menuId);
menu.setMenuName(mymenu);
menu.setMenuPrice(Double.parseDouble(menu_price));
model.addAttribute("menus", GetMenus());
mycart.add(menu);
return new ModelAndView("edit_menu");
//return "show_menu";
}

Values for th:field attributes in checkbox

I have table with datas from database (insert dynamically). In one column I insert checkbox. Now I want to select one of them and send to next form (I select one product and send properties to another form. In this form should be displayed properties only the select product). But I don't know what kind of value insert in th:field="*{}". I tried many solutions but doesn't work. My html form with all products table:
<form action="/oferta/zamow" th:action="#{/oferta/zamow}"
th:object="${oferta}" method="post">
<table border="1" id="display-data">
<tr>
<td>#</td>
<td>title</td>
<td>author</td>
<td>rok</td>
<td>cena</td>
<td></td>
</tr>
<tr th:each="produkt, pozycja : ${oferta}">
<td th:text="${pozycja.count}"></td>
<td><span th:text="${produkt.tytul}"></span></td>
<td><span th:text="${produkt.autor}"></span></td>
<td><span th:text="${produkt.rok}"></span></td>
<td><span th:text="${produkt.cena}"></span></td>
<td>
<input type="submit" value="zamow"/>
<!-- <a th:href="#{/zamowienie}">zamow</a> -->
</td>
<td>
<label>zamow</label>
<input type="checkbox" th:field="*{produkt}" th:value="${produkt}"/>
</td>
</tr>
</table>
</form>
Form to display select product:
<form action="/zamowienie/zam" th:action="#{/zamowienie/zam}"
th:object="${zamowienie}" method="post">
<table border="1" id="display-data">
<tr align="center">
<td colspan="2">twoje zamowienie</td>
</tr>
<tr>
<td>tytul</td>
<td><span th:text="${produkt.tytul}"></span></td>
</tr>
<tr>
<td>autor</td>
<td><span th:text="${produkt.autor}"></span></td>
</tr>
<tr>
<td>rok</td>
<td><span th:text="${produkt.rok}"></span></td>
</tr>
<tr>
<td>cena</td>
<td><span th:text="${produkt.cena}"></span></td>
</tr>
<tr>
<td>data zlozenia zamowienia</td>
<td><span th:text="${datazam}"></span></td>
</tr>
</table>
</form>
Thanks for help.
I am not sure if this is the answer you seek, but you can find an example at http://www.thymeleaf.org/doc/html/Thymeleaf-Spring3.html#checkbox-fields.
Here is a simple example to illustrate how to use a checkbox in Thymeleaf with Spring MVC.
Controller:
#RequestMapping(value = "/showForm", method=RequestMethod.GET)
public String showForm(Model model) {
List<String> allItems = new ArrayList<String>();
allItems.add("value1");
allItems.add("value2");
allItems.add("value3");
model.addAttribute("allItems", allItems);
Foo foo = new Foo();
List<String> checkedItems = new ArrayList<String>();
// value1 will be checked by default.
checkedItems.add("value1");
foo.setCheckedItems(checkedItems);
model.addAttribute("foo", foo);
...
}
#RequestMapping(value = "/processForm", method=RequestMethod.POST)
public String processForm(#ModelAttribute(value="foo") Foo foo) {
// Get value of checked item.
List<String> checkedItems = foo.getCheckedItems();
...
}
html:
<form action="#" th:action="#{/processForm}" th:object="${foo}" method="post">
<div th:each="item : ${allItems}">
<input type="checkbox" th:field="*{checkedItems}" th:value="${item}" />
<label th:text="${item}">example</label>
</div>
<input type="submit" />
</form>
Foo.java:
public class Foo {
private List<String> checkedItems;
public List<String> getCheckedItems() {
return checkedItems;
}
public void setCheckedItems(List<String> checkedItems) {
this.checkedItems = checkedItems;
}
}
Hope this helps.
Take a look at the thymeleaf spring integration docs.
All th:field are mapped against the command object. Thats why you need the *{} expression.
One thing the template engine is not able to do (yet) is mapping fields inside a loop directly. So you cannot use the *{} approach to reference the produkt variable from the loop.
What you have to do is use the index of the th:each expression and build a property accessor with a pre-evaluated expression for the index.
<input type="checkbox" th:field="*{produkts[__${index}__].checked" />
You do not need the th:value, th:field is taking care of it. (Except if you want to superseed it)

Resources