fatiherdem
fatiherdem

Reputation: 1233

Spring Thymelaf in form table list

I pass multiple object from my GET request page. And one of them is ReplacedPartList as a list of ReplacedPart.

ReplacedPart.java

@Id
@GeneratedValue(strategy = GenerationType.TABLE)
@Column(name = "replaced_part_id")
private Long replacedPartId;

@Column(name = "maintain_id")
private Long maintainId;

@Column(name = "part_serial_no")
private String partSerialNo;

@Column(name = "quantity")
private Long quantity;

@Column(name = "unit_price")
private Double unitPrice;

@Column(name = "total_price")
private Double totalPrice;

//GETTERS and SETTERS

Part of my controller's GET method

List<ReplacedPart> replacedPartList = new ArrayList<>();

for (int i = 0; i < 7; i++) {
    ReplacedPart replacedPart = new ReplacedPart();
    replacedPartList.add(replacedPart);
}
model.addAttribute("replacedPartList", replacedPartList);

part of my returned form

<tr th:each="replacedPart, stat : ${replacedPartList}">
    <td th:text="${__${stat.index}__}"></td>
    <td><input type="text" th:value="${replacedPartList[__${stat.index}__].partSerialNo}" th:field="${replacedPartList[__${stat.index}__].partSerialNo}"></td>
    <td><input type="text" th:value="${replacedPartList[__${stat.index}__].quantity}" th:field="${replacedPartList[__${stat.index}__].quantity}"></td>
    <td><input type="text" th:value="${replacedPartList[__${stat.index}__].unitPrice}" th:field="${replacedPartList[__${stat.index}__].unitPrice}"></td>
    <td><input type="text" th:value="${replacedPartList[__${stat.index}__].totalPrice}" th:field="${replacedPartList[__${stat.index}__].totalPrice}"></td>
</tr>

error message

Neither BindingResult nor plain target object for bean name 'replacedPartList[0]' available as request attribute

And iy is just GET request not even POST. How can I solve this problem?

Upvotes: 0

Views: 584

Answers (2)

Hassam Abdelillah
Hassam Abdelillah

Reputation: 2304

Your are not using the correct syntax as specified in the doc

Try this :

    <tr th:each="replacedPart, rpStat : *{replacedPartList}">
    <td th:text="${rpStat.index}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${rpStat.index}__].partSerialNo}" th:field="*{replacedPartList[__${rpStat.index}__].partSerialNo}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${rpStat.index}__].quantity}" th:field="*{replacedPartList[__${rpStat.index}__].quantity}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${rpStat.index}__].unitPrice}" th:field="*{replacedPartList[__${rpStat.index}__].unitPrice}"></td>
    <td><input type="text" th:value="*{replacedPartList[__*{rpStat.index}__].totalPrice}" th:field="*{replacedPartList[__${rpStat.index}__].totalPrice}"></td>
</tr>

When using a list whether you want to show it so you have to not use it in a form. Forms ar binded to an object with the 'th:object' attribute. So if you will fill it it has to be a part of your model Maintain class.

Here is a full example on how to manipulate lists.

Upvotes: 1

fatiherdem
fatiherdem

Reputation: 1233

I solved my problem with MaintainFormDto class. I created as a form object and send this to view. And then I use * for the object binding like this.

MaintainFormDto

@Valid
private Maintain maintain;

@Valid
private Demand demand;

private List<ReplacedPart> replacedPartList;

public MaintainFormDto(Maintain maintain, Demand demand, List<ReplacedPart> replacedPartList) {
    this.maintain = maintain;
    this.demand = demand;
    this.replacedPartList = replacedPartList;
}
//GETTER and SETTERS

MaintainController

MaintainFormDto formDto = new MaintainFormDto(maintain, demand, replacedPartList);
model.addAttribute("form", formDto);

form.html

<tr th:each="replacedPart, stat : *{replacedPartList}">
    <td th:text="${__${stat.index}__}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${stat.index}__].partSerialNo}" th:field="*{replacedPartList[__${stat.index}__].partSerialNo}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${stat.index}__].quantity}" th:field="*{replacedPartList[__${stat.index}__].quantity}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${stat.index}__].unitPrice}" th:field="*{replacedPartList[__${stat.index}__].unitPrice}"></td>
    <td><input type="text" th:value="*{replacedPartList[__${stat.index}__].totalPrice}" th:field="*{replacedPartList[__${stat.index}__].totalPrice}"></td>
</tr>

Upvotes: 0

Related Questions