I have a form where there are different groups of radio buttons. After using the Thymeleaf template I quickly faced an issue whereby I could not group my radio buttons due to them sharing the same th:fields tag. The issue is that I have a list to handle the ingredients, thus can not reference different fields for the th:fields tag (since there is only a single list). Thymeleaf then restricts my radio button options to one of all of the ingredient list items, even though I want to be able to select different radio options in various groups (buns, sauces, cheeses e.t.c.). Does anyone have a workaround for this? Here is my code:
HTML Template:
<form method="POST" th:object="${burger}"> <div class="grid"> <div class="ingredient-group" id="buns"> <h3>Designate your bun:</h3> <div th:each="ingredient : ${bun}"> <input th:name="${ingredient.name}" type="radio" th:id="${ingredient.id}" th:value="${ingredient.id}" th:field="*{ingredients}" v-model="bun"> <label th:for="${ingredient.id}" th:text="${ingredient.name}">INGREDIENT</label> <br> </div> </div> <div class="ingredient-group" id="meats"> <h3>Pick your meat:</h3> <div th:each="ingredient : ${meat}"> <input th:name="${ingredient.name}" type="radio" th:id="${ingredient.id}" th:value="${ingredient.id}" th:field="*{ingredients}" v-model="meat"> <label th:for="${ingredient.id}" th:text="${ingredient.name}">INGREDIENT</label> <br> </div> </div> <div class="ingredient-group" id="toppings"> <h3>Choose your toppings:</h3> <div th:each="ingredient : ${topping}"> <input th:name="${ingredient.name}" type="checkbox" th:id="${ingredient.id}" th:value="${ingredient.id}" th:field="*{ingredients}" v-model="toppings"> <label th:for="${ingredient.id}" th:text="${ingredient.name}">INGREDIENT</label> <br> </div> </div> <div class="ingredient-group" id="cheeses"> <h3>Determine your cheese:</h3> <div th:each="ingredient : ${cheese}"> <input th:name="${ingredient.name}" type="radio" th:id="${ingredient.id}" th:value="${ingredient.id}" th:field="*{ingredients}" v-model="cheese"> <label th:for="${ingredient.id}" th:text="${ingredient.name}">INGREDIENT</label> <br> </div> </div> <div class="ingredient-group" id="sauces"> <h3>Select your sauce:</h3> <div th:each="ingredient : ${sauce}"> <input th:name="${ingredient.name}" type="radio" th:id="${ingredient.id}" th:value="${ingredient.id}" th:field="*{ingredients}" v-model="sauce"> <label th:for="${ingredient.id}" th:text="${ingredient.name}">INGREDIENT</label> <br> </div> </div> </div> <div class="name-submit"> <h3 class="submit-section-title row">Name your burger creation:</h3> <input class="submit-section-input" type="text" th:field="*{name}" v-model="burgerName"/> <br/> <button class="submit-section-button">Submit Your Burger</button> </div> </form>
Burger model that I refer to:
@Data public class Burger { @NotNull @Size(min=5, message="Name must be at least 5 characters long") private String name; @NotNull @Size(min=1, message="You must choose at least 1 ingredient") private List<Ingredient> ingredients; }
Advertisement
Answer
Some options:
Use checkboxes instead, and use JavaScript to make sure they can only select one of each ingredient list. (Or use some kind of third party library w/selectable buttons so you still use checkboxes, but they don’t look like checkboxes.)
Add a variable for each type of ingredient and add a helper method to turn them into a
List<Ingredient>
/. Then your radio buttons will works as normal, each bound to a different field. (Might have to remove null ingredients after, if they are optional.)public class Burger { Ingredient cheese; Ingredient sauce; Ingredient meat; public List<Ingredient> getIngredients() { return Arrays.asList(cheese, sauce, meat); }
I don’t think you’re going to get the functionality you want out of radio buttons, they just aren’t designed to be used that way.