Spring / Thymeleaf checkbox compatibility issue
See original GitHub issueHello,
I’d like to let you know that there’s a compatibility issue with Thymeleaf templating engine (used in Spring framework).
The issue in question:
Required structure of checkbox input in Materialize is following (<p>
can be replaced for any other tag AFAIK):
<p>
<input type="checkbox">
<label> ... </label>
</p>
With CSS code used to target the label being:
[type="checkbox"] + label { ... }
Meaning “a label right after a checkbox”. Problem is that Thymeleaf adds additional <input type="hidden">
element after each checkbox input, breaking the checkbox + label selector. Following is actual Thymeleaf code I use in one of my projects. It uses a th:each loop to go over a list of items:
<div th:each="anArtwork : ${listOfArtworks}" class="row">
<div class="col s12">
<p>
<input th:field="*{artworks}" th:value="${anArtwork.id}" type="checkbox" class="filled-in">
<label th:for="${#ids.prev('artworks')}" th:text="${anArtwork.nameSk}"></label>
</p>
</div>
</div>
Which results into the following HTML code (generated repeatedly for each item in list with small differences in ID-related values):
<div class="row">
<div class="col s12">
<p>
<input class="filled-in" type="checkbox" value="2" id="artworks2" name="artworks" />
<input type="hidden" name="_artworks" value="on" />
<label for="artworks2"> ... </label>
</p>
</div>
</div>
This of course breaks previous CSS selector for checkbox + label elements, as it adds additional element between them. Workaround I’m using adds additional selector to the CSS code in Materialize like this:
[type="checkbox"] + label,
[type="checkbox"] + [type="hidden"] + label { ... }
Which accounts for the additional hidden input and thus targets the required label. This is a Thymeleaf-specific solution only however and fastest one I could think of for my project.
My suggestion for a full compatibility fix/solution would be adding a mandatory wrapper element (like <p>
or <span>
) with a mandatory class (eg.: .material-checkbox
) to the material checkboxes and target the inside checkbox and label elements using this class (.material-checkbox [type="checkbox"]
and .material-checkbox label
) instead of relying on the fact that the two elements will always be next to each other, which in Thymeleaf is not the case:
<p class="materialize-checkbox">
<input type="checkbox">
<label> ... </label>
</p>
.materialize-select [type="checkbox"] { ... }
.materialize-select label { ... }
I understand this add additional complexity and constraints on the Materialize framework, however as I said, a change on the part of Thymeleaf is not really possible. Or someone could devise a different solution, CSS/HTML is not really my primary focus, so there might be better options than what I suggested.
Issue Analytics
- State:
- Created 8 years ago
- Reactions:9
- Comments:7
I did so, at the bottom of the page:
Its Works!
tgmarinho: The complete solution is in my answer from 9 May. It does, however require recompiling Materialize. I’ll see if I can put in a pull request for it.
Your javascript workaround breaks quite a lot of things, including spring form handling and CSRF protection.