Thymeleaf checkbox can't default to checked when using th:field? - java

Does anyone know how to add a default setting of checked in a Thymeleaf, SpringBoot, Java project, to an input field for a Single checkbox?
I have to use th:field because I am later submitting this form via email and if I use th:name with the checked box default, the default works but email doesn't.
Any suggestions?
<label>
<input type="checkbox" id="serviceLevel" th:field="*{serviceLevel}" th:checked="${serviceLevel}"/>
Affiliate Serviced</label>
Email html code to pull value on email:
<tr class="emailRow">
<h3>Direct: </h3>
<td class="bodycopy" th:text="${directBind.directBox}">
</td>
</tr>
I have this variable set as private Boolean directBox in the model.
I've tried everything: th:checked=checked, value=true, value=checked, set the value and checked ="${directBox}" none of this works.
Is there a solution out there?

Figured out a way to use th:field and have it default to checked. Have to set it in my controller, like Gustavo mentioned. Code example below.
...
directBind.setDirectBox(true);
directBind.setServiceLevel(true);
model.addAttribute("directBind", directBind);
return "directBind";

Related

Why does this Spring Boot/Thymeleaf button hide my data or not work at all?

I'm curently trying to get into Spring Boot and Thymeleaf by following tutorials and playing around with the code they provide. I tried implementing an extra functionality and had the following problem: The code should display a ToDo-List consisting of ToDo-Objects that each have a name, description and a boolean status that denotes if they are done or not. Each line of the table is supposed to have a button to click in order to mark a ToDo as done.
<table style="border-collapse:collapse; font-family: Arial,Arial,sans-serif;">
<tr>
<th padding: 5px"></th>
<th> To-Do</th>
<th> Description</th>
<th> Done?</th>
</tr>
<tr th:each="todo : ${todos}">
<td>
<!-- <form method="POST" th:action="#{/updateDone(exactToDo=${todo})}">
<button type="submit" name="submit" value="value" class="link-button">Done</button>
</form> -->
<form method="POST" th:action="#{/updateDone}">
<input type="hidden" name="exactToDo" id="exactToDo" th:value="${todo.getName()}" />
<button type="submit" name="submit" value="value" class="link-button" >This is a link that sends a POST request</button>
</form>
</td>
<td th:utext="${todo.name}" style="border: 1px solid black;">...</td>
<td th:utext="${todo.description}" style="border: 1px solid black;">...</td>
<td th:text="${todo.done} ? 'Yes! ' : 'No' " style="border: 1px solid black;">...</td>
</tr>
</table>
Displaying the contents works, but my button does nothing in this configuration. I followed the directions from this older question, but it doesn't change the status of my ToDos. I can see in the Browser console that it sends a Post request, but there seems to be nothing inside.
The part that is currently commented out makes the data disappear from my table, only leaving the first line with the headers. I tried various similar approaches that I found online, but they all had one of those two results.
Here is the code of the relevant controller:
#RequestMapping(value = {"/updateDone"}, method=RequestMethod.POST)
public String completeTask(Model model, #RequestParam("exactToDo") String exactToDo){
for (ToDo todo : todos){
if (todo.getName().equals(exactToDo)){
todo.markDone();
}
}
return "list";
}
Setting return to "redirect:/list" fixes the problem with the "disappearing" data, but the status of the ToDo still doesn't change. I assume that the problem is that the ToDo object isn't sent to the method correctly, but I'm not exactly sure why. You might have noticed that I am trying to send todo.getName() instead of the ToDo Object directly, that is because when I try to send the object, I get an error in the second line of my posted Controller code, telling me that a String couldn't be converted into a ToDo-Object (the Controller was of course configured to take a ToDo object as parameter). This is why I think the problem has to be somewhere there.
I'd be very grateful if someone could help me fix this problem or point me to a better way of having a button on an HTML-page activate a method in my Java-Code. Tips for good learning resources are also greatly appreciated. I'm trying to learn Spring and Thymeleaf in order to make User Interfaces for Java programs.
Thank you for your time!
First thing First.
Why would you need to write so much (form) just for a button? Now if you "must" use form then you are missing the th:object="${todo}" in your form tag. It will help Controller to understand on what object you are going to take some action.
But I would suggest you use this inside your 'td' block instead of a form. It will do the same job for you. Once your request is successful, you can redirect it to your list and you should see the new results getting reflected immediately.
Mark Done
You can refer this to see a full blown example. Here you will find two things. User Controller and Task Controller that might interest you.
For anyone who might find this later, here is the answer:
The link Ajay Kumar posted ended up working, with a little tweak to include the necessary parameter:
<a href="/updateDone" th:href="#{/updateDone(exactToDo=${todo.getName()})}" >Mark Done</a>

How to handle buttons with same value but different names in Spring

I have a table that is dynamically created that has rows of movies.
It has a title column,
a media type column,
a rating column,
and a column that contains a "view" button.
When one of these view buttons is clicked,
I would like to go to a page that contains all the details of that movie by sending the title to the controller so I can query for it in mySql.
The problem is that for all these buttons,
the value is always going to be "view".
So my solution is to make the name of the button different as shown in the code below (this is the raw html generated from the jsp):
<html>
<body>
<form action="someAction">
<table>
<tr>
<th>title</th>
<th>type</th>
<th>rating</th>
</tr>
<tr>
<td>title1</td>
<td>DVD</td>
<td>R</td>
<td><input type="submit" name="mediaType.title1" value="view"></td>
</tr>
<tr>
<td>title2</td>
<td>DVD</td>
<td>R</td>
<td><input type="submit" name="mediaType.title2" value="view"></td>
</tr>
<tr>
<td>title3</td>
<td>BLU-RAY</td>
<td>PG-13</td>
<td><input type="submit" name="mediaType.title3" value="view"></td>
</tr>
</table>
</form>
</body>
</html>
I could then use a parameterMap to figure out which view was pressed.
That is messy and Spring has to have some way of being able to do this.
I thought something like this would work in the controller:
#RequestMapping("someAction", params = "mediaType.{title}=view")
public ModelAndView loadPage(String title) {
// use title to query mysql
// build Model
// return ModelAndView
}
However this doesn't work.
Is there something that I can use in Spring that would be simpler and cleaner like above instead of getting the parameterMap from the request?
If I'm understanding this correctly, you have rows of information organized into a table. You're looping through some kind of collection, which has the side effect of making each input field have similar 'name' attributes. As a result, it's difficult to determine which input fields you really care about. You've then chosen to use the button as an identifier (presumably, because only the one button you actually click on get's added to the request -all the others don't get submitted) to determine which 'row', and subsequent input fields.
I think this might all come down to which 'button' you're using. If you're using a literal input tag (type="submit" or "button") the 'value' attribute is what the user sees as the text on the button -so, you're forced to play shenanigans with the 'name' attribute (presumably by adding an index to the name, splitting the string once you get it out of the request, and using that identifier to get the other parameters out of the request that also have the same identifier appended to their 'name' attribute).
JSP
<input type="submit" name="view${varStatus.index}" value="View" />
HTML Source
<input type="submit" name="view3" value="View">
You should probably use the button tag instead. It allows the text that the user sees to be different than the value that is submitted in the request.
JSP
<button type="submit" name="view" value="${varStatus.index}" >View</button>
HTML Source
<button type="submit" name="view" value="3">View</button>
This gives you the 'identifier' for the row.
How Spring fits into this:
I played with the #RequestMapping and the #RequestParam annotations, and was unable to get Spring to give me the values directly into the controller. But, I was able to do it by writing a custom HandlerMethodArgumentResolver along with a custom annotation.
note: I'm using annotations and java config instead of xml config, AND probably more importantly -this was a quick and dirty example to get it working. adjust it as needed for your situation.
HandlerMethodArgumentResolver
Annotation
Controller method
Instead of putting the table inside one form, you could put multiple forms inside the table, in the TRs:
<tr>
<form action="someAction">
<td>title1<input type='hidden' name='title' value='title1' /></td>
<td>DVD</td>
<td>R</td>
<td><input type="submit" value="view"></td>
</form>
</tr>
Then each title has its own form and you send in the title (always with parameter name of title) from a hidden input.
The solution lies in this statement:
"I have a table that is dynamically created that has rows of movies".
Presumably,
you are looping through a list of movies and generating the table in the jsp file and each row has some unique identifier.
Add a hidden to identify the selected row.
Set the value of the hidden value in an onclick handler from the submit buttons.
Here is some example stuff:
<form ...>
<c:forEach blah var="row">
<tr>
...
<td><input type="submit" value="View" onclick="setSelectedRow('${row.id}')"/></td>
</c:forEach>
<input type="hidden" id="blammy" name="blammy" value=""/>
</form>
<script type="text/javascript">
function setSelectedRow(rowId)
{
... set blammy.value equal to rowId.
}
</script>
// the id is used by JavaScript to find the object in the DOM.
// the name is what appears in the request.
#RequestMapping("someAction")
public ModelAndView loadPage(
#RequestParameter("blammy") final String blammy)
{
...
}

Why is my post not give data to my controller from my form?

I am developing a Sprin MVC application and I have a form containing a table in one of the UI jsp's, (welcome.jsp) and when the submit button is clicked, I am trying to print out the data in the form to the web applications console.From there i intend to parse the checkboxes that are selected and then have the controller send the 'selected' data back to the databased to be updated to the next status in the applications flow.
So far the form is 'successfully' posting as in no error or exceptions is being thrown, but the printed statement in the console is blank which makes me think that no data is being sent, and I would greatly welcome any help to fix this.
Here is the setup of what I have, not the actual code but a rough set up of the elements and methods.
welcome.jsp:
<form action="<c:url value="/postPage" />"method="post" modelAttribute="rTable">
<br/>
<table>
<thead>
<tr>
<th>title1</th>
<th>title2</th>
<th>title3</th>
<th><select>
<option>option1</option>
<option>option2</option>
</select></th>
</tr>
</thead>
<tbody>
<tr>
<td>value1</td>
<td>value1</td>
<td>value1</td>
<td><input type="checkbox" value="row_data_id" /></td>
</tr>
</tbody>
<tfoot>
<tr><td colspan="4"></td>
</tfoot>
</table>
<br/>
</form>
My controller has the following method in it with all the necessary libraries imported:
controller.java
#RequestMapping(value="/postPage", method = RequestMethod.POST)
public String processUpdate(#ModelAttribute("rTable") String table, ModelMap model) {
System.out.println(table);
return "postPage";
}
The console line that is print is this:
.
.
.
[3/19/14 16:36:53:625 EDT] 0000006a SystemOut O
.
.
.
Does anyone know why this is not printing anything? Am I really not successfully sending anything to the controller?
After a good deal of reading and trial and error I found my answer. I will explain in terms with spring framework forms. In order to pass data through the form from front-end to back end, first every input will need to be tied to the form using the spring form JSTL tag
ex.
form => form:form
input=> form:input
in the form:form it isn;t necessary but you should have a modelAttribute that is linked to a java class, then in each input their need to be a path attribute the is linked to a variable in the modelAttribute class and a value to assign to the variable. Then on a submit the values are linked to the back end via the getters and setters on the java class to be used in the back-end. I hope I am explained that clearly.

Retrieving value of visible element using java

I have two elements with name price1 [BTW I know that having duplicate IDs is against standards, is this the same with NAME?]
<TR CLASS="Blocks" id="p_priceKILO" style="display: none ;">
<TD>Price:</TD>
<TD><INPUT TYPE="text" name="price1">$/kilo</TD>
</TR>
<TR CLASS="Blocks" id="p_pricePOUND" style="display: none ;">
<TD>Price:</TD>
<TD><INPUT TYPE="text" name="price1">$/pound</TD>
</TR>
Only one of these rows will be visible at one time (using javascript)
I use the following java code to retrieve price1
public PricePosition(HttpServletRequest request) {
this.price1=StringFunctions.StringToDouble(request
.getParameter("PRICE1"));
...
Is there any neat way to retrieve only the visible element?
I have a workaround - calling them price1a and price1b and retrieving the correct one based on my knowledge of which one is visible, but I wondered if there was another way.
You'll have to use JS again: when displaying a row, rename the inner corresponding input to displayedPrice for example, and get this parameter server-side.
When hiding a row, don't forget to rename it back.

Setting jsp checkbox with a value from database

Ok. I'm making a java web app with a database backend to do some CRUD on some data. When the edit button is clicked next to an item, it navigates to a form with the current data for editing. One of the fields is boolean and I would like to display it as a checkbox so that True makes it checked and False leaves it unchecked.
I have tried many different variations none seem to work. Here are some examples where <%= action.get("stable")%> returns a string with either True or False
<input TYPE=checkbox name="stable" value=<%= action.get("stable") %>
<input TYPE=checkbox name="stable" value=<%= action.get("stable")?"True":"False" %><%= action.get("stable")?"checked":"" %>
<input TYPE=checkbox name="stable" checked=<%= action.get("stable")%>/>
So how do you set a check box to checked/unchecked depending on the string returned with action.get("stable")
Thank you for any help sorry if the question is a bit trivial.
I used this, and it worked perfectly.
<input type="checkbox" <c:if test="${item.estado==2}">checked=checked</c:if> class="switch-input" >
The correct markup for a checked checkbox is checked="checked". If it's not checked, the checked attribute must not be present at all.
You should generate it using the JSTL and the JSP EL, because scriptlets are something from the past which should not be used in JSPs for years. See How to avoid Java code in JSP files?.
This would of course need some refactoring so that the action bean has a regular isStable() method returning a boolean, which would be much cleaner. But anyway, here's how it would work using your existing code :
<input type="checkbox" name="stable" <%
if ("True".equals(action.get("stable"))) {
out.print("checked=\"checked\"");
} %>/>
Note that all attributes should also be surrounded by quotes.
You need to set checked attribute of <input type="checkbox"/>
Edit:
<input type="checkbox" <%=action.get("stable") ? "checked='checked'" : "" %> />

Categories