Reputation:
How do I receive either true or false from an checkbox in html with Thymeleaf over to my controller, so I can take the value either true or false and save in my DB. So far I receive these errors:
org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/normal/start-dag.html]")
Caused by: org.attoparser.ParseException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputCheckboxFieldTagProcessor' (template: "normal/start-dag" - line 24, col 44)
Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Error during execution of processor 'org.thymeleaf.spring5.processor.SpringInputCheckboxFieldTagProcessor' (template: "normal/start-dag" - line 24, col 44)
2018-07-17 09:05:16.097 ERROR 6713 --- [nio-8080-exec-2] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.thymeleaf.exceptions.TemplateInputException: An error happened during template parsing (template: "class path resource [templates/normal/start-dag.html]")] with root cause
java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'goodNightOfSleep' available as request attribute at org.springframework.web.servlet.support.BindStatus.(BindStatus.java:153) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
My html looks like this:
<table>
<tr>
<input type="checkbox" th:path="goodNightOfSleep">
<label th:for="${#ids.next('goodNightOfSleep')}" th:text="#{StartDay.goodNightOfSleep}">Kan du huske hvad du drømte?</label>
<input type="checkbox" th:field="*{goodNightOfSleep}"/>
</tr>
</table>
And my Controller:
// Start Day
@GetMapping("/normal/start-dag")
public String opretGoal() {
return "normal/start-dag";
}
@PostMapping("/normal/start-dag")
public String opretGoal(@ModelAttribute StartDay startDay, BindingResult bindingResult) {
if (bindingResult.hasErrors()) {
return "/normal/menu";
}
startDayService.createGoalOfTheDay(startDay);
return "normal/menu";
}
My StartDay.java class:
@Entity
@Table(name = "start_day")
public class StartDay {
@Id
@Column(name = "age_in_days", nullable = true)
private int ageInDays;
@Column(name = "day_created", nullable = true)
private String dayCreated;
@Column(name = "username", nullable = true)
private String username;
@Column(name = "dream_remembered", nullable = true)
private boolean dreamRemembered;
@Column(name = "nightmare", nullable = true)
private boolean nightmare;
@Column(name = "waking_time", nullable = true)
private int wakingTime;
@Column(name = "good_night_of_sleep", nullable = true)
private boolean goodNightOfSleep;
Any help appreciated :)
UPDATE #1
So I just tried to move the second th:field from the html, so it looks like this:
<table>
<tr>
<input type="checkbox" th:path="goodNightOfSleep">
<label th:for="${#ids.next('goodNightOfSleep')}" th:text="#{StartDay.goodNightOfSleep}">Kan du huske hvad du drømte?</label>
</tr>
</table>
And that makes me actually able to land on the page, but my checkbox looks like this, and doesn't return a value:
Upvotes: 1
Views: 3928
Reputation: 814
@GetMapping("/normal/start-dag")
public String opretGoal(Model model) {
...
StartDay startDay = .... // e.g. new StartDay();
model.addAttribute("startDay", startDay);
...
return "normal/start-dag";
}
@PostMapping("/normal/start-dag")
public String opretGoal(@Valid StartDay startDay, BindingResult bindingResult, Model model)
{
if (bindingResult.hasErrors()) {
// log and/or handle errors
}
else {
// your logic goes here
startDayService.createGoalOfTheDay(startDay);
}
return "/normal/menu";
}
<form action="... or use th:action" method="post" th:object="${startDay}">
...
<input type="checkbox" name="goodNightOfSleep">
...
</form>
You could also use th:field for the goodNightOfSleep-Input but it works like writen above. Thymeleaf match the field by name to the object defined in the form-element. If you check the box the value will be true else it will be false.
The point is to 1.) add the object to the model and 2.) receive the object as a input parameter.
Warning: The code is writen to the editor without testing it. Maybe there are typos.
Upvotes: 1
Reputation: 2268
Did you try returning a ModelAndView
instead of your String
, and adding your StartDay
as Model attribute as described here?
e.g.
@GetMapping("/normal/start-dag")
public ModelAndView opretGoal(){
ModelAndView mav = new ModelAndView("normal/start-dag");
mav.addObject("StartDay", new StartDay());
return mav;
}
Upvotes: 0
Reputation: 298
- java.lang.IllegalStateException: Neither BindingResult nor plain target object for bean name 'goodNightOfSleep' available as request attribute at org.springframework.web.servlet.support.BindStatus.(BindStatus.java:153) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE] at org.springframework.web.servlet.support.RequestContext.getBindStatus(RequestContext.java:903) ~[spring-webmvc-5.0.7.RELEASE.jar:5.0.7.RELEASE]
Error No 5 is because thymeleaf is not able to find "goodNightOfSleep" attribute.
Try passing StartDay object in the model attribute of get request.
@GetMapping("/normal/start-dag")
public String opretGoal(Model model){
model.addAttribute("startDay", new startDay());
return "normal/start-dag";
}
and make sure startDay "th:object" is defined in the UI.
<form th:action="@{normal/start-dag}" th:object="${startDay}" method="post">
Upvotes: 0