Thymeleaf populate a date field with date - spring-boot

I need help populating a date field for an edit page in Thymeleaf. So Im a beginner with this but I've tried so many variations I don't know the best approach now. So Im passing the Employee list to thymeleaf with a model.addTribute("employee", employee) and the data looks like this:
Employee: Employee{id=2, name='John Smith', contractedFrom='2022-01-01', contractedTo='2022-12-31', employeeProjects=[EmployeeProject{id=1, project=Project{id=1, projectNumber=61741501, name='Project 1', startDate='2022-04-01', endDate='2022-09-30', projectLengthInMonths=3.0, currentBookedMonths=0.0, remainingBookedMonths=0.0, numberOfEmployees=0}, employeeBookedMonths=4.0, employeeProjectStartDate=2022-05-01, employeeProjectEndDate=2022-09-15, projectName='null'}, EmployeeProject{id=2, project=Project{id=2, projectNumber=61241514, name='Project 2', startDate='2022-01-01', endDate='2023-03-31', projectLengthInMonths=24.0, currentBookedMonths=0.0, remainingBookedMonths=0.0, numberOfEmployees=0}, employeeBookedMonths=4.5, employeeProjectStartDate=2022-10-01, employeeProjectEndDate=2022-12-31, projectName='null'}], projectIds=[4, 5, 7, 8], startDates=[2022-01-01, 2022-05-01, 2022-10-01, 2022-08-01], endDates=null}
So the input form has the Employee name, contractedFrom and ContractedTo which work fine, then below there is a checkbox with a date field. I can populate the checkbox using the projectsIds field, but how can I populate the dates fields with the startDates array? Or is there a better way? I've also tried creating a projectDto but I couldn't get that to work either. Here is what the dto looks like:
[ProjectDto(id=1, employeeProjectStartDate=2022-01-01, employeeProjectEndDate=2022-04-30), ProjectDto(id=2, employeeProjectStartDate=2022-05-01, employeeProjectEndDate=2022-09-15), ProjectDto(id=3, employeeProjectStartDate=2022-10-01, employeeProjectEndDate=2022-12-31), ProjectDto(id=4, employeeProjectStartDate=null, employeeProjectEndDate=null)]
Any help is greatly appreciated. Here is the form code:
<form action="#" th:action="#{/ines/updateEmployee/{id}(id=${employee.id})}" th:object="${employee}"
method="POST">
<input type="hidden" th:field="*{id}" />
<input type="text" th:field="*{name}"
placeholder="Employee Name" class="form-control mb-4 col-4">
<input type="date" th:field="*{contractedFrom}"
placeholder="Contracted From" class="form-control mb-4 col-4">
<input type="date" th:field="*{contractedTo}"
placeholder="Contracted To" class="form-control mb-4 col-4">
<div th:each="proj : ${projects}">
<div class="form-group blu-margin">
<input type="checkbox" th:field="*{projectIds}" th:name="projectId"
th:text="${proj.name}" th:value="${proj.id}">
<input type="date"
th:field="*{startDates}"
class="form-control mb-4 col-4">
<!-- <input type="date"-->
<!-- th:field="*{endDates}"-->
<!-- class="form-control mb-4 col-4">-->
</div>
</div>
<button type="submit" class="btn btn-info col-2">Save Employee</button>
</form>
Image of the page, as I said the contractedFrom/To populated but not the project startDate.

You can use indices to access individual dates in the startDates array (assuming your startDates is an array of Date (i.e. Date[] startDates).
<div th:each="proj, stats : ${projects}">
<div class="form-group blu-margin">
<input type="checkbox" th:field="*{projectIds}" th:name="projectId"
th:text="${proj.name}" th:value="${proj.id}">
<input type="date"
th:value="${startDates[stats.index]}"
class="form-control mb-4 col-4">
<!-- <input type="date"-->
<!-- th:value="${endDates[stats.index]}"-->
<!-- class="form-control mb-4 col-4">-->
</div>
Or alternatively, since your ProjectDTO already contains employeeProjectStartDate and employeeProjectEndDate fields, you can access those fields in the th:each loop by using ${proj.employeeProjectStartDate} and ${proj.employeeProjectEndDate} respectively.

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}}

How would I display a single form label with the required class above two text fields using Laravel and Bootstrap 4

I'm using Laravel and Bootstrap 4.2.1 and would like to display a form label over two required in-line text fields. I can get the label over the two fields by placing the form label outside of a form group but I am unable to get the red asterisk (*) display next to the form label. I've placed my code here in jsfiddle.
<label for="contact_first_name" class="form-label required">Contact Name</label>
<div class="form-group mb-3">
<div class="row">
<div class="col-md-6">
<input class="form-control" id="contact_first_name" name="contact_first_name" type="text"
placeholder="First Name" value="" required>
</div>
<div class="col-md-6">
<input class="form-control" id="contact_last_name" name="contact_last_name" type="text"
placeholder="Last Name" value="" required>
</div>
</div>
</div>
Try adding a span tag with class="text-danger" or style="color:red" inside the label tag and the * in it. Either way, you will get an * sign with the label.
Below, I have used the bootstrap approach of adding class="text-danger" to the span tag.
<label for="contact_first_name" class="form-label required">Contact Name
<span class="text-danger">*</span>
</label>
<div class="form-group mb-3">
<div class="row">
<div class="col-md-6">
<input class="form-control" id="contact_first_name" name="contact_first_name" type="text"
placeholder="First Name" value="" required>
</div>
<div class="col-md-6">
<input class="form-control" id="contact_last_name" name="contact_last_name" type="text"
placeholder="Last Name" value="" required>
</div>
</div>
</div>
Here is the link to the Jsfiddle.
#AhmadKarimi Thank you for your comment and solution. I just figured it out (by accident) while working on a different form. I needed to drop the label form control down one level inside of the form-group. It doesn't appear to work in jfiddle though.
<div class="form-group mb-3">
<label for="contact_first_name" class="form-label required">Contact Name</label>
<div class="row">
<div class="col-md-6">
<input class="form-control" id="contact_first_name"
name="contact_first_name" type="text"
placeholder="First Name" value="" required>
</div>
<div class="col-md-6">
<input class="form-control" id="contact_last_name"
name="contact_last_name" type="text"
placeholder="Last Name" value="" required>
</div>
</div>
</div>

Avoiding field prepopulation in a thymeleaf form with Spring-Boot

I am having a trouble getting rid of the field prepopulation in a thymeleaf form and displaying text placeholders instead.
Here is the snippet of the form:
<form action="#" th:action="#{/catch/save}" th:object="${catch}" method="post">
<input type="hidden" th:field="*{id}">
<input type="text" th:field="*{species}" th:placeholder="Species"
class="form-control mb-4 col-3">
<input type="text" th:field="*{length}" th:placeholder="Length"
class="form-control mb-4 col-3">
<input type="text" th:field="*{weigth}" th:placeholder="Weigth"
class="form-control mb-4 col-3">
and here is the image of the resulting form:
Prepopulated form
My goal is to have the two fields prepopulated with "Length" and "Weigth". These fields correspond to int and double object fields, so if I understand correctly they are initiated with 0 when the bean is created and therefore so are th:fields when the form is loaded.
Could you help me find a way to solve this?
Thank you in advance

Form Fields: Name and Phone Not Passed Along with Request in Paystack

I am trying to implement Paystack in Laravel; I'm using their suggested documentation for Laravel. The issue is that the amount and email get passed onto the Paystack database, but the customer's name and phone details aren't. How do I get it to be passed along to Paystack?
I have configured the checkout process as mentioned in the documentation based on https://github.com/unicodeveloper/laravel-paystack. I'm using Windows 10 and running Laravel 5.6 and PHP 7.3.
<form class="needs-validation" action="{{ route('pay') }}" method="POST">
<div class="row">
<div class="col-md-6 mb-3">
<label for="first_name">First name</label>
<input type="text" class="form-control" id="first_name"
placeholder="first name" value="" name="first_name" required="">
</div>
<div class="col-md-6 mb-3">
<label for="last_name">Last name</label>
<input type="text" class="form-control" id="last_name"
placeholder="last Name" name="last_name" value="" required="">
</div>
</div>
<div class="mb-3">
<label for="email">Email <span class=" text-danger"> * </span>
</label>
<input type="email" class="form-control" id="email" name="email"
placeholder="you#example.com" required>
</div>
{{ csrf_field() }}
<hr class="mb-4">
<button class="btn btn-success btn-lg btn-block" type="submit"
value="Pay Now!">
<i class="fa fa-plus-circle fa-lg"></i> Complete Payment!
</button>
</form>
I expected that after the payment is complete, the customer data should contain the customer email, and name. But it returns only the email in the customer array.
you have to implement it yourself, before the pay button try to have a form like this
<form action="/myform" method="post">
<input type="text" name="fullname">
<input type="number" name="phone_number">
<button>submit</button>
</form>
Route::post('/myform','controllerhere#form1')->name('name');
Route::get('/pay','controller#function')->name('pay');
Route::post('/pay','controller#function')->name('pay');
then your controller to look like this
public function form1(Request $request){
$request->validate([....]);
save the form and return redirect to your payment form like this
..
return redirect('/pay');
}
then payments can be made, please the above codes are just samples to help
Alternatively if you check the https://github.com/unicodeveloper/laravel-paystack package, there is a commented section in the paystack.php; this contains a sample of how to add custom_fields to the metadata.
`<input type="hidden" name="metadata" value="{{ json_encode($array) }}" >`
$array = [ 'custom_fields' => [
['display_name' => "Cart Id", "variable_name" => "cart_id", "value" => "2"],
['display_name' => "Sex", "variable_name" => "sex", "value" => "female"],
]
]
Edit this to add name of the customer and amount then if you dd($paymentdatails) you will see the details in metadata.

AngularJS Slightly Advanced Validation / Bootstrap3 Style

I am in the process of learning AngularJS, still at the most basic stages of form validation. I followed the official tutorial here, and managed to get the validation working like they have, where if input is invalid, the background changes colour.
That is all nice and counts as an important step in my learning, but how do I move a little further and have the validation add / remove CSS classes required by Bootstrap to show visual cues?
Here is my HTML code:
<form novalidate class="css-form">
<div class="form-group">
<label class="control-label" for="fname">First Name</label>
<input type="text" id="fname" placeholder="First Name" class="form-control" ng-model="user.fname" required >
</div>
<div class="form-group">
<label class="control-label" for="lname">Last Name</label>
<input type="text" id="lname" placeholder="Last Name" class="form-control" ng-model="user.lname" required >
</div>
<div class="form-group">
<label class="control-label" for="email">Email</label>
<input type="email" id="email" placeholder="Email" class="form-control" ng-model="user.email" required >
</div>
<div class="form-group">
<label class="control-label" for="password">Password</label>
<input type="password" id="password" placeholder="Password" class="form-control" ng-model="user.password" required >
</div>
<div class="form-group">
<label class="control-label" for="emailpref">Want annoying emails?</label>
<select class="form-control" ng-model="user.emailpref" required>
<option value="Null">Please Select</option>
<option value="Yes">Yes</option>
<option value="No">No</option>
</select>
</div>
<button type="submit" class="btn btn-primary">Submit</button>
</form>
In the Bootstrap3 documentation, it says that if I need to show a valid state, I must add a CSS class of has-success like so:
<div class="form-group has-success">
<label class="control-label" for="fname">First Name</label>
<input type="text" id="fname" placeholder="First Name" class="form-control" ng-model="user.fname" required >
</div>
How can I get my AngularJS validation to do that? At the moment, my AngularJS is as follows:
function UserCtrl($scope) {
$scope.master = {};
$scope.user = { fname: "J", lname: "Watson", password: "test", email: "j.watson#world.com", emailpref: "Yes" };
$scope.update = function(user) {
$scope.master = angular.copy(user);
};
$scope.reset = function() {
$scope.user = angular.copy($scope.master);
};
$scope.reset();
}
To add dynamic classes based on field validation you need to do two things
Give your form a name
`<form novalidate class="css-form" name="form1">`
Give each input field a name too. You can then use expression to determine state of error of a field
<div class="form-group has-success" ng-class="{'has-success':form1.fname.$invalid}">
<label class="control-label" for="fname">First Name</label>
<input type="text" id="fname" placeholder="First Name" class="form-control" ng-model="user.fname" required name="fname">
</div>
Please go through the form guide http://docs.angularjs.org/guide/forms for more details.
You can use angular-validator.
Disclaimer: I am the author of angular-validator

Resources