th:field syntax inside th:each is incorrect - spring-boot

I am using spring boot and thymeleaf combination for my project.
Following is the code snippet for Get controller -
#GetMapping("/split")
public String VerticalSplit(Model model) {
MessageContent messageContent0 = new MessageContent();
MessageContent messageContent1 = new MessageContent();
List<MessageContent> messageContentList = new ArrayList<MessageContent>();
messageContentList.add(0, messageContent0);
messageContentList.add(1, messageContent1);
DisplayMessage displayMessage = new DisplayMessage();
model.addAttribute("displayList", displayService.getAllDisplays());
model.addAttribute("groupList", groupService.getAllGroups());
model.addAttribute("messageContentList", messageContentList);
model.addAttribute("displayMessage", displayMessage);
return "combo_vertical_split";
}
And respective html code is as follows -
<html>
<head></head>
<body>
<div class="col-12">
<label class="form-label"> Name of Message </label>
<input type="text" name="name" class="form-control" placeholder="Enter Name Of Message" required="required" th:value="${displayMessage.name}" />
</div>
<hr />
<div th:each="messageContent, iStat : ${messageContentList}">
<h6 align="center" th:text="'Section '+${iStat.count}"></h6>
<div class="form-group">
<label class="form-label"> Select the content type </label>
<select name="messageContentType" id="messageContent" class="form-control" th:onchange="ShowHideTextMediaDiv();" th:field="${messageContent.type}"> <option class="form-select" th:value="Text">Text</option> <option class="form-select" th:value="Image">Image</option> <option class="form-select" th:value="Video">Video</option> </select>
<br />
</div>
</div>
</body>
</html>
When I am trying to load the page, i am getting error as follows -
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'messageContent' available as request attribute
The point which I am not getting is that even though I have declared the messageContent in controller, why am i getting the above mentioned error.
I tried multiple syntax of
th:field="${messageContent.type}"
as follows -
th:field="*{messageContent.type}" //its silly as i have not declared the form object but still i tried
th:field="${messageContentList[__${iStat.index}__].type}"
and few other combinations as well, but nothing worked and almost everytime i got the same error.

You're getting the Neither Bindingnor plain target... error because you have used the th:field in your HTML, but you haven't defined an object from which to bind to it.
You can add your input elements in a form element and add a th:object attribute bound to your model's messageContent object.
You can do something similar to this:
<form th:object="${messageContent}">
<div class="form-group">
<label class="form-label"> Select the content type </label>
<select name="messageContentType" id="messageContent" class="form-control" th:onchange="ShowHideTextMediaDiv();" th:field="*{type}">
<option class="form-select" th:value="Text">Text</option>
<option class="form-select" th:value="Image">Image</option>
</select>
<br />
</div>
</form>

Related

Error in passing the foreign key in the form for editing

I have two tables, one named Client and the other named Projects linked together via a foreign key (this is client_id, which is present in Projects).
Each project has an edit button; when I click to edit a project I have a form with all fields secured to it.
To edit a project I have to pass the client id (client_id) associated with that project.
To do this, I did the following:
ROUTE
Route::get('/project/edit/{project}', [ProjectController::class, 'edit'])->name('project.edit');
CONTROLLER
public function edit(Project $project)
{
$client_id = Project::select('client_id')->where('id',$project->id)->get();
//dd($client_id);
return view('project.edit', compact('project','client_id'));
}
VIEW
<div class="row mt-3">
<div class="col-12 col-md-6 namelabel">
<form action="{{route('project.store')}}" method="post" enctype="multipart/form-data">
#csrf
<div class="mb-3">
<input type="hidden" class="form-control" name="client_id" value="{{$client_id}}" >
</div>
<div class="mb-3">
<label for="name" class="form-label">Project name</label>
<input type="text" class="form-control" name="name" value="{{$project->name}}">
</div>
<div class="mb-3">
<div class="mb-3">
<label for="logo" class="form-label">Insert image</label>
<input type="file" name="logo">
</div>
<div class="mb-3">
<label for="project_start_date" class="form-label">Data init</label>
<input type="date" class="form-control" name="project_start_date" value="{{$project->project_start_date}}">
</div>
<label for="description" class="form-label">Description</label>
<textarea name="description" cols="30" rows="10" class="form-control">{{$project->description}}</textarea>
</div>
<button type="submit" class="btn btn-primary mb-5">Modifica progetto</button>
</form>
</div>
</div>
I get the following error:
Incorrect integer value: '[{"client_id":14}]' for column 'client_id' at row 1
How can I solve this problem?
Thanks to those who will help me
This statement
Project::select('client_id')->where('id',$project->id)->get()
does not return the client_id. It returns an Eloquent Collection of Projects with only the client_id Attribute.
You can chain the pluck function to extract only value and then you can call first to get the value from the collection.
Project::select('client_id')
->where('id',$project->id)
->get()
->pluck('client_id')
->first()
After checking your code in the full detail you don't need to do the select part at all.
You have already the Project Model so you can access all of it's fields directly.
$project->client_id
In your view you are doing this already with the name of the project:
{{$project->name}}
You can do the same with the client_id as well:
{{$project->client_id}}

Can't load page in Spring Boot using th:object

It contains a line error: "An error happened during template parsing (template: "class path resource [templates//register.html]")".
I can't open register html page to add new object into db. why?
<form th:action="#{/register-user}" th:object="user" method="post">
<div class="form-group">
<label for="email">Email:</label>
<input type="email" class="form-control" id="email" placeholder="Enter email" name="email">
</div>
<div class="form-group">
<label for="password">Password:</label>
<input type="password" class="form-control" id="password" placeholder="Enter password" name="pswd">
</div>
<div class="form-group form-check">
</div>
<button type="submit" class="btn btn-primary">Register</button>
</form>
My controller
#RequestMapping(path="/register-user", method = RequestMethod.POST)
public String registerNewUser(#Valid #ModelAttribute("user") User user){
userService.register(user);
return "redirect:/login";
}
Your "user" is a model attribute, hence, to access it (and use it as the th:object) you gotta use the ${...} syntax. The result would look like this:
<form th:action="#{/register-user}" th:object="${user}" method="post">

How to populate model with primary key when persisting through a controller

I'm quite new to spring and Thymeleaf integration so bear with me:
I'm having trouble getting the data from my Thymeleaf template using a JPA model. I've tried using both sequential and identity generation strategies but It doesn't even let me load the page
I've tried creating a completely new variable as seen before but that's clearly not the problem. I know the problem might come from the Thymeleaf references from the html but I'm quite confused; is there a way to auto generate an ID? It doesn't even let me add a value in the form as an ID
class Admin(#Id #GeneratedValue(strategy = GenerationType.IDENTITY) var id: Long, var firstName: String, var lastName: String, var login: String, var password: String) {
#PostMapping("/addstuff")
fun addAdmin(#ModelAttribute(name = "admin") admin: Admin, result: BindingResult, model: Model): String {
val newAdmin: Admin = Admin(admin.id, admin.firstName, admin.lastName, admin.firstName[0].plus(admin.lastName), encoder.encode("password"))
adminRepository.save(newAdmin)
return "adminadd"
}
form action="#" data-th-action="#{/addstuff}" th:object="${admin}" method="post">
<div class="row justify-content-center" id="mainBody">
<div class="col-8">
<div id="student0">
<div class="row">
<div class="col">
Administrator Information
</div>
</div>
<div class="row">
<div class="col">
<input th:field="*{firstName}" type="text" class="form-control" placeholder="First name">
</div>
<div class="col">
<input th:field="*{lastName}" type="text" class="form-control" placeholder="Last name">
</div>
<div class="col">
<input type="number" class="form-control" placeholder="Administrator ID number">
</div>
</div>
<div class="row">
<div class="col">
<label>Role
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="adminRadio"
value="option1" checked>
<label class="form-check-label" for="adminRadio">
Administrator
</label>
</div>
<div class="form-check">
<input class="form-check-input" type="radio" name="exampleRadios" id="profRadio"
value="option2">
<label class="form-check-label" for="profRadio">
Professor
</label>
</div>
</label>
</div>
</div>
<hr>
</div>
<input id="submitAdmin" type="submit" value="Add Administrator">
<!-- <button id="submitAdmin">Add Administrator</button>-->
</div>
</div>
</form>
The result I expect should be the persisting of the data into my local db but the error i get is this:
'admin' on field 'id': rejected value [null]; codes [typeMismatch.admin.id,typeMismatch.id,typeMismatch.long,typeMismatch]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [admin.id,id]; arguments []; default message [id]]; default message [Failed to convert value of type 'null' to required type 'long'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [null] to type [#javax.persistence.Id #javax.persistence.GeneratedValue long] for value 'null'; nested exception is java.lang.IllegalArgumentException: A null value cannot be assigned to a primitive type]]
I know it has to do with the id value but I'm stuck as to how I generate a value for it. I'm using the h2 embedded database if anyone is interested. Thanks in advance
Though your question is about data not getting transferred between template and JPA but exception clearly say the problem with JPA only. You are never required to pass ID while saving a new entity object in database. I suspect your id column in database table is not defined with auto generation strategy. Can you try modifying it and rerunning your code.
I've figured it out! I used the regular old html name tag and thymeleaf parsed and read it.
<div class="col">
<input type="text" name="lastName" class="form-control" placeholder="Last name">
</div>

attributes in form that define in modal does not get dynamic value in laravel :(

I created a table for editing the Movie Object.
One of the table's column is a form that pops up with a modal class (bootstrap)
Here is my code:
<div class="modal-body">
<form method="post" action="{{asset(route('movies.update', $movie->id))}}">
<input type="hidden" name="_token" value="{{csrf_token()}}">
{{method_field('PATCH')}}
<div class="form-group">
<label for="movie-name" class="col-form-label">Name:</label>
<input type="text" class="form-control" name="movie_name" id="movie-name" placeholder="{{$movie->name}}">
</div>
<div class="form-group">
<label for="movie-director" class="col-form-label">Direcor:</label>
<select class="form-control" name="Director">
#foreach($directors as $director)
<option value="{{$director->id}}">{{$director->name}}</option>
#endforeach
</select>
</div>
<button class="form-control btn btn-success" type="submit" class="btn btn-primary">Send message</button>
</form></div>
When I choose one of the edit buttons, the value of the first item (movie) passes to my controller.
I've tested my code and find out it's happening because I have used the modal class.
Do you have any ideas to solve this problem?

Form fields in acordina are not geting validated

I am using validationEngine for validating form fields. I have tab and inside the tab, I have two accordions. Each accordion has 4 fields. When I submit, only first accordion form fields that are opened are getting validated. Is there any way I can force to validate all the form fields and open all accordions to show the required field message? Thank you!
<div id="tabs-1">
<div id="accordion">
<h3>Select Agent</h3> <!-- First accordion title) -->
<fieldset>
<div>
<label >Agent Name or ID</label>
<input name="insuredFirsName" title="type "Agent name or id "" class="validate[required] text-input" type="text" >
</div>
<label>Age</label>
<input type="text" name="age" value="${ajaxForm.age}" maxlength="3" size="3" class="validate[required] text-input" >
</fieldset>
<h3>Application Details</h3> <!-- Second accordion title) -->
<fieldset>
<div>
<label>Contract State</label>
<select name="State" id="State" class="validate[required]">
<option value="">Choose a State</option>
<option value="IL">Illinois</option>
<option value="MN">Minnesota</option>
<option value="WI">Wisconsin</option>
</select>
</div>
<div>
<label>Application Number :</label>
<input value="" class="validate[required] text-input" type="text" name="req" id="req" />
</div>
<div>
<label>Application Number :</label>
<input value="" class="validate[required] text-input" type="text" name="req1" id="req1" />
</div>
</fieldset>
</div> <!-- Accordion close -->
<html:button property="button1" value ="Submit"></html:button>
</div> <!-- Tab-1 close -->
maybe a little late but I had this same problem, i searched on the internet and found a solution, but this will work for you:
jQuery("#digitale-aanvraag").validationEngine({
validateNonVisibleFields: true,
});
Your fields in an accordion are set to hidden so as default the validator would skip them.
Be aware that if you use this in a wizard, it won't work, because those fields are also hidden...
Anyway, GL!

Resources