Reputation: 69
I have a form that presents as a DataTable with checkmarks on each row. The user should be able to check up to 10 checkboxes. Once the tenth is checked, all the unchecked checkboxes need to be disabled until the user unchecks at least one to go back below the limit. Everything works fine, except when I start playing with the number of rows per page. If I go from 25 to 10 rows and then go back and forth through different pages, some checkboxes are still disabled while others are not. The total count of checked checkboxes is always right though. I'm not sure how to refresh the 'disabled' attribute when the table is redrawn.
This is the HTML code:
<div class="card-header pb-0 card-no-border">
<span>Select up to 10 playlists for this song. You can select up to 10 playlists daily.</span>
</div>
<div class="alert alert-warning inverse alert-dismissible fade show" role="alert"
id="pageMessages">
<i class="icon-info-alt"></i>
<p id="limitCounter">0 playlists selected from limit of 10</p>
</div>
<div class="card-body">
<div class="table-responsive HideScrollbar">
<form method="POST" action="submission_agreement.php">
<table class="display" id="basic-1" data-page-length="25">
<thead>
<tr>
<th class="no-sort">Cover</th>
<th>Details</th>
<th>Saves</th>
<th>Songs</th>
<th>Updated</th>
<th class="no-sort">Select</th>
</tr>
</thead>
<tbody>
<tr>
<td><img src="assets/images/playlists/playlist-cover-1.png" alt=""></td>
<td>
<h6>Contemporary Piano</h6>
<span>
by <a href="#">antonioromopiano</a><br>
Submissions: 1,013 | Approval rate: 43%<br>
neo-classical · instrumental · cinematic · calming
</span>
</td>
<td>539 <i class="fa fa-heart-o fa-sm"></i></td>
<td>150 <i class="fa fa-music"></i></td>
<td class="font-success">2023 05 27</td>
<td>
<input type="checkbox" id="checkpoint1" class="checkpoint ms-4" name="checkpoints"
value="{{playlist.id}}">
</td>
</tr>
<tr>
... many rows like the one above ...
</tr>
</tbody>
</table>
<div class="col text-center mt-3">
<button class="btn btn-primary btn-next" type="submit" id="done_selecting">Done Selecting Playlists</button>
</div>
</form>
</div>
</div>
And this is my JavaScript:
<script>
$(document).ready(function () {
$("input[id^='checkpoint']").change(function () {
const checkbox_limit = 10;
const checkboxes = document.querySelectorAll('input[type="checkbox"]');
var element = document.getElementById("pageMessages");
var $table = $('#basic-1').dataTable();
var allNodes = $table.fnGetNodes();
var total_checked = 0;
$(allNodes).each(function () {
$(this).change(updatetotal_checked);
});
updatetotal_checked();
function updatetotal_checked () {
total_checked = $(allNodes).find("input[name='checkpoints']:checked").length;
$("#total_checked").text(total_checked);
if (total_checked > 0) {
$("#status").toggle(total_checked > 0);
}
};
/* Disable unchecked checkboxes if total checked = 10 */
checkboxes.forEach((checkbox) => {
checkbox.disabled = total_checked >= checkbox_limit && !checkbox.checked;
});
/* Disable submit button if at least one playlist hasn't been selected */
if (total_checked == 0) {
document.getElementById('done_selecting').setAttribute('disabled', '');
}
else {
document.getElementById('done_selecting').removeAttribute('disabled');
}
/* Change alert color if total checked = 10 */
if (total_checked >= checkbox_limit) {
element.classList.remove("alert-warning");
element.classList.add("alert-danger");
} else {
element.classList.remove("alert-danger");
element.classList.add("alert-warning");
}
/* Update alert text with total checked */
const limitCounter = document.getElementById('limitCounter');
limitCounter.textContent = `${total_checked} playlists selected from limit of ${checkbox_limit}`;
});
/* To set initial state */
$("input[id^='checkpoint']").trigger('change');
});
</script>
Any help is greatly appreciated!
Upvotes: 1
Views: 33