From 9bb3deb778e05895c79917a967052c76699a4e56 Mon Sep 17 00:00:00 2001 From: Peter Goodhall Date: Wed, 30 Jul 2025 17:30:05 +0100 Subject: [PATCH] Improve DataTable language handling and checkbox events Added a default fallback for DataTables language selection if lang_datatables_language is undefined. Refactored checkbox event handling in qslprint.js to ensure proper attachment after DataTable redraws, prevent duplicate handlers, and keep the 'select all' checkbox in sync. Also improved checks for AJAX response data in markSelectedQsos and removeSelectedQsos. --- assets/js/sections/common.js | 4 +- assets/js/sections/qslprint.js | 87 ++++++++++++++++++++++------------ 2 files changed, 61 insertions(+), 30 deletions(-) diff --git a/assets/js/sections/common.js b/assets/js/sections/common.js index 4a73a34e..b899327d 100644 --- a/assets/js/sections/common.js +++ b/assets/js/sections/common.js @@ -634,5 +634,7 @@ if ($('.table-responsive .dropdown-toggle').length>0) { } function getDataTablesLanguageUrl() { - return base_url + "/assets/json/datatables_languages/" + lang_datatables_language + ".json"; + // Check if lang_datatables_language is defined, otherwise use a default + var language = (typeof lang_datatables_language !== 'undefined') ? lang_datatables_language : 'english'; + return base_url + "/assets/json/datatables_languages/" + language + ".json"; } diff --git a/assets/js/sections/qslprint.js b/assets/js/sections/qslprint.js index cde42d91..7fc18dce 100644 --- a/assets/js/sections/qslprint.js +++ b/assets/js/sections/qslprint.js @@ -89,20 +89,71 @@ $(".station_id").change(function(){ paging: false, "language": { url: getDataTablesLanguageUrl(), + }, + "drawCallback": function(settings) { + // Re-attach event handlers after DataTable draws/redraws + attachCheckboxEvents(); } }); + // Attach checkbox events immediately after initialization + attachCheckboxEvents(); } }); }); -$('#qslprint_table').DataTable({ - "stateSave": true, - paging: false, - "language": { - url: getDataTablesLanguageUrl(), +// Initialize DataTable only if it exists and isn't already initialized +$(document).ready(function() { + if ($('#qslprint_table').length && !$.fn.DataTable.isDataTable('#qslprint_table')) { + $('#qslprint_table').DataTable({ + "stateSave": true, + paging: false, + "language": { + url: getDataTablesLanguageUrl(), + }, + "drawCallback": function(settings) { + // Re-attach event handlers after DataTable draws/redraws + attachCheckboxEvents(); + } + }); } + // Initial attachment of events + attachCheckboxEvents(); }); +// Function to attach checkbox events +function attachCheckboxEvents() { + // Remove any existing handlers to prevent duplicates + $('#checkBoxAll').off('change.qslprint'); + $('.qso-checkbox').off('click.qslprint'); + + // Attach select all functionality + $('#checkBoxAll').on('change.qslprint', function (event) { + var isChecked = this.checked; + $('#qslprint_table tbody tr .qso-checkbox').each(function (i) { + $(this).prop("checked", isChecked); + if (isChecked) { + $(this).closest('tr').addClass('activeRow'); + } else { + $(this).closest('tr').removeClass('activeRow'); + } + }); + }); + + // Attach individual checkbox functionality + $(document).on('click.qslprint', '.qso-checkbox', function() { + if ($(this).is(":checked")) { + $(this).closest('tr').addClass('activeRow'); + } else { + $(this).closest('tr').removeClass('activeRow'); + } + + // Update the "select all" checkbox state + var totalCheckboxes = $('#qslprint_table tbody tr .qso-checkbox').length; + var checkedCheckboxes = $('#qslprint_table tbody tr .qso-checkbox:checked').length; + $('#checkBoxAll').prop('checked', totalCheckboxes === checkedCheckboxes); + }); +} + function showOqrs(id) { $.ajax({ url: base_url + 'index.php/qslprint/show_oqrs', @@ -147,28 +198,6 @@ function mark_qsl_sent(id, method) { }); } -$(document).on('change', '#checkBoxAll', function (event) { - if (this.checked) { - $('#qslprint_table tbody tr .qso-checkbox').each(function (i) { - $(this).prop("checked", true); - $(this).closest('tr').addClass('activeRow'); - }); - } else { - $('#qslprint_table tbody tr .qso-checkbox').each(function (i) { - $(this).prop("checked", false); - $(this).closest('tr').removeClass('activeRow'); - }); - } -}); - -$(document).on('click', '.qso-checkbox', function() { - if ($(this).is(":checked")) { - $(this).closest('tr').addClass('activeRow'); - } else { - $(this).closest('tr').removeClass('activeRow'); - } -}); - function markSelectedQsos() { var elements = $('.qso-checkbox:checked'); var nElements = elements.length; @@ -191,7 +220,7 @@ function markSelectedQsos() { 'method' : '' }, success: function(data) { - if (data !== []) { + if (data && data.length > 0) { $.each(data, function(k, v) { $("#qslprint_"+this.qsoID).remove(); }); @@ -225,7 +254,7 @@ function removeSelectedQsos() { 'method' : '' }, success: function(data) { - if (data !== []) { + if (data && data.length > 0) { $.each(data, function(k, v) { $("#qslprint_"+this.qsoID).remove(); });