Pattern for avoiding duplicating content when using Thymeleaf and Apache Tiles - tiles

I am seeking to find a clean solution to the following antipattern with my Thymeleaf/Tiles app:
I have two forms (located in two different templates as of now) which are completely identical but for the th:action attributes which point to different urls.
First form:
<form th:object="${advertisementInfo}" th:action="#{/advertisement/family/new}" method="post" class="form-horizontal">
<div th:if="${#fields.hasErrors('*')}" class="alert alert-danger form-group">
<ul>
<li th:each="err : ${#fields.errors('*')}" th:text="${err}"></li>
</ul>
</div>
<input type="hidden" th:field="*{advertisement.id}"/>
<div th:class="${#fields.hasErrors('advertisement.needs')}? 'form-group error':'form-group'">
<label class="control-label col-lg-3" for="needs" th:text="#{advertisement.family.form.needs}">Needs</label>
<div class="col-lg-6">
<select multiple="multiple" th:field="*{advertisement.needs}" class="form-control">
<option th:each="need: ${needs}" th:value="${need}" th:text="#{${'domain.enum.need.' + need}}"></option>
</select>
</div>
</div>
Second form is identical but for the th:action attribute which is as follows: th:action="#{/advertisement/family/edit}"
I thought of several ways to address this antipattern of mine:
Having two different forms and including the (identical) form content with a tiles:include.
Finding a way to have the value for the th:action as a variable somehow.
However, I would be very grateful if someone who has met the same issue could suggest a best practice to me...

If only the action-value is different, I would put the action-url into the model.
If it more complex I would use the default include-mechanism from thymelaef which can be parametrized.
Perhaps tiles isn't the best choice in this situation. Thymeleaf offers 4 different solutions.

Related

How do I get the values of all the selected check box from thymeleaf in spring boot

Data is being populated from database
<div th:each="comm : ${listBothComm}">
<label class="list-group-item d-flex gap-2"> <input
checked="" class="form-check-input flex-shrink-0"
th:field="*{comm_cd}" th:value="${comm.comm_cd}" type="checkbox"><span
th:text="${comm.comm_nm}"> </span>
</label>
</div>
The answer to your question is provided in this post:
https://stackoverflow.com/a/72300493/15730570
The answer is for simple checkbox which passes one value back to controller. To pass multiple values, you will need to to tweak your thymeleaf code accordingly.

handling empty table when displaying view of data

I have a laravel project. it has a table that I want to fill with data from a form. Currently it populates the form with any data that may exist in the table.
I'm using #foreach to iterate through the data object. This works fine when there is data in the table, but when there's no data obviously the #foreach data object will be empty.. How do folk handle this so that the form still shows with default values?
#foreach($pricing as $price)
<div class="form-row align-items-center">
<div class="col-12">
<p><strong>Rate</strong></p>
</div>
<div class="col-12">
<div class="row">
<div class="col-md-2">
<label for="hirePrice" class="">Hire Price</label>
</div>
<div class="col-md-4">
<input type="text" name="hire" class="form-control" placeholder="1200" aria-label="hireprice" id="hirePrice" value="{{ $price->hire}}">
Currently, if I empty the table, the page just displays the header and none of the html above, including the form fields.
edit: The table will always only have 1 ROW !! not sure if this makes it any easier.
You can use
#isset($pricing)
#foreach($pricing as $price)
<div class="form-row align-items-center">
<div class="col-12">
<p><strong>Rate</strong></p>
.................................
//your code
#endforeach
#endisset
Or, You can use if else condition like this:
#if($pricing != Null)
#foreach($pricing as $price)
<div class="form-row align-items-center">
<div class="col-12">
<p><strong>Rate</strong></p>
.....................
//code
#endforeach
#else
<div>No data</div>
#endif
Though i can not get your actual scenario,i can give some advice.
You can add one line condition inside of input tag like this:
HTML:
<input type="text" #if($data->variable) value="{{ $data->variable }}" #else value=" " #endif >
Otherwise, You can put same code within foreach loop into else condition. So, when data exists in the table, it shows the data in the form otherwise same form with empty value will appear.

The PUT method is not supported for this route. Supported methods: GET, HEAD

I'm trying to learn Laravel, and I'm following a series of tutorials called laracast. I'm at episode 24, "Forms that submit PUT requests. The short story is that the markup uses a hidden value to set the method to PUT, although the forms method is set to POST. Still, when I do this, I get the error message from the title:
Symfony\Component\HttpKernel\Exception\MethodNotAllowedHttpException
The PUT method is not supported for this route. Supported methods: GET, HEAD.
From the tutorials, I'd expect POST to also be a supported method. However, when I try to fix this, all resources I can find simply tells me what I already know. PUT is not supported, but I can fake it/override it, and then they refer to what I have already done... Are there any other reasons why I might get this error message?
HTML Form:
<form method="POST" action="/competition-categories">
#csrf
#method('PUT')
<div class="form-group row">
<label for="competition-category-name-input" class="col-4 col-form-label">Name</label>
<div class="col-8">
<input id="competition-category-name-input" name="competition-category-name-input" type="text" class="form-control" required="required" value="{{ $competitionCategory->name }}">
</div>
</div>
<div class="form-group row">
<label for="competition-category-abbreviation-input" class="col-4 col-form-label">Abbreviation</label>
<div class="col-8">
<input id="competition-category-abbreviation-input" name="competition-category-abbreviation-input" type="text" class="form-control" required="required" value="{{ $competitionCategory->abbreviation }}">
</div>
</div>
<div class="form-group row">
<div class="offset-4 col-8">
<button name="submit" type="submit" class="btn btn-primary">Submit</button>
</div>
</div>
</form>
web.php snippet:
//Competition Categories
Route::get('/competition-categories', 'CompetitionCategoryController#index');
Route::get('/competition-categories/create', 'CompetitionCategoryController#create');
Route::get('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#show');
Route::get('/competition-categories/{competitionCategory}/edit', 'CompetitionCategoryController#edit');
Route::post('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#store');
Route::put('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#udpate');
Route::delete('/competition-categories/{competitionCategory}', 'CompetitionCategoryController#destroy');
Snippet from the controller:
public function update(Request $request, CompetitionCategory $competitionCategory)
{
$competitionCategory->update($this->validateCompetitionCategory());
return redirect()->route('competition-categories' , [$competitionCategory]);
}
You're forgetting the id in form, this should fix your problem:
action="/competition-categories/{{$competitionCategory->id}}"
The most common thing that this happens is your cache. When you add a new route or change something in your routes, always run after php artisan optimize to refresh you cache.
I recommend using the named-routes for more informations and messages see =>
https://laravel.com/docs/7.x/routing#named-routes

how to get current user data only in laravel

i am working on laravel and want to get only login user data but when i change code it give error in my view
public function index(){
$users = User::all();//Auth::user();//
//dd($users);
return view ('profile.index',compact('users'));
}
this is the code that give output and show all user data
when i change the code the error it give me no output
this is image
this is view i am using
<div class="container">
<div class="row">
<div class="container" >
<h2>Basic Details<h2>
<form>
#foreach($users as $user)
<image src=" {{$user['image']}}" class="img-circle">
<div class="form-group col-lg-3">
<span class="input-group-addon"><i class="glyphicon glyphicon-user"></i></span>
<h4>Name:</h4>
<input type="text" value="{{$user['name']}}" class="form-control" id="text" name="text"
readonly="true">
</div>
<div class="form-group col-lg-3">
<h4 for="Email">Email:</h4>
<input type="email" value="{{$user['email']}}" class="form-control" id="email" name="email"
readonly="true">
</div>
#endforeach
</form>
There are several issues with your code and, as #pseudoanime commented, you can't directly interchange the single user case vs. all users because of the returned data types. However, if you REALLY want to do this, you could change things up so that both situations return a collection, as shown below:
public function index(){
$users = collect(Auth::user());
return view ('profile.index',compact('users'));
}
I'm not sure why you would want to do this rather than simply returning a different view, but I'll leave that up to you. Please note that I would suggest re-evaluating your problem and taking a different approach, as it makes no sense to loop through a collection you will know only has a single member.
Additionally, you should note that you are not accessing the user model properly. You are using array syntax in the view (for example, $user['email']) when you should be using object syntax ($user->email). There are other issues with the code that may still cause issues, but this is the most obvious problem I see.

is it good practice to use custom tag lib to generate html forms dynamically?

I'm using MVC architecture, I have used my own custom taglib along with JSTL that will generate forms, gridList dynamically. is it a proper practice to do it. is it make any impact on performance?
<c:forEach items="${uiFieldList}" var="u" >
<div class="span5">
<div class="control-group">
<label class="control-label" ><spring:message code="${u.fieldLabel}" /><c:if test="${u.mandatory =='Y'}"><strong style="color:red;">*</strong></c:if></label>
<div class="controls">
<div class="input-prepend">
<iana:text name="${u.name}" id="${u.id}" value="${u.value}" ></iana:text>
</div>
</div>
</div>
</div>
Any suggestions?

Resources