Reputation: 137
Please help me to solve this problem: I have no idea how to transfer data from thymeleaf view to controller, that expected data as a hash map? So let me explain in more detail.
I have next pojo, that is used as a wrapper for my hashMap data. It looks like this:
public class DTDays {
private Map<Driver, String> driversDays = new HashMap<>();
public Map<Driver, String> getDriversDays() {
return driversDays;
}
public void setDriversDays(Map<Driver, String> driversDays) {
this.driversDays = driversDays;
}
}
Controller has method with parameter model attribute and another pojo:
@RequestMapping(value = "/go", method = RequestMethod.POST)
public String advanced(@ModelAttribute DTDays dtDays,
@RequestParam(name = "tourId") Long tourId, Model model){
// make some business logic with provided data
return "redirect:/tours/advanced";
}
Here I debugged and dtDays
is not null, but map property is empty, also tourId is worked as expected, I can get right value.
Now to the problem, view:
<body>
<div style="margin-left: 20px;">
<h1 th:text="${tour.tittle}"></h1>
<p>Add tour interval for drivers</p>
<form id="driverIntervals" th:action="@{/advanced/go}" th:object="${driversDays}" method="post">
<table>
<tr>
<td>Drivers:</td>
<td>Date:</td>
</tr>
<tr th:each="d: ${attachedDrivers}">
<td th:text="${d.id+' '+d.fullName}" >
<input type="hidden" th:value="${d.id}" >
</td>
<td>
<input type="text" placeholder="Pick days" th:name="days"/>
</td>
</tr>
</table>
<input type="hidden" th:name="tourId" th:value="${tour.id}"/>
<button type="submit">Confirm</button>
</form>
</div>
</body>
View looks like this:
What should i write in view to submit data? In my case Driver is a key of the map and user entered data in related input field will be a value of a map.
I already know how to submit List, by using select-option in a view:
<select th:name="drivers2attach" multiple="multiple" id="attachDrivers">
<!--/*@thymesVar id="drivers" type="java.util.List<stanislav.tun.novinomad.picasso.persistance.pojos.Driver>"*/-->
<option th:each="d : ${drivers}" th:value="${d.id}"
th:text="${d.getId()+' '+d.fullName}">
</option>
</select>
and @RequestParam List list in controller:
@RequestMapping(value = "/save", method = RequestMethod.POST)
public ModelAndView addTourAction(@ModelAttribute("tour") Tour tour,
@RequestParam(required = false, name = "drivers2attach") List<Long> drivers2attach)
But how to deal with map?
In case with list data is auto populated. In map only keys is prepopulated, this is count of drivers, and now i expect user input for each driver as a key value.
In researching of answers i already read these sources: How to bind an object list with thymeleaf?
Send list object from thymeleaf to controller
How do I load HashMap and ModelandView object values using Thymeleaf in a Spring Boot application?
Use HashMap as Form Backing Bean Spring MVC + ThymeLeaf etc.
But didn't helps. Somewhere in this links I found out that I should use some wrapper to do it, but again no idea why it not works, or what should I do additionally for make it working. Maybe I generally make wrong logic and to submit data as hashmap I shall convert data to list first and then somehow get map from it in controller?
Upvotes: 3
Views: 4981
Reputation: 137
Sorry for creating duplicate question, finally i found solution by following this answer on stackoverflow
i wrote little project for test it and it works. So i was on right way in controller with a wrapper. I missed only view map representation and syntax;
Finally view will looks like this: view
here is view source code:
<form th:action="@{/save}" th:object="${form}" method="post">
<h1>Welcome</h1>
<div th:each="property : ${form.properties.entrySet()}">
<div class="form-group">
<label th:for="*{properties['__${property.key}__']}" th:text="${property.key}">Property</label>
<input type="text" class="form-control" th:field="*{properties['__${property.key}__']}" />
</div>
</div>
<button type="submit">send to controller</button>
and controller:
@PostMapping("/save")
public ModelAndView save(@ModelAttribute(name = "form") MapWrapper form){
var mav = new ModelAndView();
mav.setViewName("index");
mav.addObject("mapWrapper", form);
var map = form.getProperties();
System.out.println("Size of map = "+map.size());
for (Long id : map.keySet()) {
System.out.println("Key: "+id+"; Value: "+map.get(id));
}
return mav;
}
and output is : output
P.S. reason of asking here is that i stuck on this problem for about 2 weeks, I despaired, but found solution after create a question.
Upvotes: 1