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;
}
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.