I have a table where a user can (un)check checkboxes among other features in each row.
I faced the problem that I don't receive unchecked checkboxes to my backend. This led to a bigger issue since every row should have synchronized fields of course.
For example:
- Row 1 - checked
- Row 2 - unchecked
- Row 3 - checked
My backend receives now an array like this:
clickBoxReduce
[true, true]
Backend-Function like this
@PostMapping()
public String selectPost(
@RequestParam(required = false, name = "clickboxReduce") String[] clickboxReduce,
Model model) {
System.out.println("clickBoxReduce");
System.out.println(Arrays.toString(clickboxReduce));
return "fillDetails";
}
Obviously I cannot see which row exactly is unchecked.
My solution was to give each input tag a value no
and yes
and update this value with every checkbox click.
function handleClickOnReduceStart (element) {
if (element.value === 'yes') {
element.value = 'no'
} else if (element.value === 'no') {
element.value = 'yes'
}
}
And set all checkboxes on checked before submitting the form with the function interceptSubmit
blow.
With that I get all checkbox values in the correct order.
It is visible for the user that the checkboxes change again if there is a slight delay what is not so good.
Does anyone have a better idea?
Here the table:
<!--- start table -->
<div class="container">
<br>
<h4 style="text-align: center">Please specify below</h4>
<br>
<form method="POST" id="postDetails" onsubmit="return interceptSubmit()">
<table id="buyTable" class="table table-hover">
<thead>
<tr>
<th>Type</th>
<th>Brand</th>
<th>Buy-Price</th>
<th>Bottom</th>
<th>Top</th>
<th>Stop</th>
<th>Reduce</th>
<th>Start</th>
</tr>
</thead>
<tbody>
<tr th:each="car : ${cars}">
<td>
<select th:id="${car.getBrand()}" title="selectBuyOrSell" onchange="updateBuyTable(this)">>
<option value="buy">Buy</option>
<option value="sell">Sell</option>
</select>
</td>
<td>
<a th:text="${car.getBrand()}"></a><input type="hidden" name="brandBuy"
th:value="${car.getBrand()}"/>
</td>
<td><input type="number" step="0.00000001" placeholder="Enter price"
name="buyPrice"/></td>
<td><input type="number" step="0.00000001" placeholder="Enter bottom"
name="bottom"/></td>
<td><input type="number" step="0.00000001" placeholder="Enter top"
name="top"/></td>
<td><input type="number" step="0.00000001" placeholder="Enter stop"
name="stop"/></td>
<td>
<label class="custom-control custom-checkbox">
<input id="clickboxReduce" name="clickboxReduce" type="checkbox" class="custom-control-input"
value="yes"
onchange="handleClickOnReduceStart(this)" checked>
<span class="custom-control-indicator"></span>
</label>
</td>
<td>
<label class="custom-control custom-checkbox">
<input id="clickboxStart" type="checkbox" class="custom-control-input"
onchange="handleClickOnReduceStart(this)" checked>
<span class="custom-control-indicator"></span>
</label>
</td>
<!-- <td><input id="clickboxReduce" type="checkbox"></td>
<td><input id="clickboxStart" type="checkbox"></td>-->
</tr>
</tbody>
</table>
<br/>
<br/>
<button style="float: right!important;" class="btn btn-outline-primary">Continue</button>
</form>
</div>
and the function
function interceptSubmit () {
let form = document.getElementsByClassName('custom-control-input')
for (i = 0; i < form.length; i++) {
if (!form[i].checked) {
console.log('unchecked')
form[i].checked = true
}
}
return true // return false to cancel form action
}
Output of my backend controller
clickBoxReduce
[yes, no, yes]
th:name="${'clickboxReduce_' + car.id}"
. \$\endgroup\$!!+”0”
equals false and!!+”1”
equals true. Don’t you think it would be easier to maintain and require less logic and take up less data using 0 & 1? I’m sure java has a typecast equivalent. \$\endgroup\$