nested loop in select option in thymeleaf over map? - spring-boot

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>

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>

thymeleaf how to pass many objects?

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.

How can I use a list of object in the model to automatically populate the options of a select in Thymeleaf view?

I am working on a Spring MVC application that use Thymeleaf for the view.
I am absolutly new in Thymeleaf and I have the following problem.
At this stage of the work into a view I have a select which options values are hard coded into the code, something like this:
<select id="selReg" class="form-control">
<option value="" >--SELEZIONARE UN'AREA--</option>
<option value="areaUmanistica" >Area Umanistica</option>
<option value="areaLinguistica" >Area Linguistica</option>
<option value="areaScientifica" >Area Scientifica</option>
<option value="areaPsicoMotoria" >Area Psico-Motoria</option>
</select>
Now, into my controller, I retrieve a list of Tad1005Tipodisciplina objects using a service and I put this list into the model.
List<Tad1005Tipodisciplina> listaTipoDisciplina = tipoDisiplinaService.getListaTipoDisciplina();
model.addAttribute("listaTipoDisciplina", listaTipoDisciplina);
This Tad1005Tipodisciplina class contain this field:
private String desTipDis;
that I want to use in my view to dinamically show the content of the previous select.
How can I use this list putted into the model to dinamically populate my select options?
You need to iterate through your list using th:each in the select statement. This is where you define a variable that will represent each object in the list, which in turn you can use in each of the option tags like this:
<select id="selReg" class="form-control" th:each="object: ${listaTipoDisciplina}" th:field="*{listaTipoDisciplina}">
<option th:value="${listObject.desTipDis}" th:text="${object.desTipDis}"></option>
</select>
/Edit: A minute too late :)
Solved by myself, in this way:
<select id="selReg" class="form-control">
<option value="" >--SELEZIONARE UN'AREA--</option>
<option th:each="tipoDisciplina: ${listaTipoDisciplina}"
th:value="${tipoDisciplina.codTipDis}"
th:text="${tipoDisciplina.desTipDis}">
</option>
</select>
Posted because maybe it could be util to someone in the future

Spring Web Flow List mapping

In the model bean I have a List with my objects. Like this:
private List<Data> data;
class Data{
String val1;
String val2;
...getters, setters
}
I need to map a few from select tags to a list of my objects. I mean I have something like this:
<select name="val1">
<option value=1>val1 value 1</option>
<option value=2>val1 value 2</option>
</select>
<select name="val2">
<option value=1>val2 value 1</option>
<option value=2>val2 value 2</option>
</select>
after submit action I need to have a list with one Data element with selected values (val1, val2 selects). I need a list cause I have a lot of such "select" pairs and the count is determined dynamically.
Does anybody know how to that?
Thanks in advance.
if your using JSP, use <c:forEach>
http://www.tutorialspoint.com/jsp/jstl_core_foreach_tag.htm

jQuery Prev() Question

Sorry guys, I should have posted the script directly without cleaning it. Please check the updated script, it should now clear things up. Thanks!
Consider the following JavaScript :
var selected = 0;
var options = 0;
$('.newListSelected').each(function() {
selected = $(this).children('.selectedTxt');
selected = selected.text();
/* Everything before this line works completely fine */
options = $(this).prev();
options.find('option[value=' +selected+ ']').attr('selected', 'selected');
}).remove();
And HTML :
<select name="type[]" style="display: none;">
<optgroup>
<option value="none">Select</option>
</optgroup>
<optgroup label="First Group">
<option value="1">One</option>
<option value="2">Two</option>
</optgroup>
<optgroup label="Second Group">
<option value="10">Ten</option>
<option value="20">Twenty</option>
</optgroup>
</select>
<div class="newListSelected">
<div class="selectedTxt">20</div>
<ul class="newList">
<!-- Other stuff here -->
</ul>
</div>
What I'm trying to do actually is adding the selected attribute to the corresponding select option that has the same value as the text in .selectedTxt. In the code above, it should add selected="selected" to <option value="20">Twenty</option>.
However its not performing as expected, I also tried adding alert(option); below prev(); but it didn't output anything useful.
Thanks.
The Javascript works fine, as can be seen here: http://jsfiddle.net/4HsXp/
If you need to be able to select multiple items in a select element, you need to set the multiple and size attribute, like this:
<select multiple="multiple" size="2">
<option>1</option>
<option>2</option>
</select>
See: http://reference.sitepoint.com/html/select
Edit:
Attaching console.log statements to the new code still does not any problem. Running it on jsfiddle gave me the correct output:
jQuery(select)
Original Value: none
New Value: 20
I'm not sure what you are trying to do, but why couldn't you just select all option elements with proper selectors? If you want to select only some options, then you have to add extra selector attrbiutes.
$('select option').each(function() {
$(this).attr('selected', 'selected');
});

Resources