Thymeleaf 3 with Spring MVC breaks unchecked checkboxes

classic Classic list List threaded Threaded
4 messages Options
Reply | Threaded
Open this post in threaded view
|

Thymeleaf 3 with Spring MVC breaks unchecked checkboxes

HersheySquirt
Prior to upgrading to version 3 an unchecked box would still post and wire to the form bean's setter method.  After upgrading to version 3 unchecked boxes don't post so the setter never gets called.  If you default the value in the bean to true it can never be set to untrue by deselecting the checkbox in the form.

There's supposedly a workaround by adding a hidden input field in the form just below the checkbox with the same name as the checkbox with a value of false.  So, even if the checkbox is unchecked and not posted a false value will still be passed along and mapped to the form bean to trigger the setter.

Is this expected behavior or was it an oversight?
Reply | Threaded
Open this post in threaded view
|

Re: Thymeleaf 3 with Spring MVC breaks unchecked checkboxes

HersheySquirt
I have an update to this issue.  After reading the other issue where someone was having alignment problems in bootstrap because of the hidden field it made me wonder why I'm not getting the hidden field for my checkbox like I used to get in previous versions.

It turns out that the input field also had a th:text attribute and for some reason this prevents thymeleaf from creating the hidden field for the checkbox.  When I moved the th:text to a label (where it really should have been in the first place) then I get my hidden field and everything plays nice.

This example prevents the hidden field from getting generated so it's impossible to post an unchecked box value:

<input th:field="*{fooField}" type="checkbox" id="fooField" th:text="#{my.localized.text}"/>

This fixes the problem, but I still wonder if it should work the other way as well for backward compatibility and the fact that an input field should be allowed to have a text attribute:

<input th:field="*{fooField}" type="checkbox" id="fooField"/>
<label th:for="*{fooField}" th:text="#{my.localized.text}"></label>

I'd also like to point out the reason I'm explicitly adding the id attribute even though th:field auto generates the id and name for us.  If I remove the id attribute I will get name="fooField" id="fooField1" and I have javascript that is looking for fooField without the number 1 appended to the end.  I'm not sure why it's doing this because the id is unique.
Reply | Threaded
Open this post in threaded view
|

Re: Thymeleaf 3 with Spring MVC breaks unchecked checkboxes

danielfernandez
Administrator
Please note that th:text sets the evaluated text as body of the host tag. But <input> tags are void, i.e. they should have no body at all (nor they should have a closing tag, which applying th:text would generate). So I'm not sure of the reasons why you are adding th:text there...

Maybe you mean to use th:placeholder?

Reply | Threaded
Open this post in threaded view
|

Re: Thymeleaf 3 with Spring MVC breaks unchecked checkboxes

HersheySquirt
I've been updating some legacy code that has been developed by many over the years.  I agree, the input tag should never have had a th:text attribute, but this didn't break in previous versions.  However, moving it to a label was an easy fix.  I only ran across this issue in one place across the entire site so luckily it wasn't a big deal.

Thanks for the reply!