pass object from HTML template back to the controller - spring

I have the following HTML block. I want to pass the object "jobDTO" back to the contoller "/deleteJob" method. Whatever I do I am getting null object.
<th:block th:if="${jobDTO != null}" th:each="jobDTO: ${allJobDTOs.get(jobGroup)}">
<div id="accordion2" style="margin-bottom: 3px;">
<div class="card" id="headingOne">
<div class="card-header" style="padding: 0">
<h5 class="mb-0">
<button class="btn btn-link" data-toggle="collapse" th:attr="data-target='#accordion2_'+${jobDTO.identity.name}"
aria-expanded="true" aria-controls="collapseChild" >
<p class="font-weight-bold custom-p identity-black" > Job Identity </p>
<p class="custom-p" style="padding-left: 52px;" th:text="${jobDTO.identity.group} +' , ' + ${jobDTO.identity.name}"></p>
</button>
</h5>
</div>
<div th:id="'accordion2_'+${jobDTO.identity.name}" class="collapse" aria-labelledby="headingOne" data-parent="#accordion2">
<div class="card-body">
<dl class="row">
<dt class="col-lg-3">Trigger List</dt>
<dd class="col-sm-9">
<th:block th:each="trigger: ${jobDTO.triggers}">
<p><b>nextFireTime</b> <span th:text="${trigger.nextFireTime}"> </span></p>
<hr>
</th:block>
</dd>
</dl>
<!-- important part.. how to pass the jobDTO object back to the controller -->
<form id="form2" action="#" th:action="#{/deleteJob}" th:object="${jobDTO}" th:method="post">
<input type="text" th:value="*{identity.name}" th:field="*{identity.name}" hidden/>
<button type="submit" value="Submit" class="btn btn-danger btn-sm" >Delete Job</button>
</form>
</div>
</div>
</div>
</div>
</th:block>
my controller relevant parts are:
#GetMapping(value = "/deleteJob")
public String deleteJobPage(Model model) {
model.addAttribute("jobDTO", new ScheduleJobDTO());
//Returns the Home page with the prepared model attributes
return "Home";
}
// =================
#PostMapping("/deleteJob")
public String deleteJob(#ModelAttribute final ScheduleJobDTO jobDTOReturn, BindingResult bindingResult, Model model) {
// I want to receive the jobDTO object here
schedulerService.deleteJobFromGroup(jobDTOReturn.getIdentity().getGroup(),
jobDTOReturn.getIdentity().getName());
return "redirect:/";
}
what I am missing here?

I think there is an error in your input tag, try this :
<input type="text" th:value="${jobDTO.identity.name}" th:field="*{identity.name}" hidden/>

Related

Problem with Passing data from Laravel controller to Boostrap Modal

Hello everyone one i have a problem . I want to pass data from my Controller to my modal . I have a list of categories i want to display it in a dropdown list i've tried using href attribute and ajax but none of these worked is there any solution ?
here is a piece of code :
List of all Categories blade.php :
#extends('layouts.Template')
#section('content')
<div class="content-wrapper">
<div class="container-fluid">
<div class="row">
<div class="col-md-12">
<center> <h2 class="page-title">Gérer les Sous Catégories</h2> </center>
<div class="panel panel-default">
<div class="panel-heading"> <strong>Liste Sous Catégories</strong></div>
<div class="panel-body">
<table id="zctb" class="table table-bordered">
<tr>
<th>Id</th>
<th>Nom</th>
<th>Nom de Catégories</th>
<th>image</th>
<th>created_at</th>
<th>updated_at</th>
<a class="fas fa-plus-circle" style="font-size:60px;color:#e2ccae;margin-left:90%;"href="{{url ('/Sous_Catégories/ajouter')}}"></a>
</tr>
#foreach($Souscategories as $Scategorie)
<tr>
<td>{{$Scategorie->id}}</td>
<td>{{$Scategorie->nom}}</td>
<td>{{$Scategorie ->nomCat}}</td>
<td>{{$Scategorie->image}}</td>
<td>{{$Scategorie -> created_at}}</td>
<td>{{$Scategorie -> updated_at}}</td>
<td ><a class="fas fa-edit" href="{{ route('Sous_Catégories.getAllCategories')}}" data-nom="{{$Scategorie->nom}}" data-nomCat="{{$Scategorie->nomCat}}" data-image="{{$Scategorie->image}}" data-cat_id1 ="{{$Scategorie->id }}" data-toggle="modal" data-target="#edit1">Edit</a></td>
<td><a class="fas fa-trash" href="{{url ('/Sous_Catégories/supp',[$Scategorie->id])}}" > </td>
</tr>
#endforeach
</table>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
<div class="modal fade" id="edit1" tabindex="-1" role="dialog" aria-labelledby="myModalLabel">
<div class="modal-dialog" role="document">
<div class="modal-content">
<div class="modal-header">
<button type="button" class="close" data-dismiss="modal" aria-label="Close"><span aria-hidden="true">×</span></button>
<h4 class="modal-title" id="myModalLabel">Modifier Sous Catégories</h4>
</div>
<form action="{{ route('Sous_Catégories.update','test')}}" method="POST">
{{method_field('patch')}}
{{csrf_field()}}
<div class="modal-body">
<input type="hidden" name="cat_id1" id="cat_id1" value="">
#include('formSousCat')
</div>
<div class="modal-footer">
<button id="fermer" type="button" class="btn btn-default" data-dismiss="modal">Fermer</button>
<button id="save" type="submit" class="btn btn-primary">Enregistrer</button>
</div>
</form>
</div>
</div>
</div>
#endsection
controller Methode :
public function getAllCategories()
{
$Cat = categories::all();
return view('formSousCat', compact('Cat'));
}
My routers :
Route::get('/Sous_Catégories', 'SousCatController#index' );
Route::post('/Sous_Catégories/ajouter', 'SousCatController#create');
Route::get('/Sous_Catégories/supp/{id}', 'SousCatController#destroy');
Route::get('/Sous_Catégories/getAllCategories', 'SousCatController#getAllCategories');
Route::resource('Sous_Catégories', 'SousCatController');
My Modal.blade
<label>Nom</label>
<input id="nom" name="nom" class="form-control"type="text"/>
</div>
<br/>
<div>
<label for="le_nom">Choix de categorie</label><br />
<label for="le_nom">Choix de categorie</label><br />
<select name="le_nom" id="le_nom" class="form-control">
#foreach($Cat as $categorie) <!-- $Cat is undefined -->
<option class="form-control">{{$categorie->nomCat}}</option>
#endforeach
</select>
<div class="input-group">
<div class="custom-file">
<div class="form-group">
<input type="file" name="image" class="form-control-file">
</div>
</div>
You can use a click event on a button tag, to opent the modal and initiate an ajax request which fetches the data from the controller and inserts into the categories.
<button id="openModal">Open Modal</button>
In your controller:
public function getAllCategories()
{
$Cat = categories::all();
return response()->json($cat);
}
In your script
let btn = document.querySelector('#openModal')
let slct = document.querySelector('#le_nom')
btn.addEventListener('click', function(){
$.ajax({
url: '{{url("/Sous_Catégories/getAllCategories")}}',
method: 'GET',
success: function(response){
response.Foreach((op) = > {
slct.innerHTML += `<option value="${op.id}">${op.nomCat}</option>`
})
}
})
})

How can i resolve my update record query in same page?

In My list view I have all the details of department. But when I click on details It will display me a Pop-up. In Pop up box it has to fetch and give me all the details of particular field but instead of that it always give me details of last inserted record
Here is my code of blade file
#extends('layouts.master')
#section('content')
<section>
<div class="page-wrapper">
<div class="container-fluid">
<div class="row page-titles">
<div class="col-md-5 align-self-center">
<h4 class="text-themecolor">{{__('Department')}}</h4>
</div>
</div>
<div class="card">
<div class="card-body">
<div>
+ Add Department
</div>
<div id="myModal" class="modal fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabel" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabel">Add Department </h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form id="myform" class="form-horizontal" method="POST" action="{{route('store_department')}}">
#csrf
<div class="form-group">
#if(Session::has('key'))
<?php $createdBy = Session::get('key')['username']; ?>
#endif
<div class="col-md-12">
<input type="hidden" name="createdBy" value="<?php echo $createdBy ?>">
<input type="text" class="form-control" name="nameOfDepartment" placeholder="Add New Department">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info waves-effect" data-dismiss="modal">Save</button>
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
<div class="table-responsive m-t-40">
<table class="table table-bordered table-striped ">
<thead>
<tr>
<th>Department Name</th>
<th>Created By</th>
<th>Created On</th>
<th>Action</th>
</tr>
</thead>
<tbody>
#if($listOfDepartment != null)
#foreach($listOfDepartment as $departmentList)
<tr>
<td>{{$departmentList->nameOfDepartment}}</td>
<td>{{$departmentList->createdBy}}</td>
<td>{{$departmentList->created_at}}</td>
<td>
<i class="fa fa-edit fa-lg" style="color:#0066ff" aria-hidden="true"></i>
<i class="fa fa-trash fa-lg" style="color:red" aria-hidden="true"></i>
</td>
</tr>
#endforeach
#endif
</tbody>
</table>
</div>
</div>
<div id="myEditModal" class="modal fade in" tabindex="-1" role="dialog" aria-labelledby="myModalLabelEdit" aria-hidden="true">
<div class="modal-dialog">
<div class="modal-content">
<div class="modal-header">
<h4 class="modal-title" id="myModalLabelEdit">Edit Department</h4>
<button type="button" class="close" data-dismiss="modal" aria-hidden="true">×</button>
</div>
<div class="modal-body">
<form class="form-horizontal" method="POST" action="{{ route('update_department', $departmentList->id) }}">
#csrf
#method('PUT')
<div class="form-group">
<div class="col-md-12">
<input type="text" name="nameOfDepartment" class="form-control" placeholder="Edit Department" value="{{$departmentList->nameOfDepartment}}">
</div>
</div>
</form>
</div>
<div class="modal-footer">
<button type="submit" class="btn btn-info waves-effect" data-dismiss="modal">Update</button>
<button type="button" class="btn btn-default waves-effect" data-dismiss="modal">Cancel</button>
</div>
</div>
</div>
</div>
</div>
</div>
</div>
</section>
#endsection
here is my code of department controller
<?php
namespace App\Http\Controllers;
use App\Department;
use Illuminate\Http\Request;
class DepartmentController extends Controller
{
public function createDepartment()
{
return view('pages.department');
}
public function storeDepartment(Request $request)
{
$department = new Department();
$department->createdBy = $request->get('createdBy');
$department->nameOfDepartment = $request->get('nameOfDepartment');
$department->save();
return redirect('list-department')->with('Success', 'Department Added Successfully!');
}
public function listDepartment()
{
$listOfDepartment = Department::all();
return view('pages.department', compact('listOfDepartment'));
}
public function editDepartment($id)
{
$departments = Department::find($id);
return view('pages.department', compact('departments', 'id'));
}
public function updateDepartment(Request $request, $id)
{
$department = Department::find($id);
$department->createdby = $request->get('createdBy');
$department->nameOfDepartment = $request->get('nameOfDepartment');
$department->save();
return redirect('list-department')->with('Success', 'Department Updated Successfully!');
}
public function deleteDepartment($id)
{
$department = Department::find($id);
$department->delete();
return redirect('list-department')->with('Success', 'Department Deleted SuccessFully!');
}
}
And Here Are My Routes
Route::get('add-department', 'DepartmentController#createDepartment')->name('create_department');
Route::post('store-department', 'DepartmentController#storeDepartment')->name('store_department');
Route::get('list-department', 'DepartmentController#listDepartment')->name('list_department');
Route::get('edit-department/{id}', 'DepartmentController#editDepartment')->name('edit_department');
Route::put('update-department/{id}', 'DepartmentController#updateDepartment')->name('update_department');
Route::get('delete-department/{id}', 'DepartmentController#deleteDepartment')->name('delete_department');
Your modal is always created with the last $departmentList
You are using this to create some kind of list
#foreach($listOfDepartment as $departmentList)
<tr>
<td>{{$departmentList->nameOfDepartment}}</td>
<td>{{$departmentList->createdBy}}</td>
<td>{{$departmentList->created_at}}</td>
<td>
<a href="{{route('edit_department', $departmentList->id)}}" data-toggle="modal" data-target="#myEditModal">
<i class="fa fa-edit fa-lg" style="color:#0066ff" aria-hidden="true"></i>
</a>
<a href="{{route('delete_department', $departmentList->id)}}">
<i class="fa fa-trash fa-lg" style="color:red" aria-hidden="true"></i>
</a>
</td>
</tr>
#endforeach
You end the loop here so $departmentList is the last one from the loop
Later you add some html again that uses $departmentList
<form class="form-horizontal" method="POST" action="{{ route('update_department', $departmentList->id) }}">
This variable still contains the last department from your loop before.
You can probably utilize some javascript that opens the modal and put the correct post url in place.

400 the request sent by the client was syntactically incorrect

I have gone through so many examples of this nature and proposed solutions from this site, but none of the solutions provided thereon apply to my problem. I believe that this error message, 400, shows up when the information sent to the controller is mulformed. I spent the last two days cross referrencing to another project I worked on in the past, which works, but I cannot pick up the problem.
#RequestMapping(value = {"/", "/home"}, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("user", getPrincipal());
Catalog catalog = catalogService.getCatalogByCategory(Catalog.CatalogCategory.ALL);
model.addAttribute("catalog", catalog);
return "welcome";
}
This sends the data to a JSTL Spring form on my JSP as follows:
<form:form method="POST" modelAttribute="catalog">
<form:hidden path="id"/>
<form:hidden path="name"/>
<form:hidden path="category"/>
<form:hidden path="orderItems"/>
<div id="products" class="row list-group">
<c:forEach var="orderItem" items="${catalog.orderItems}">
<div class="item col-xs-4 col-lg-4">
<div class="thumbnail">
<img class="group list-group-image" src="http://placehold.it/400x250/000/fff" alt=""/>
<div class="caption">
<h4 class="group inner list-group-item-heading">
${orderItem.name}</h4>
<p class="group inner list-group-item-text">
${orderItem.description}
</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<p class="lead">
R ${orderItem.price}</p>
</div>
<div class="col-xs-12 col-md-6">
<label for="${orderItem.id}" class="btn btn-primary">Add to Cart <input
type="checkbox" id="${orderItem.id}" name="orderItem.addedToCart"
class="badgebox"><span class="badge">&check;</span></label>
</div>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-12 pull-right">
</div>
<div class="col-sm-2 pull-right">
<input type="submit"
class="btn btn-default btn-block btn-primary"
value="Next" name="action" formmethod="POST"
formaction="confirmList"/>
</div>
</div>
</div>
</form:form>`
At this point I submit the form to the following listener in my controller:
#RequestMapping(value = "/confirmList", method = RequestMethod.POST)
public String confirmList(#ModelAttribute Catalog catalog, #ModelAttribute String numberOfItemsAdded) {
List<OrderItem> selectedItems = new ArrayList<OrderItem>();
for (OrderItem orderItem : catalog.getOrderItems()) {
if (orderItem.isAddedToCart()) {
selectedItems.add(orderItem);
}
}
//model.addAttribute("numberOfItemsAdded", selectedItems.size());
return "welcome";
}
That's it, execution flow does NOT even reach back my controller. Exhausting bug because I really do not understand what I am doing wrong here. Thank you in advance
EDIT:
Catalog.java
#Entity
#Table(name="Catalogs")
public class Catalog{
private long id; //generated value using hibernate ...
private String name; //column annotated by #Column
private String category;// column also annotated by #Column
private List<OrderItem> orderItems;// one to many mapping
//getters and setters here
}
I tested your code and I got HTTP 400 too. The thing is that what browser sends does not match whith what the controller method confirmList expects:
This is the form data I saw in Chrome's network tab:
id:1
name:the catalog
category:category
orderItems:[com.eej.ssba2.model.test.catalog.OrderItem#82ea8a, com.eej.ssba2.model.test.catalog.OrderItem#f441ae, com.eej.ssba2.model.test.catalog.OrderItem#40a13, com.eej.ssba2.model.test.catalog.OrderItem#1316c95, com.eej.ssba2.model.test.catalog.OrderItem#1cfc05a, com.eej.ssba2.model.test.catalog.OrderItem#5d725c, com.eej.ssba2.model.test.catalog.OrderItem#ff32b9, com.eej.ssba2.model.test.catalog.OrderItem#5b49a4, com.eej.ssba2.model.test.catalog.OrderItem#13faf31, com.eej.ssba2.model.test.catalog.OrderItem#6d64d]
orderItem.addedToCart:on
orderItem.addedToCart:on
orderItem.addedToCart:on
orderItem.addedToCart:on
action:Next
But controller cannot understand this, as OrderItems shows a toString() of each OrderItem instance and the addedToCart is not binded to any orderItem of the orderItems list.
You must modify your jsp this way:
<form:form method="POST" modelAttribute="catalog">
<form:hidden path="id"/>
<form:hidden path="name"/>
<form:hidden path="category"/>
<!-- form:hidden path="orderItems"/-->
<div id="products" class="row list-group">
<c:forEach var="orderItem" items="${catalog.orderItems}" varStatus="status">
<div class="item col-xs-4 col-lg-4">
<div class="thumbnail">
<img class="group list-group-image" src="http://placehold.it/400x250/000/fff" alt=""/>
<div class="caption">
<h4 class="group inner list-group-item-heading">
${orderItem.name}</h4>
<form:hidden path="orderItems[${status.index}].name" />
<p class="group inner list-group-item-text">
${orderItem.description}
<form:hidden path="orderItems[${status.index}].description" />
</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<p class="lead">
R ${orderItem.price}</p>
<form:hidden path="orderItems[${status.index}].price" />
</div>
<div class="col-xs-12 col-md-6">
<label for="${orderItem.id}" class="btn btn-primary">Add to Cart <input
type="checkbox" id="${orderItem.id}" name="catalog.orderItems[${status.index}].addedToCart"
class="badgebox"><span class="badge">&check;</span></label>
</div>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-12 pull-right">
</div>
<div class="col-sm-2 pull-right">
<input type="submit"
class="btn btn-default btn-block btn-primary"
value="Next" name="action" formmethod="POST"
formaction="confirmList"/>
</div>
</div>
</div>
</form:form>
If you do so, you could see the message changes in Chrome's network tab (or the browser you are using). This is the form data right now:
id:1
name:the catalog
category:category
orderItems[0].name:OrderItemName#0
orderItems[0].description:OrderItemDesc#0
orderItems[0].price:0.0
orderItems[1].name:OrderItemName#1
orderItems[1].description:OrderItemDesc#1
orderItems[1].price:0.43645913001303904
orderItems[2].name:OrderItemName#2
orderItems[2].description:OrderItemDesc#2
orderItems[2].price:1.7151992716801088
orderItems[3].name:OrderItemName#3
orderItems[3].description:OrderItemDesc#3
orderItems[3].price:1.303683806806788
orderItems[4].name:OrderItemName#4
orderItems[4].description:OrderItemDesc#4
orderItems[4].price:2.507039003743686
orderItems[5].name:OrderItemName#5
orderItems[5].description:OrderItemDesc#5
orderItems[5].price:3.173744751378154
orderItems[6].name:OrderItemName#6
orderItems[6].description:OrderItemDesc#6
orderItems[6].price:3.183771167856446
catalog.orderItems[6].addedToCart:on
orderItems[7].name:OrderItemName#7
orderItems[7].description:OrderItemDesc#7
orderItems[7].price:6.73370053587355
catalog.orderItems[7].addedToCart:on
orderItems[8].name:OrderItemName#8
orderItems[8].description:OrderItemDesc#8
orderItems[8].price:2.0266022634803216
orderItems[9].name:OrderItemName#9
orderItems[9].description:OrderItemDesc#9
orderItems[9].price:5.251986962977732
catalog.orderItems[9].addedToCart:on
action:Next
And you would see now it returns a HTTP 200 as the request in fact reaches your controller. Delete the #ModelAttribute in your controller method too, as you have been suggested to:
#RequestMapping(value = "/confirmList", method = RequestMethod.POST)
public String confirmList(Catalog catalog, String numberOfItemsAdded) {
List<OrderItem> selectedItems = new ArrayList<OrderItem>();
for (OrderItem orderItem : catalog.getOrderItems()) {
if (orderItem.isAddedToCart()) {
selectedItems.add(orderItem);
}
}
//model.addAttribute("numberOfItemsAdded", selectedItems.size());
return "catalog";
}
try this extra handle in your Controller and Check your Console,
#ExceptionHandler(MissingServletRequestParameterException.class)
public void handleMissingRequestParams(MissingServletRequestParameterException ex) {
System.out.println();
System.out.println("------------------------MissingServletRequestParameterException------------------------");
System.out.println(" Parameter name:- "+ex.getParameterName());
System.out.println(" Parameter Type:- "+ex.getParameterType());
System.out.println(" Cause:- "+ex.getCause());
System.out.println(" LocalizedMessage:- "+ex.getLocalizedMessage());
System.out.println(" Message:- "+ex.getMessage());
System.out.println(" RootCause:- "+ex.getRootCause());
System.out.println("-------------------------------********************-----------------------------");
}
Edit
#kholofelo Maloma I can't see the variable numberOfItemsAdded in your jsp
AND i never used #ModelAttribute String numberOfItemsAdded to String parameter plz check this in documentation, I think it is used along with Bean, plz confirm
rather use #RequestParam
Read Documentation Here
It clears me
Sorry for above handle,
Note however that reference data and all other model content is not available to web views when request processing results in an Exception since the exception could be raised at any time making the content of the model unreliable. For this reason #ExceptionHandler methods do not provide access to a Model argument.

Submitting a POST object

I spent the whole weekend searching the net on my problem. It seems like I am missing something really silly, but I failed to pick it up.
Here's the problem. I sent an object to a JSP and on the JSP I could see its content. I them I submitted the form. Back in the controller, it shows the object is overwritten/recreated. I can't seem to understand. I checked the logs on my Tomcat but I do not see any error...
On my Controller:
#RequestMapping(value = {"/", "/home"}, method = RequestMethod.GET)
public String homePage(ModelMap model) {
model.addAttribute("user", getPrincipal());
Catalog catalog = catalogService.getCatalogByCategory(Catalog.CatalogCategory.ALL);
model.addAttribute("catalog", catalog);
model.addAttribute("numberOfItemsAdded", "500");
return "welcome";
}`
and in my JSP I have the following:
<form:form method="POST" modelAttribute="catalog">
<form:hidden path="id"/>
<div id="products" class="row list-group">
<c:forEach var="orderItem" items="${catalog.orderItems}">
<div class="item col-xs-4 col-lg-4">
<div class="thumbnail">
<img class="group list-group-image" src="http://placehold.it/400x250/000/fff" alt=""/>
<div class="caption">
<h4 class="group inner list-group-item-heading">
${orderItem.name}</h4>
<p class="group inner list-group-item-text">
${orderItem.description}
</p>
<div class="row">
<div class="col-xs-12 col-md-6">
<p class="lead">
R ${orderItem.price}</p>
</div>
<div class="col-xs-12 col-md-6">
<label for="${orderItem.id}" class="btn btn-primary">Add to Cart <input
type="checkbox" id="${orderItem.id}" name="orderItem.addedToCart"
class="badgebox"><span class="badge">&check;</span></label>
</div>
</div>
</div>
</div>
</div>
</c:forEach>
</div>
<div class="row">
<div class="form-group">
<div class="col-sm-12 pull-right">
</div>
<div class="col-sm-2 pull-right">
<input type="submit"
class="btn btn-default btn-block btn-primary"
value="Next" name="action" formmethod="POST"
formaction="confirmList"/>
</div>
</div>
</div>
</form:form>`
After pressing "Next", which submits the form data to a controller:
#RequestMapping(value = "/confirmList", method = RequestMethod.POST)
public String confirmList(#ModelAttribute Catalog catalog, #ModelAttribute String numberOfItemsAdded) {
System.out.println("\n\n------>catalog = " + catalog);
System.out.println("\n\n------>numberOfItemsAdded = " + numberOfItemsAdded);
List<OrderItem> selectedItems = new ArrayList<OrderItem>();
for (OrderItem orderItem : catalog.getOrderItems()) {
if (orderItem.isAddedToCart()) {
selectedItems.add(orderItem);
}
}
//model.addAttribute("numberOfItemsAdded", selectedItems.size());
return "welcome";
}
`
The System.out.println(...) output the following:
------>catalog = Catalog{id=1, name='null', category='null', orderItems=null}
------>numberOfItemsAdded =
Those are empty outputs.... :'(
I have no idea what I am doing wrong here.....
This was answered in a comment line by George. All I had to do is hide/bind those null fields.
It is very concerning that we use the term 'hidden' to also mean 'ignore' or 'leave as is'. But anyway, the solution above did exactly what I was looking for.
Thanks to the Community

how to turn this spring boot thyme-leaf code into Ajax

I Have a comment and post system and I want To turn it into ajax without using thymeleaf fragmentation. How to do it i cannot figure out I do not want to refresh the page each time i make a post or comment .
Controller :
#Controller
public class DashboardController {
private Post post;
private User user;
#Autowired
private PostRepository postRepository;
#Autowired
private UserRepository userRepository;
#Autowired
CommentRepository commentRepository;
#RequestMapping(value = "/dashboard", method = RequestMethod.GET)
public String returnPosts(Model model) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName(); //holding login user details
model.addAttribute("firstName", userRepository.findByEmail(currentPrincipalName).getFirstName());
model.addAttribute("newPost", new Post());
model.addAttribute("newComment", new Comment());
model.addAttribute("posts", postRepository.findAllByOrderByDateDesc());
model.addAttribute("comments", commentRepository.findAll());
return "main";
}
#RequestMapping(value = "/dashboard/posts", method = RequestMethod.POST)
public String addPost(Model model, #ModelAttribute Post post, #ModelAttribute User user) {
model.addAttribute("newPost", post);
creatPost(post);
System.out.println(post.getId());
return "redirect:/dashboard";
}
#RequestMapping(value = "/dashboard/comments", method = RequestMethod.POST)
public String addComment( Model model, #ModelAttribute Comment comment,
#ModelAttribute User user) {
model.addAttribute("newComment", comment);
// model.addAttribute("posts", post);
creatComment(comment.getPostId(), comment);
System.out.println(comment.toString());
//System.out.println(post.getId());
// System.out.println(comment.getPostId());
return "redirect:/dashboard";
}
private Comment creatComment(String id, Comment comment) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName();
comment.setDate(new Date());
comment.setAuthor(userRepository.findByEmail(currentPrincipalName).getFirstName()
+ " " + userRepository.findByEmail(currentPrincipalName).getLastName());
comment.setPostId(id);
return commentRepository.save(comment);
}
private Post creatPost(Post post) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
String currentPrincipalName = authentication.getName(); //holding login user details
post.setAuthor(userRepository.findByEmail(currentPrincipalName).getFirstName()
+ " " + userRepository.findByEmail(currentPrincipalName).getLastName());
post.setDate(new Date());
return postRepository.save(post);
}
}
Thymeleaf forms :
<div id="content" class="yellow col-xs-12">
<form class="col-xs-12" role="form" action="/dashboard/posts"
th:action="#{/dashboard/posts}" th:object="${newPost}" method="post">
<div class="form-group col-xs-12">
<textarea class="form col-xs-6" rows="2" id="full" placeholder="share anything....."
th:field="*{content}" style="font-size: 20px;" required="required"></textarea>
<div class="menu1 col-xs-12">
<hr/>
<ul class="text-center col-xs-12">
<a href="#">
<li>
<button type="submit" class="sendpost btn btn-success">Send</button>
</li>
<li class="xs-12 "><i class="fa fa-flash fa-lg"></i>Tasks</li>
<li class="xs-12"><i class="fa fa-paperclip fa-lg"></i>files</li>
<li class="xs-12"><i class="fa fa-calendar fa-lg"></i> calendar</li>
<li class="xs-12"><i class="fa fa-search fa-lg"></i>stying</li>
</a>
</ul>
</div>
</div>
</form>
<div>
<div th:each="post : ${posts}" style="border:2px solid #CCCCCC ; margin-bottom: 50px" id="post-div"
class="post-group col-xs-12">
<div class="imag col-xs-2">
<!--<input type="hidden" th:field="*{post.id}" disabled="disabled"/>-->
<img style="width: 50px;" src="images/1.png" class="img-circle img-responsive" alt=""/>
</div>
<div class=" col-xs-10">
<h4 style="line-height: .4;"><p class="name" th:text="*{post.author}">
</p>
<small style="color: #337ab7" th:text="*{post.date}"></small>
</h4>
<br/>
<p style="font-size: 20px" id="post-p" class="desc" th:text="*{post.content}"></p><br/>
<div class="footer ignore-zoom">
<a class="comment" onclick="showDiv1()"><i class="aa fa fa-comment"></i>
<span class="lin">0</span></a>
<a onclick="showDiv2()" href="#">
<i id="like" class="aa fa fa-heart active"></i>
<span style="display:none;" id="like-1" class="lin">1</span></a>
<a class="aa dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false"><i
class="fa fa-pencil"></i> </a>
</div>
<div th:each="comment : ${comments}" id="my-comment">
<div th:if="${post.id == comment.postId}">
<hr/>
<br/>
<img class="img-circle img-responsive" src="images/1.png"
style="margin-right:5%; width: 50px; display: inline-flex; color:#080602;"/>
<div style="line-height:.8">
<label th:text="*{comment.author}"> </label><br/>
<small th:text="*{comment.date}" style=" color: #337ab7 ; margin-left:16%;">time of
comment
</small>
</div>
<br/>
<p style="font-size: 16px;" id="-comment" th:text="*{comment.comment}"></p>
<div class="footer footer1 ignore-zoom">
<a onclick="showDiv4()" href="#">
<i id="like1" class="aa fa fa-heart active"></i>
<span style="display:none;" id="like-2" class="lin">1</span></a>
<a class="aa dropdown-toggle" data-toggle="dropdown" href="#" aria-expanded="false"><i
class="fa fa-pencil"></i> </a>
</div>
</div>
</div>
<form role="form" action="/dashboard/comments"
th:action="#{/dashboard/comments}" th:object="${newComment}" method="post">
<input type="hidden" name="postId" th:value="${post.id}"/>
<div id="comment-div" class="form-group col-xs-12">
<textarea th:field="*{comment}" class="form col-xs-6" rows="2" id="full2"
placeholder="Your Comment....." required="required"></textarea>
<div class="menu1 col-xs-12">
<hr/>
<ul class="text-center col-xs-12">
<a href="#">
<li onclick="showDiv()">
<button type="submit" class="btn btn-info">Send</button>
</li>
<li class="xs-12 "><i class="fa fa-flash fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-paperclip fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-calendar fa-lg"></i></li>
<li class="xs-12"><i class="fa fa-search fa-lg"></i></li>
</a>
</ul>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
You can have a look at the tutorial http://www.thymeleaf.org/doc/tutorials/2.1/thymeleafspring.html#ajax-fragments
And the content is as below:
Ajax fragments
WebFlow allows the specification of fragments to be rendered via AJAX with tags, like this:
<view-state id="detail" view="bookingDetail">
<transition on="updateData">
<render fragments="hoteldata"/>
</transition>
</view-state>
These fragments (hoteldata, in this case) can be a comma-separated list of fragments specified at the markup with th:fragment :
<div id="data" th:fragment="hoteldata">
This is a content to be changed
</div>
Always remember that the specified fragments must have an id attribute, so that the Spring JavaScript libraries running on the browser are capable of substituting the markup.
tags can also be specified using DOM selectors:
<view-state id="detail" view="bookingDetail">
<transition on="updateData">
<render fragments="[//div[#id='data']]"/>
</transition>
</view-state>
...and this will mean no th:fragment is needed:
<div id="data">
This is a content to be changed
</div>
As for the code that triggers the updateData transition, it looks like:
<script type="text/javascript" th:src="#{/resources/dojo/dojo.js}"></script>
<script type="text/javascript" th:src="#{/resources/spring/Spring.js}"></script>
<script type="text/javascript" th:src="#{/resources/spring/Spring-Dojo.js}"></script>
...
<form id="triggerform" method="post" action="">
<input type="submit" id="doUpdate" name="_eventId_updateData" value="Update now!" />
</form>
<script type="text/javascript">
Spring.addDecoration(
new Spring.AjaxEventDecoration({formId:'triggerform',elementId:'doUpdate',event:'onclick'}));
</script>

Resources