I'm using spring-boot with .jsp files to show web-content. My controller looks like this:
@Slf4j
@Controller
@AllArgsConstructor
@SessionAttributes({"language", "amount", "words"})
public class LanguageController
{
private LanguageService languageService;
// Additional services
@Transactional
@GetMapping("/language")
public String editLanguage(ModelMap model, @RequestParam(value = "languageId", defaultValue = "-1", required = false) long languageId)
{
log.info("editLanguage() called");
model.put("languageData", languageService.getLanguageData(languageId));
return "language";
}
// Additional endpoints
}
And the .jsp file contains this:
<%@ taglib uri="http://java.sun.com/jsp/jstl/core" prefix="c" %>
<%@ taglib prefix="form" uri="http://www.springframework.org/tags/form" %>
<html>
<head>
<%@include file="common/head.jspf" %>
</head>
<body>
<%@include file="common/navigation.jspf" %>
<div class="container">
<h1>Edit Language Details</h1>
<%--@elvariable id="languageData" type="io.fi0x.languagegenerator.logic.dto.LanguageData"--%>
<form:form method="post" modelAttribute="languageData">
<form:input type="hidden" path="id"/>
<form:input type="hidden" path="username"/>
<table>
<tr>
Name: <form:input type="text" path="name"/>
</tr>
<tr>
<%-- TODO: Fix the initial state of the checkbox to represent the language data--%>
Public Language: <form:checkbox path="isPublic" checked="${languageData.isPublic}"/>
</tr>
<tr>
Min-Word-Length: <form:input type="number" path="minWordLength"/>
</tr>
<tr>
Max-Word-Length: <form:input type="number" path="maxWordLength"/>
</tr>
<tr>
<a>Separate individual letter-combinations by ','</a>
</tr>
<tr>
Possible Vocals: <form:input type="text" path="vocals"/>
</tr>
<tr>
Possible Consonants: <form:input type="text" path="consonants"/>
</tr>
<tr>
Possible Vocal-Consonant-Combinations: <form:input type="text" path="vocalConsonant"/>
</tr>
<tr>
Possible Consonant-Vocal-Combinations: <form:input type="text" path="consonantVocals"/>
</tr>
<tr>
Forbidden Combinations: <form:input type="text" path="forbiddenCombinations"/>
</tr>
<tr>
<input type="submit" class="btn-success">
</tr>
</table>
</form:form>
</div>
<%@include file="common/scripts.jspf" %>
</body>
</html>
When I open the endpoint in a browser, everything works, except for the isPublic
checkbox. The checkbox is never pre-selected, weather the boolean is true or false.
I tried to access the value of the boolean in several ways, but none worked. What am I doing wrong here, why is the checked
state always unchecked, regardless of the boolean-value?
I'm not trying to get the value of the checkbox, but I want to set the initial state of the checkbox.
My LanguageData
class:
@Data
@Builder
public class LanguageData
{
private Long id;
private String name;
private String username;
private Boolean isPublic;
private int minWordLength;
private int maxWordLength;
private List<String> vocals;
private List<String> consonants;
private List<String> vocalConsonant;
private List<String> consonantVocals;
private List<String> forbiddenCombinations;
public static LanguageData getFromEntity(Language language)
{
// Some conversion logic
}
public boolean invalid()
{
// Some logic
}
}
The first problem was actually that isPublic
was a Boolean
-object instead of a primitive-type. But this on its own does not make any visible changes.
The second part of the problem, is the checked
attribute in the <checkbox>
-tag. This answer contains the solution:
If the checked attribute exists, the checkbox will be checked regardless of what value you set it to.
When I removed the checked
attribute from the <checkbox>
-tag, it finally worked. Here are the parts I changed, for anyone who finds this post in the future:
@Data
@Builder
public class LanguageData
{
// Same as in question
private boolean isPublic;
// Same as in question
}
// Same as in question
<tr>
Public Language: <form:checkbox path="isPublic" />
</tr>
// Same as in question