thymeleaf how to pass many objects? - spring

how to pass many objects in one form? becouse like that not working.... help me please
<form class="form-control" action="#" th:action="#{'/'}" method="post">
<select>
<option th:each="city :${cities}" th:value="${city.getId()}" th:text="${city.getName()}"/>
</select>
<select>
<option th:each="category :${categories}" th:value="${category.getId()}" th:text="${category.getDescirption()}">
</option>
</select>
//this line isnt correct:
<a class="btn btn btn-primary btn-sm" href="#"
th:href="#{'/todo/done?id=' + ${city.id} + '&name=' + ${category.name}}">done</a>
</form>

You add each object as named model attribute. Example
#RequestMapping(value = "message", method = RequestMethod.GET)
public String messages(Model model) {
model.addAttribute("cities", citiesRepository.getAll());
model.addAttribute("categories", citiesRepository.getAll());
return "message/list";
}
Personally I find it more readable to have single object as model attribute. That object has fields for each actual attribute.
See official documentation for more details https://www.thymeleaf.org/doc/articles/springmvcaccessdata.html
In your example you are not using th:each correctly.
You should have th:each as select level (not at option level) then refer to individual items in nested select elements.
like
<select th:each="city :${cities}">
<option th:value="${city.getId()}" th:text="${city.getName()}"/>
</select>
In your last example you are refering to ${city.id} and ${category.name} but city and category are not defined (probably thymleaf error message tells you that).
What exactly you want to achieve? Do you want to link with selected city and category? If so, you need separate model attributes like
selectedCity and selectedCatetory.

Related

thymeleaf replacing th:field to comply with th:selected

I appreciate your passing by my post. I have searched here in StackOverFlow and google as well to fix my following code:
My HTML code:
<form th:action="#{/surgerywaitinglist/saveToWaitinList}"
th:object="${waitinglistDTO}" method="POST">
.
.
.
<select name="departmentName"
th:field="*{department.departmentName}"
th:with="departmentName = ${waitinglistDTO.department.departmentName}"
class="form-control" id="departmentJS">
<option value="" th:selected="selected"
th:disabled="disabled">select option
</option>
<option th:each="department: ${departments}"
th:value="${department.departmentName}"
th:text="${department.departmentName}">
</option>
</select>
.
.
.
<input type="submit" value="Save" class="btn btn-primary" />
</form>
form other posts like this post I found out that th:field and th:selected do not work together; in fact, th:field needs to be replace with something else. Notice that the th:object holds another object (from Department class) ...
My DTO class:
public class WaitinglistDTO {
private Long waitingListId;
#NotBlank(message = "Please enter a procedure")
private String waitingListProcedure;
private String waitingListDiagnosis;
private Long waitingListPatientId;
private Long waitingListSurgeonId;
private Long waitingListDepartmentId;
#DateTimeFormat(iso=ISO.DATE)
private Date waitingListAdditionDate;
#DateTimeFormat(iso=ISO.DATE)
private Date waitingListActualBookingDate;
private Patient patient;
private Surgeon surgeon;
private Department department;
Could you help me figure this out?
Many thanxxxxx :)
...
Update:
The following image explains how it should look,,, however, the default option should be the select option which should be somehow disabled
This is the result I get when I apply the suggested code of Rafael da Silva ,, you can see the pre-selected option is the first option rather than the select option option :)
you can do like this:
<select name="departmentName" th:field="*{department.departmentName}" th:with="departmentName = ${waitinglistDTO.department.departmentName}" class="form-control" id="departmentJS">
<option selected="selected" disabled="disabled">select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
this worked for me.
I don't see why you would add the selected to the blank option, the first option is always selected if your model object has nothing set and if it does normal behaviour would be to have that item selected, which th:field should resolve.
In case you want the select to always start at the default option, even if the model has another value or want to set it some other way. you can set th:id="*{department.departmentName}" and th:name="*{department.departmentName}" and than manualy handle th:selected.
As a side note theres no need to use the th version th:selected="selected" if using static values just selected or selected="selected would sufice in that case
Edit with code, not tested as i don't have my work pc where i am.
If you want to always have the first option selected even when editing with previous data
<select name="departmentName" th:name="*{department.departmentName}" th:id="*{department.departmentName}" class="form-control" id="departmentJS">
<option selected disabled>select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
If you want to fill with existing data but default to the first option
<select name="departmentName" th:field="*{department.departmentName}" class="form-control" id="departmentJS">
<option disabled>select option</option>
<option th:each="department : ${departments}" th:value="${department.departmentName}" th:text="${department.departmentName}"></option>
</select>
I'm not 100% sure on the use of disabled but i think it should work, personally i would just leave it selectable and enforce a #notnull on your bean in controller validation.
the th:with annotation does nothing asfar i can see, what th:with is used for is defining a new variable for all elements nested inside the elment you define it on. example:
<div th:with="newVar='someString'">
<span th:text="${newVar}"></span>
</div>

Get DropDownList value into POST method

I am working on this ASP.NET Core MVC where I have this DropDownLisit which gets its values from Controller using ViewBag.DishTypes. However, upon submitting the form, the POST method is not getting the value of the option selected in the DropDownList. The code snippets are as follows:
Controller: GET Method
var allDishTypes = _context.DishType
.ToList()
.Select(dt => new SelectListItem { Value = dt.DishTypeId.ToString(), Text = dt.DishTypeName.ToString() }).ToList();
ViewBag.DishTypes = allDishTypes;
return View();
View
<form asp-controller="Home" asp-action="AddMenuItems">
<div class="row">
<label class="my-1 mr-2" for="inlineFormCustomSelectPref">Dish Type</label>
<div class="input-group">
<div class="fg-line form-chose">
<label asp-for="DishTypeId" class="fg-labels" for="DishTypeId">Dish Type</label>
<select asp-for="DishTypeId" asp-items="ViewBag.DishTypes" class="form-control chosen" data-placeholder="Choose Dish Type" required name="dishtype" id="dishtype">
<option value=""></option>
</select>
</div>
</div>
....
Controller: POST Method
[HttpPost]
public IActionResult AddMenuItems([Bind("DishTypeId, DishName, Cost")] Dishes dishesObj)
{
....
}
the POST method is not getting the value of the option selected in the DropDownList
Note that you specified a name=dishtype within your code. By this way, the field name is
always the same as this name attribute, i.e, dishtype instead of DishTypeId, which will not be recognized by ASP.NET Core by default.
To fix that issue, simply remove that attribute such that it uses asp-for to generate the name attribute automatically:
<select asp-for="DishTypeId" asp-items="ViewBag.DishTypes"
class="form-control chosen" data-placeholder="Choose Dish Type" required
name="dishtype" id="dishtype"
>
<option value=""></option>
</select>

Problem with form option selected where parameters in the url

Hi I have problem with my multiple select search form.
The parameters are in the url
urlhomepage.../search?cars=1&cars=2&cars=4
I do not know how to get parameters url in form option as selected
<select multiple="multiple" name="cars[]" id="select2" placeholder="">
#foreach($names as $name)
<option value="{{$name->id}}">{{$name->title}}</option>
#endforeach
</select>
I want to get the effect so that the form options are marked on the basis of a url query
First you should pass variable as array as cars[] like below
urlhomepage.../search?cars[]=1&cars[]=2&cars[]=4
Inside php you can get cars array form query string
<?php
$cars = request('cars',[]);
?>
And put cars value as auto selected in select
<select value="{{$cars}}" multiple="multiple" name="cars[]" id="select2" placeholder="">

nested loop in select option in thymeleaf over map?

I am passing Map which containg Integer and list from my controller class to view. Inside view I have select option in which i want to show only List value in option but i don't know how to implement this. Please help me to do this.
controller
Map<Integer, List<String>> deviceidsAndwhatToUpdateText = new HashedMap<Integer, List<String>>();
view
<select class="form-control select-checkbox"
id="WhatToUpdate" multiple="multiple">
<option th:each="idsAndText : ${deviceidsAndwhatToUpdateText}"
th:value="${idsAndText.value}"
th:utext="${idsAndText.value}">Wireframe</option>
</select>
This will list all the String in your map, is that what you want?
<select class="form-control select-checkbox" id="WhatToUpdate" multiple="multiple">
<th:block th:each="idsAndText : ${deviceidsAndwhatToUpdateText}">
<option th:each="text : ${idsAndText.value}" th:value="${text}" th:text="${text}" />
</th:block>
</select>

Why it appears the erro Non-static method should not be called statically in this context?

Im trying to use this package " dannyvankooten/laravel-vat" to load a select menu with the countries and then validate the vat number inserted in the input type text.
So I have this in a form:
<div class="form-group font-size-sm">
<select class="form-control" name="country" id="country">
#foreach($countries as $country)
<option value="{{$country}}">{{$country}}</option>
#endforeach
</select>
</div>
<div class="form-group font-size-sm">
<label for="vat" class="text-gray">VAT</label>
<input type="text" id="vat" name="vat" class="form-control" value="">
</div>
In the RegistrationController I have in a method this to return the $countries to the view to the select menu:
$countries = Countries::all();
But it appears:
Non-static method DvK\Laravel\Vat\Countries::all() should not be called statically
Do you know why?
In your specific case (laravel & facades), it's because you have imported the wrong class in your controller.
You need to replace
use DvK\Laravel\Vat\Countries;
with
use DvK\Laravel\Vat\Facades\Countries;
like shown in the readme # https://github.com/dannyvankooten/laravel-vat
The facade is what provides the static accessor e.g. Countries::all()
all is not a static method in the Countries class. You should first create an instance of Countries and then call its all method:
$countries = new Countries();
$allCountries = $countries->all();
return view('congress.registration', ['countries' => $allCountries]);

Resources